1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-05 15:25:49 +02:00

Bug 438348 - Allow decltype-specifiers in base-specifiers

Change-Id: Ib027b78aa207e1fe0e1aef56fae7eeace041118c
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/31341
Tested-by: Hudson CI
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2014-08-09 04:38:34 -04:00 committed by Sergey Prigogin
parent b7ec8deec4
commit 42235704cb
19 changed files with 210 additions and 43 deletions

View file

@ -112,6 +112,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
@ -649,7 +650,7 @@ public class AST2CPPTests extends AST2TestBase {
IASTName name_B1 = comp.getName(); IASTName name_B1 = comp.getName();
ICPPASTBaseSpecifier base = comp.getBaseSpecifiers()[0]; ICPPASTBaseSpecifier base = comp.getBaseSpecifiers()[0];
IASTName name_A2 = base.getName(); IASTName name_A2 = (IASTName) base.getNameSpecifier();
decl = (IASTSimpleDeclaration) comp.getMembers()[0]; decl = (IASTSimpleDeclaration) comp.getMembers()[0];
IASTName name_f1 = decl.getDeclarators()[0].getName(); IASTName name_f1 = decl.getDeclarators()[0].getName();
@ -8301,6 +8302,17 @@ public class AST2CPPTests extends AST2TestBase {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// struct Base {};
// struct Derived : decltype(Base()) {};
public void testDecltypeInBaseSpecifier_438348() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType base = helper.assertNonProblem("struct Base", "Base");
ICPPClassType derived = helper.assertNonProblem("Derived");
ICPPBase[] bases = derived.getBases();
assertEquals(1, bases.length);
assertEquals(base, bases[0].getBaseClass());
}
// template <typename T> // template <typename T>
// T bar(); // T bar();
// struct S { // struct S {

View file

@ -681,7 +681,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
final ICPPASTCompositeTypeSpecifier cppCompositeTypeSpecifier= (ICPPASTCompositeTypeSpecifier) compositeTypeSpecifier; final ICPPASTCompositeTypeSpecifier cppCompositeTypeSpecifier= (ICPPASTCompositeTypeSpecifier) compositeTypeSpecifier;
ICPPASTBaseSpecifier[] baseSpecifiers= cppCompositeTypeSpecifier.getBaseSpecifiers(); ICPPASTBaseSpecifier[] baseSpecifiers= cppCompositeTypeSpecifier.getBaseSpecifiers();
for (final ICPPASTBaseSpecifier baseSpecifier : baseSpecifiers) { for (final ICPPASTBaseSpecifier baseSpecifier : baseSpecifiers) {
final IASTName baseName= baseSpecifier.getName(); final ICPPASTNameSpecifier nameSpec= baseSpecifier.getNameSpecifier();
final ASTAccessVisibility visibility; final ASTAccessVisibility visibility;
switch (baseSpecifier.getVisibility()) { switch (baseSpecifier.getVisibility()) {
case ICPPASTBaseSpecifier.v_public: case ICPPASTBaseSpecifier.v_public:
@ -696,7 +696,11 @@ public class CModelBuilder2 implements IContributedModelBuilder {
default: default:
visibility= ASTAccessVisibility.PUBLIC; visibility= ASTAccessVisibility.PUBLIC;
} }
element.addSuperClass(ASTStringUtil.getSimpleName(baseName), visibility); if (nameSpec instanceof IASTName) {
element.addSuperClass(ASTStringUtil.getSimpleName((IASTName) nameSpec), visibility);
} else {
element.addSuperClass(new String(nameSpec.toCharArray()), visibility);
}
} }
} }

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTDesignator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier;
@ -146,6 +147,12 @@ public abstract class ASTVisitor {
*/ */
public boolean shouldVisitVirtSpecifiers = false; public boolean shouldVisitVirtSpecifiers = false;
/**
* Set this flag to visit decltype-specifiers.
* @since 5.8
*/
public boolean shouldVisitDecltypeSpecifiers = false;
/** /**
* Per default inactive nodes are not visited. You can change that by setting * Per default inactive nodes are not visited. You can change that by setting
* this flag to <code>true</code>. * this flag to <code>true</code>.
@ -213,6 +220,7 @@ public abstract class ASTVisitor {
shouldVisitTranslationUnit= visitNodes; shouldVisitTranslationUnit= visitNodes;
shouldVisitTypeIds= visitNodes; shouldVisitTypeIds= visitNodes;
shouldVisitVirtSpecifiers= visitNodes; shouldVisitVirtSpecifiers= visitNodes;
shouldVisitDecltypeSpecifiers= visitNodes;
} }
// visit methods // visit methods
@ -338,6 +346,13 @@ public abstract class ASTVisitor {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
/**
* @since 5.8
*/
public int visit(ICPPASTDecltypeSpecifier decltypeSpecifier) {
return PROCESS_CONTINUE;
}
// leave methods // leave methods
public int leave(IASTTranslationUnit tu) { public int leave(IASTTranslationUnit tu) {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
@ -461,6 +476,13 @@ public abstract class ASTVisitor {
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
/**
* @since 5.8
*/
public int leave(ICPPASTDecltypeSpecifier decltypeSpecifier) {
return PROCESS_CONTINUE;
}
/** /**
* @deprecated use {@link IASTTranslationUnit#getComments()}, instead. * @deprecated use {@link IASTTranslationUnit#getComments()}, instead.
*/ */

View file

@ -60,10 +60,21 @@ public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifie
/** /**
* Relation between base specifier and its name. * Relation between base specifier and its name.
*
* @deprecated Use ICPPASTBaseSpecifier.NAME_SPECIFIER instead.
*/ */
@Deprecated
public static final ASTNodeProperty NAME = new ASTNodeProperty( public static final ASTNodeProperty NAME = new ASTNodeProperty(
"ICPPASTBaseSpecifier.NAME - Name of base class"); //$NON-NLS-1$ "ICPPASTBaseSpecifier.NAME - Name of base class"); //$NON-NLS-1$
/**
* Relation between base specifier and its name specifier.
*
* @since 5.8
*/
public static final ASTNodeProperty NAME_SPECIFIER = new ASTNodeProperty(
"ICPPASTBaseSpecifier.NAME_SPECIFIER - Name specifier of base class"); //$NON-NLS-1$
public static final int v_public = ICPPASTVisibilityLabel.v_public; public static final int v_public = ICPPASTVisibilityLabel.v_public;
public static final int v_protected = ICPPASTVisibilityLabel.v_protected; public static final int v_protected = ICPPASTVisibilityLabel.v_protected;
public static final int v_private = ICPPASTVisibilityLabel.v_private; public static final int v_private = ICPPASTVisibilityLabel.v_private;
@ -80,9 +91,19 @@ public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifie
/** /**
* Returns the name of this specifier. * Returns the name of this specifier.
*
* @deprecated Use getNameSpecifier() instead.
*/ */
@Deprecated
public IASTName getName(); public IASTName getName();
/**
* Returns the name specifier inside this base specifier.
*
* @since 5.8
*/
public ICPPASTNameSpecifier getNameSpecifier();
/** /**
* @since 5.1 * @since 5.1
*/ */
@ -97,9 +118,19 @@ public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifie
/** /**
* Sets the name for this specifier, not allowed on frozen AST. * Sets the name for this specifier, not allowed on frozen AST.
*
* @deprecated Use setNameSpecifier() instead.
*/ */
@Deprecated
public void setName(IASTName name); public void setName(IASTName name);
/**
* Sets the name specifier for this base specifier. Not allowed on frozen AST.
*
* @since 5.8
*/
public void setNameSpecifier(ICPPASTNameSpecifier nameSpecifier);
/** /**
* Sets whether this specifier is for a virtual base. Not allowed on frozen AST. * Sets whether this specifier is for a virtual base. Not allowed on frozen AST.
*/ */

View file

@ -65,8 +65,14 @@ public interface ICPPNodeFactory extends INodeFactory {
*/ */
public ICPPASTAttributeSpecifier newAttributeSpecifier(); public ICPPASTAttributeSpecifier newAttributeSpecifier();
@Deprecated
public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual); public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual);
/**
* @since 5.8
*/
public ICPPASTBaseSpecifier newBaseSpecifier(ICPPASTNameSpecifier nameSpecifier, int visibility, boolean isVirtual);
@Override @Override
public ICPPASTBinaryExpression newBinaryExpression(int op, IASTExpression expr1, IASTExpression expr2); public ICPPASTBinaryExpression newBinaryExpression(int op, IASTExpression expr1, IASTExpression expr2);

View file

@ -20,6 +20,8 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@ -31,21 +33,21 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier
private boolean isVirtual; private boolean isVirtual;
private int visibility; private int visibility;
private IASTName name; private ICPPASTNameSpecifier nameSpecifier;
private boolean fIsPackExpansion; private boolean fIsPackExpansion;
public CPPASTBaseSpecifier() { public CPPASTBaseSpecifier() {
} }
public CPPASTBaseSpecifier(IASTName name) { public CPPASTBaseSpecifier(ICPPASTNameSpecifier nameSpecifier) {
setName(name); setNameSpecifier(nameSpecifier);
} }
public CPPASTBaseSpecifier(IASTName name, int visibility, boolean isVirtual) { public CPPASTBaseSpecifier(ICPPASTNameSpecifier nameSpecifier, int visibility, boolean isVirtual) {
this.isVirtual = isVirtual; this.isVirtual = isVirtual;
this.visibility = visibility; this.visibility = visibility;
setName(name); setNameSpecifier(nameSpecifier);
} }
@Override @Override
@ -55,7 +57,7 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier
@Override @Override
public CPPASTBaseSpecifier copy(CopyStyle style) { public CPPASTBaseSpecifier copy(CopyStyle style) {
CPPASTBaseSpecifier copy = new CPPASTBaseSpecifier(name == null ? null : name.copy(style)); CPPASTBaseSpecifier copy = new CPPASTBaseSpecifier(nameSpecifier == null ? null : nameSpecifier.copy(style));
copy.isVirtual = isVirtual; copy.isVirtual = isVirtual;
copy.visibility = visibility; copy.visibility = visibility;
copy.fIsPackExpansion= fIsPackExpansion; copy.fIsPackExpansion= fIsPackExpansion;
@ -85,17 +87,33 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier
} }
@Override @Override
@Deprecated
public IASTName getName() { public IASTName getName() {
return name; if (nameSpecifier instanceof IASTName) {
return (IASTName) nameSpecifier;
}
throw new UnsupportedOperationException("Cannot call getName() on base-specifier whose name-specifier " //$NON-NLS-1$
+ "is not a name. Use getNameSpecifier() instead."); //$NON-NLS-1$
} }
@Override @Override
@Deprecated
public void setName(IASTName name) { public void setName(IASTName name) {
setNameSpecifier((ICPPASTName) name);
}
@Override
public ICPPASTNameSpecifier getNameSpecifier() {
return nameSpecifier;
}
@Override
public void setNameSpecifier(ICPPASTNameSpecifier nameSpecifier) {
assertNotFrozen(); assertNotFrozen();
this.name = name; this.nameSpecifier = nameSpecifier;
if (name != null) { if (nameSpecifier != null) {
name.setParent(this); nameSpecifier.setParent(this);
name.setPropertyInParent(NAME); nameSpecifier.setPropertyInParent(NAME_SPECIFIER);
} }
} }
@ -109,7 +127,7 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier
} }
} }
if (name != null && !name.accept(action)) if (nameSpecifier != null && !nameSpecifier.accept(action))
return false; return false;
if (action.shouldVisitBaseSpecifiers && action.leave(this) == ASTVisitor.PROCESS_ABORT) if (action.shouldVisitBaseSpecifiers && action.leave(this) == ASTVisitor.PROCESS_ABORT)
@ -120,7 +138,7 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier
@Override @Override
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
if (name == n) return r_reference; if (nameSpecifier == n) return r_reference;
return r_unclear; return r_unclear;
} }

