diff options
author | Nathan Ridge | 2014-08-09 08:38:34 +0000 |
---|---|---|
committer | Sergey Prigogin | 2014-08-11 17:30:57 +0000 |
commit | 42235704cb6742c32119f12580bb486107140282 (patch) | |
tree | 4e2b6c2c2480d80064d48b6f7f47a5d1988c32a0 | |
parent | b7ec8deec417e0338a13f0f3bde024a2d84f07c3 (diff) | |
download | org.eclipse.cdt-42235704cb6742c32119f12580bb486107140282.tar.gz org.eclipse.cdt-42235704cb6742c32119f12580bb486107140282.tar.xz org.eclipse.cdt-42235704cb6742c32119f12580bb486107140282.zip |
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>
19 files changed, 210 insertions, 43 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index a6fdf220243..4e1eaafe4a6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -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.ICPPASTUsingDeclaration; 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.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; @@ -649,7 +650,7 @@ public class AST2CPPTests extends AST2TestBase { IASTName name_B1 = comp.getName(); ICPPASTBaseSpecifier base = comp.getBaseSpecifiers()[0]; - IASTName name_A2 = base.getName(); + IASTName name_A2 = (IASTName) base.getNameSpecifier(); decl = (IASTSimpleDeclaration) comp.getMembers()[0]; IASTName name_f1 = decl.getDeclarators()[0].getName(); @@ -8300,6 +8301,17 @@ public class AST2CPPTests extends AST2TestBase { public void testDecltypeInNameQualifier_380751() throws Exception { 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> // T bar(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java index 55a3ef1d2f1..4f09068d49c 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java @@ -681,7 +681,7 @@ public class CModelBuilder2 implements IContributedModelBuilder { final ICPPASTCompositeTypeSpecifier cppCompositeTypeSpecifier= (ICPPASTCompositeTypeSpecifier) compositeTypeSpecifier; ICPPASTBaseSpecifier[] baseSpecifiers= cppCompositeTypeSpecifier.getBaseSpecifiers(); for (final ICPPASTBaseSpecifier baseSpecifier : baseSpecifiers) { - final IASTName baseName= baseSpecifier.getName(); + final ICPPASTNameSpecifier nameSpec= baseSpecifier.getNameSpecifier(); final ASTAccessVisibility visibility; switch (baseSpecifier.getVisibility()) { case ICPPASTBaseSpecifier.v_public: @@ -696,7 +696,11 @@ public class CModelBuilder2 implements IContributedModelBuilder { default: 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); + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java index 3baae85be56..812fd37948a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTVisitor.java @@ -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.ICPPASTClassVirtSpecifier; 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.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier; @@ -147,6 +148,12 @@ public abstract class ASTVisitor { 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 * this flag to <code>true</code>. * @since 5.1 @@ -213,6 +220,7 @@ public abstract class ASTVisitor { shouldVisitTranslationUnit= visitNodes; shouldVisitTypeIds= visitNodes; shouldVisitVirtSpecifiers= visitNodes; + shouldVisitDecltypeSpecifiers= visitNodes; } // visit methods @@ -337,6 +345,13 @@ public abstract class ASTVisitor { public int visit(ICPPASTClassVirtSpecifier classVirtSpecifier) { return PROCESS_CONTINUE; } + + /** + * @since 5.8 + */ + public int visit(ICPPASTDecltypeSpecifier decltypeSpecifier) { + return PROCESS_CONTINUE; + } // leave methods public int leave(IASTTranslationUnit tu) { @@ -462,6 +477,13 @@ public abstract class ASTVisitor { } /** + * @since 5.8 + */ + public int leave(ICPPASTDecltypeSpecifier decltypeSpecifier) { + return PROCESS_CONTINUE; + } + + /** * @deprecated use {@link IASTTranslationUnit#getComments()}, instead. */ @Deprecated diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompositeTypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompositeTypeSpecifier.java index f69d5ef0e40..a951b6e874e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompositeTypeSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTCompositeTypeSpecifier.java @@ -60,10 +60,21 @@ public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifie /** * Relation between base specifier and its name. + * + * @deprecated Use ICPPASTBaseSpecifier.NAME_SPECIFIER instead. */ + @Deprecated public static final ASTNodeProperty NAME = new ASTNodeProperty( "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_protected = ICPPASTVisibilityLabel.v_protected; public static final int v_private = ICPPASTVisibilityLabel.v_private; @@ -80,10 +91,20 @@ public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifie /** * Returns the name of this specifier. + * + * @deprecated Use getNameSpecifier() instead. */ + @Deprecated public IASTName getName(); /** + * Returns the name specifier inside this base specifier. + * + * @since 5.8 + */ + public ICPPASTNameSpecifier getNameSpecifier(); + + /** * @since 5.1 */ @Override @@ -97,10 +118,20 @@ public interface ICPPASTCompositeTypeSpecifier extends IASTCompositeTypeSpecifie /** * Sets the name for this specifier, not allowed on frozen AST. + * + * @deprecated Use setNameSpecifier() instead. */ + @Deprecated 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. */ public void setVirtual(boolean value); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java index 91e6e5bc8e4..d37d910d1e5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNodeFactory.java @@ -65,8 +65,14 @@ public interface ICPPNodeFactory extends INodeFactory { */ public ICPPASTAttributeSpecifier newAttributeSpecifier(); + @Deprecated public ICPPASTBaseSpecifier newBaseSpecifier(IASTName name, int visibility, boolean isVirtual); + /** + * @since 5.8 + */ + public ICPPASTBaseSpecifier newBaseSpecifier(ICPPASTNameSpecifier nameSpecifier, int visibility, boolean isVirtual); + @Override public ICPPASTBinaryExpression newBinaryExpression(int op, IASTExpression expr1, IASTExpression expr2); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java index 6fbbf27cf65..35ded82d1d0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBaseSpecifier.java @@ -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.ICPPASTCompletionContext; 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.internal.core.dom.parser.ASTNode; 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 int visibility; - private IASTName name; + private ICPPASTNameSpecifier nameSpecifier; private boolean fIsPackExpansion; public CPPASTBaseSpecifier() { } - public CPPASTBaseSpecifier(IASTName name) { - setName(name); + public CPPASTBaseSpecifier(ICPPASTNameSpecifier nameSpecifier) { + setNameSpecifier(nameSpecifier); } - public CPPASTBaseSpecifier(IASTName name, int visibility, boolean isVirtual) { + public CPPASTBaseSpecifier(ICPPASTNameSpecifier nameSpecifier, int visibility, boolean isVirtual) { this.isVirtual = isVirtual; this.visibility = visibility; - setName(name); + setNameSpecifier(nameSpecifier); } @Override @@ -55,7 +57,7 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier @Override 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.visibility = visibility; copy.fIsPackExpansion= fIsPackExpansion; @@ -85,19 +87,35 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier } @Override + @Deprecated 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 + @Deprecated public void setName(IASTName name) { - assertNotFrozen(); - this.name = name; - if (name != null) { - name.setParent(this); - name.setPropertyInParent(NAME); - } + setNameSpecifier((ICPPASTName) name); } + + @Override + public ICPPASTNameSpecifier getNameSpecifier() { + return nameSpecifier; + } + + @Override + public void setNameSpecifier(ICPPASTNameSpecifier nameSpecifier) { + assertNotFrozen(); + this.nameSpecifier = nameSpecifier; + if (nameSpecifier != null) { + nameSpecifier.setParent(this); + nameSpecifier.setPropertyInParent(NAME_SPECIFIER); + } + } @Override public boolean accept(ASTVisitor action) { @@ -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; if (action.shouldVisitBaseSpecifiers && action.leave(this) == ASTVisitor.PROCESS_ABORT) @@ -120,7 +138,7 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier @Override public int getRoleForName(IASTName n) { - if (name == n) return r_reference; + if (nameSpecifier == n) return r_reference; return r_unclear; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDecltypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDecltypeSpecifier.java index caf601b7f3f..05237448d18 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDecltypeSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDecltypeSpecifier.java @@ -68,7 +68,26 @@ public class CPPASTDecltypeSpecifier extends ASTNode @Override 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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java index 15eb50c2ef9..a4a8766e86d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPBaseClause.java @@ -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.cpp.ICPPASTCompositeTypeSpecifier; 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.ICPPClassType; @@ -49,16 +50,17 @@ public class CPPBaseClause implements ICPPBase, ICPPInternalBase { @Override public IType getBaseClassType() { if (baseClass == null) { - IBinding b = base.getName().resolveBinding(); + ICPPASTNameSpecifier nameSpec = base.getNameSpecifier(); + IBinding b = nameSpec.resolveBinding(); 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)) { - baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ISemanticProblem.BINDING_NO_CLASS); + baseClass = new CPPClassType.CPPClassTypeProblem(nameSpec, ISemanticProblem.BINDING_NO_CLASS); } else { baseClass= (IType) b; IType check= getNestedType(baseClass, TDEF); 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); } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index 6eb08dd0e4b..4936d67c683 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -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.cpp.ICPPASTCompositeTypeSpecifier; 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.ICPPBase; 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) { 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) { super(node, id, arg); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java index e1545e71ffa..2dfc8cd43c8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java @@ -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.ICPPASTLiteralExpression; 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.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; @@ -184,8 +185,14 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { } @Override + @Deprecated 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 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index ed2e8c03eb4..b544ab03738 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -713,6 +713,7 @@ public class ClassTypeHelper { 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); for (IIndexName indexName : names) { if (indexName.isBaseSpecifier()) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index ed31b571bd7..334750bd871 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -228,16 +228,16 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { throw backtrack; } - private IASTName qualifiedName() throws BacktrackException, EndOfFileException { - return ambiguousQualifiedName(CastExprCtx.eNotInBExpr); + private ICPPASTNameSpecifier nameSpecifier() throws BacktrackException, EndOfFileException { + return ambiguousNameSpecifier(CastExprCtx.eNotInBExpr); } - private IASTName ambiguousQualifiedName(CastExprCtx ctx) throws BacktrackException, EndOfFileException { + private ICPPASTNameSpecifier ambiguousNameSpecifier(CastExprCtx ctx) throws BacktrackException, EndOfFileException { TemplateIdStrategy strat= new TemplateIdStrategy(); IToken m= mark(); while (true) { try { - return qualifiedName(ctx, strat); + return nameSpecifier(ctx, strat); } catch (BacktrackException e) { if (strat.setNextAlternative()) { 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) - return ambiguousQualifiedName(ctx); + return ambiguousNameSpecifier(ctx); ICPPASTQualifiedName qname= null; ICPPASTNameSpecifier nameSpec= null; @@ -355,11 +355,28 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { setRange(qname, offset, endOffset); 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 :: + throwBacktrack(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 (IASTName) nameSpec; + return (ICPPASTName) nameSpec; } private void addNameSpecifier(ICPPASTQualifiedName qname, ICPPASTNameSpecifier nameSpec) { @@ -4480,7 +4497,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { int startOffset= LA(1).getOffset(); boolean isVirtual = false; int visibility = 0; - IASTName name = null; + ICPPASTNameSpecifier nameSpec = null; loop: for (;;) { switch (LT(1)) { case IToken.t_virtual: @@ -4503,9 +4520,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { break loop; } } - name = qualifiedName(); - ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(name, visibility, isVirtual); - setRange(baseSpec, startOffset, calculateEndOffset(name)); + nameSpec = nameSpecifier(); + ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier baseSpec = nodeFactory.newBaseSpecifier(nameSpec, visibility, isVirtual); + setRange(baseSpec, startOffset, calculateEndOffset(nameSpec)); return baseSpec; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 5054fa69efe..1016dedc967 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -1722,7 +1722,7 @@ public class CPPVisitor extends ASTQueries { if (prop == IASTNamedTypeSpecifier.NAME || prop == ICPPASTPointerToMember.NAME || prop == ICPPASTUsingDeclaration.NAME || - prop == ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME || + prop == ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier.NAME_SPECIFIER || prop == ICPPASTTemplateId.TEMPLATE_NAME || p2 == ICPPASTQualifiedName.SEGMENT_NAME) { break; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java index 6ed9d47371f..7c4585fb742 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/ASTWriterVisitor.java @@ -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.IASTTranslationUnit; 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.ICPPASTTemplateParameter; 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.commenthandler.NodeCommentMap; @@ -70,6 +72,7 @@ public class ASTWriterVisitor extends ASTVisitor { shouldVisitDeclarations = true; shouldVisitDeclarators = true; shouldVisitDeclSpecifiers = true; + shouldVisitDecltypeSpecifiers = true; shouldVisitExpressions = true; shouldVisitInitializers = true; shouldVisitNames = true; @@ -170,6 +173,15 @@ public class ASTWriterVisitor extends ASTVisitor { declSpecWriter.writeDelcSpec(declSpec); 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 public int visit(IASTExpression expression) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java index e7482b2302d..9c7e293c67a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/DeclSpecWriter.java @@ -261,7 +261,7 @@ public class DeclSpecWriter extends NodeWriter { scribe.print(COMMA_SPACE); } } - hasTrailingComments = hasTrailingComments(baseSpecifiers[baseSpecifiers.length-1].getName()); + hasTrailingComments = hasTrailingComments(baseSpecifiers[baseSpecifiers.length-1].getNameSpecifier()); } } if (!hasTrailingComments) { @@ -310,7 +310,7 @@ public class DeclSpecWriter extends NodeWriter { if (specifier.isVirtual()) { scribe.printStringSpace(Keywords.VIRTUAL); } - specifier.getName().accept(visitor); + specifier.getNameSpecifier().accept(visitor); } private String getCPPCompositeTypeString(int key) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 83bbde90dd2..f23ebca3ca9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -1104,7 +1104,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { name = (IASTName) parentNode; parentNode = parentNode.getParent(); } - if (name.getPropertyInParent() == ICPPASTBaseSpecifier.NAME) + if (name.getPropertyInParent() == ICPPASTBaseSpecifier.NAME_SPECIFIER) pdomName.setIsBaseSpecifier(); } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java index ee45cb854fd..ba913a88f75 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java @@ -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.ICPPASTConstructorChainInitializer; 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.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; @@ -369,6 +370,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, shouldVisitParameterDeclarations = true; shouldVisitDeclarators = true; shouldVisitDeclSpecifiers = true; + shouldVisitDecltypeSpecifiers = true; shouldVisitExpressions = true; shouldVisitStatements = true; shouldVisitTypeIds = true; @@ -868,6 +870,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, exitNode(node); return PROCESS_SKIP; } + + /* + * @see ASTVisitor#visit(ICPPASTDecltypeSpecifier) + */ + @Override + public int visit(ICPPASTDecltypeSpecifier node) { + formatRaw(node); + return PROCESS_SKIP; + } /* * @see ASTVisitor#visit(IASTExpression) @@ -1054,7 +1065,7 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor, if (needSpace) { scribe.space(); } - specifier.getName().accept(this); + specifier.getNameSpecifier().accept(this); exitNode(specifier); return PROCESS_SKIP; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java index e90fa8bc8a2..72286ab5758 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/includes/BindingClassifier.java @@ -300,7 +300,7 @@ public class BindingClassifier { * Example: * class Y : X {}; // definition of X is required here */ - defineBindingForName(baseSpecifier.getName()); + defineBinding(baseSpecifier.getNameSpecifier().resolveBinding()); return PROCESS_CONTINUE; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java index 5db8a9abf20..ef61b1625e8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THGraph.java @@ -218,6 +218,7 @@ class THGraph { try { IBinding binding = IndexUI.elementToBinding(index, elem); 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); for (IIndexName indexName : names) { if (monitor.isCanceled()) { |