View file

@ -68,7 +68,26 @@ public class CPPASTDecltypeSpecifier extends ASTNode
@Override @Override
public boolean accept(ASTVisitor visitor) { public boolean accept(ASTVisitor visitor) {
return fDecltypeExpression.accept(visitor); if (visitor.shouldVisitDecltypeSpecifiers) {
switch (visitor.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
}
if (!fDecltypeExpression.accept(visitor))
return false;
if (visitor.shouldVisitDecltypeSpecifiers) {
switch (visitor.leave(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
}
return true;
} }
@Override @Override

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -49,16 +50,17 @@ public class CPPBaseClause implements ICPPBase, ICPPInternalBase {
@Override @Override
public IType getBaseClassType() { public IType getBaseClassType() {
if (baseClass == null) { if (baseClass == null) {
IBinding b = base.getName().resolveBinding(); ICPPASTNameSpecifier nameSpec = base.getNameSpecifier();
IBinding b = nameSpec.resolveBinding();
if (b instanceof IProblemBinding) { if (b instanceof IProblemBinding) {
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ((IProblemBinding) b).getID()); baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ((IProblemBinding) b).getID());
} else if (!(b instanceof IType)) { } else if (!(b instanceof IType)) {
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ISemanticProblem.BINDING_NO_CLASS); baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ISemanticProblem.BINDING_NO_CLASS);
} else { } else {
baseClass= (IType) b; baseClass= (IType) b;
IType check= getNestedType(baseClass, TDEF); IType check= getNestedType(baseClass, TDEF);
if (!(check instanceof ICPPClassType || check instanceof ICPPUnknownType)) { if (!(check instanceof ICPPClassType || check instanceof ICPPUnknownType)) {
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ISemanticProblem.BINDING_NO_CLASS); baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ISemanticProblem.BINDING_NO_CLASS);
} }
} }
} }

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
@ -54,6 +55,9 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
public CPPClassTypeProblem(IASTName name, int id) { public CPPClassTypeProblem(IASTName name, int id) {
super(name, id); super(name, id);
} }
public CPPClassTypeProblem(ICPPASTNameSpecifier nameSpec, int id) {
super(nameSpec, id, nameSpec instanceof IASTName ? null : nameSpec.toCharArray());
}
public CPPClassTypeProblem(IASTNode node, int id, char[] arg) { public CPPClassTypeProblem(IASTNode node, int id, char[] arg) {
super(node, id, arg); super(node, id, arg);
} }

View file

@ -88,6 +88,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
@ -184,8 +185,14 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
} }
@Override @Override
@Deprecated
public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual) { public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual) {
return new CPPASTBaseSpecifier(name, visibility, isVirtual); return new CPPASTBaseSpecifier((ICPPASTName) name, visibility, isVirtual);
}
@Override
public ICPPASTBaseSpecifier newBaseSpecifier(ICPPASTNameSpecifier nameSpecifier, int visibility, boolean isVirtual) {
return new CPPASTBaseSpecifier(nameSpecifier, visibility, isVirtual);
} }
@Override @Override

View file

@ -713,6 +713,7 @@ public class ClassTypeHelper {
result.add(classOrTypedef); result.add(classOrTypedef);
} }
// TODO(nathanridge): Also find subclasses referenced via decltype-specifiers rather than names.
IIndexName[] names= index.findNames(classOrTypedef, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS); IIndexName[] names= index.findNames(classOrTypedef, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS);
for (IIndexName indexName : names) { for (IIndexName indexName : names) {
if (indexName.isBaseSpecifier()) { if (indexName.isBaseSpecifier()) {

View file

@ -228,16 +228,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
throw backtrack; throw backtrack;
} }
private IASTName qualifiedName() throws BacktrackException, EndOfFileException { private ICPPASTNameSpecifier nameSpecifier() throws BacktrackException, EndOfFileException {
return ambiguousQualifiedName(CastExprCtx.eNotInBExpr); return ambiguousNameSpecifier(CastExprCtx.eNotInBExpr);
} }
private IASTName ambiguousQualifiedName(CastExprCtx ctx) throws BacktrackException, EndOfFileException { private ICPPASTNameSpecifier ambiguousNameSpecifier(CastExprCtx ctx) throws BacktrackException, EndOfFileException {
TemplateIdStrategy strat= new TemplateIdStrategy(); TemplateIdStrategy strat= new TemplateIdStrategy();
IToken m= mark(); IToken m= mark();
while (true) { while (true) {
try { try {
return qualifiedName(ctx, strat); return nameSpecifier(ctx, strat);
} catch (BacktrackException e) { } catch (BacktrackException e) {
if (strat.setNextAlternative()) { if (strat.setNextAlternative()) {
backup(m); backup(m);
@ -249,11 +249,11 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
} }
/** /**
* Parses a qualified name. * Parses a name specifier.
*/ */
private IASTName qualifiedName(CastExprCtx ctx, ITemplateIdStrategy strat) throws BacktrackException, EndOfFileException { private ICPPASTNameSpecifier nameSpecifier(CastExprCtx ctx, ITemplateIdStrategy strat) throws BacktrackException, EndOfFileException {
if (strat == null) if (strat == null)
return ambiguousQualifiedName(ctx); return ambiguousNameSpecifier(ctx);
ICPPASTQualifiedName qname= null; ICPPASTQualifiedName qname= null;
ICPPASTNameSpecifier nameSpec= null; ICPPASTNameSpecifier nameSpec= null;
@ -355,11 +355,28 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
setRange(qname, offset, endOffset); setRange(qname, offset, endOffset);
nameSpec= qname; nameSpec= qname;
} }
if (!(nameSpec instanceof IASTName)) { return nameSpec;
}
private ICPPASTName qualifiedName() throws BacktrackException, EndOfFileException {
ICPPASTNameSpecifier nameSpec = nameSpecifier();
if (!(nameSpec instanceof ICPPASTName)) {
// decltype-specifier without following :: // decltype-specifier without following ::
throwBacktrack(nameSpec); throwBacktrack(nameSpec);
} }
return (IASTName) nameSpec; return (ICPPASTName) nameSpec;
}
/**
* Parses a qualified name.
*/
private ICPPASTName qualifiedName(CastExprCtx ctx, ITemplateIdStrategy strat) throws BacktrackException, EndOfFileException {
ICPPASTNameSpecifier nameSpec = nameSpecifier(ctx, strat);
if (!(nameSpec instanceof ICPPASTName)) {
// decltype-specifier without following ::
throwBacktrack(nameSpec);
}
return (ICPPASTName) nameSpec;
} }
private void addNameSpecifier(ICPPASTQualifiedName qname, ICPPASTNameSpecifier nameSpec) { private void addNameSpecifier(ICPPASTQualifiedName qname, ICPPASTNameSpecifier nameSpec) {
@ -4480,7 +4497,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
int startOffset= LA(1).getOffset(); int startOffset= LA(1).getOffset();
boolean isVirtual = false; boolean isVirtual = false;
int visibility = 0; int visibility = 0;
IASTName name = null; ICPPASTNameSpecifier nameSpec = null;
loop: for (;;) { loop: for (;;) {
switch (LT(1)) { switch (LT(1)) {
case IToken.t_virtual: case IToken.t_virtual:
@ -4503,9 +4520,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
break loop; break loop;
} }
} }
name = qualifiedName(); nameSpec = nameSpecifier();
ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(nameSpec, visibility, isVirtual);
setRange(baseSpec, startOffset, calculateEndOffset(name)); setRange(baseSpec, startOffset, calculateEndOffset(nameSpec));
return baseSpec; return baseSpec;
} }

View file

@ -1722,7 +1722,7 @@ public class CPPVisitor extends ASTQueries {
if (prop == IASTNamedTypeSpecifier.NAME || if (prop == IASTNamedTypeSpecifier.NAME ||
prop == ICPPASTPointerToMember.NAME || prop == ICPPASTPointerToMember.NAME ||
prop == ICPPASTUsingDeclaration.NAME || prop == ICPPASTUsingDeclaration.NAME ||
prop == ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME || prop == ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME_SPECIFIER ||
prop == ICPPASTTemplateId.TEMPLATE_NAME || prop == ICPPASTTemplateId.TEMPLATE_NAME ||
p2 == ICPPASTQualifiedName.SEGMENT_NAME) { p2 == ICPPASTQualifiedName.SEGMENT_NAME) {
break; break;

View file

@ -33,9 +33,11 @@ import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.internal.core.dom.rewrite.ASTLiteralNode; import org.eclipse.cdt.internal.core.dom.rewrite.ASTLiteralNode;
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap; import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
@ -70,6 +72,7 @@ public class ASTWriterVisitor extends ASTVisitor {
shouldVisitDeclarations = true; shouldVisitDeclarations = true;
shouldVisitDeclarators = true; shouldVisitDeclarators = true;
shouldVisitDeclSpecifiers = true; shouldVisitDeclSpecifiers = true;
shouldVisitDecltypeSpecifiers = true;
shouldVisitExpressions = true; shouldVisitExpressions = true;
shouldVisitInitializers = true; shouldVisitInitializers = true;
shouldVisitNames = true; shouldVisitNames = true;
@ -171,6 +174,15 @@ public class ASTWriterVisitor extends ASTVisitor {
return ASTVisitor.PROCESS_SKIP; return ASTVisitor.PROCESS_SKIP;
} }
@Override
public int visit(ICPPASTDecltypeSpecifier decltypeSpec) {
scribe.print(Keywords.DECLTYPE);
scribe.print('(');
decltypeSpec.getDecltypeExpression().accept(this);
scribe.print(')');
return ASTVisitor.PROCESS_SKIP;
}
@Override @Override
public int visit(IASTExpression expression) { public int visit(IASTExpression expression) {
writeLeadingComments(expression); writeLeadingComments(expression);

View file

@ -261,7 +261,7 @@ public class DeclSpecWriter extends NodeWriter {
scribe.print(COMMA_SPACE); scribe.print(COMMA_SPACE);
} }
} }
hasTrailingComments = hasTrailingComments(baseSpecifiers[baseSpecifiers.length-1].getName()); hasTrailingComments = hasTrailingComments(baseSpecifiers[baseSpecifiers.length-1].getNameSpecifier());
} }
} }
if (!hasTrailingComments) { if (!hasTrailingComments) {
@ -310,7 +310,7 @@ public class DeclSpecWriter extends NodeWriter {
if (specifier.isVirtual()) { if (specifier.isVirtual()) {
scribe.printStringSpace(Keywords.VIRTUAL); scribe.printStringSpace(Keywords.VIRTUAL);
} }
specifier.getName().accept(visitor); specifier.getNameSpecifier().accept(visitor);
} }
private String getCPPCompositeTypeString(int key) { private String getCPPCompositeTypeString(int key) {

View file

@ -1104,7 +1104,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
name = (IASTName) parentNode; name = (IASTName) parentNode;
parentNode = parentNode.getParent(); parentNode = parentNode.getParent();
} }
if (name.getPropertyInParent() == ICPPASTBaseSpecifier.NAME) if (name.getPropertyInParent() == ICPPASTBaseSpecifier.NAME_SPECIFIER)
pdomName.setIsBaseSpecifier(); pdomName.setIsBaseSpecifier();
} }
} }

View file

@ -108,6 +108,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
@ -369,6 +370,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
shouldVisitParameterDeclarations = true; shouldVisitParameterDeclarations = true;
shouldVisitDeclarators = true; shouldVisitDeclarators = true;
shouldVisitDeclSpecifiers = true; shouldVisitDeclSpecifiers = true;
shouldVisitDecltypeSpecifiers = true;
shouldVisitExpressions = true; shouldVisitExpressions = true;
shouldVisitStatements = true; shouldVisitStatements = true;
shouldVisitTypeIds = true; shouldVisitTypeIds = true;
@ -869,6 +871,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return PROCESS_SKIP; return PROCESS_SKIP;
} }
/*
* @see ASTVisitor#visit(ICPPASTDecltypeSpecifier)
*/
@Override
public int visit(ICPPASTDecltypeSpecifier node) {
formatRaw(node);
return PROCESS_SKIP;
}
/* /*
* @see ASTVisitor#visit(IASTExpression) * @see ASTVisitor#visit(IASTExpression)
*/ */
@ -1054,7 +1065,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (needSpace) { if (needSpace) {
scribe.space(); scribe.space();
} }
specifier.getName().accept(this); specifier.getNameSpecifier().accept(this);
exitNode(specifier); exitNode(specifier);
return PROCESS_SKIP; return PROCESS_SKIP;
} }

View file

@ -300,7 +300,7 @@ public class BindingClassifier {
* Example: * Example:
* class Y : X {}; // definition of X is required here * class Y : X {}; // definition of X is required here
*/ */
defineBindingForName(baseSpecifier.getName()); defineBinding(baseSpecifier.getNameSpecifier().resolveBinding());
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }

View file

@ -218,6 +218,7 @@ class THGraph {
try { try {
IBinding binding = IndexUI.elementToBinding(index, elem); IBinding binding = IndexUI.elementToBinding(index, elem);
if (binding != null) { if (binding != null) {
// TODO(nathanridge): Also find subclasses referenced via decltype-specifiers rather than names.
IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS); IIndexName[] names= index.findNames(binding, IIndex.FIND_REFERENCES | IIndex.FIND_DEFINITIONS);
for (IIndexName indexName : names) { for (IIndexName indexName : names) {
if (monitor.isCanceled()) { if (monitor.isCanceled()) {