1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-30 20:35:38 +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.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();

View file

@ -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);
}
}
}

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.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;
@ -146,6 +147,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>.
@ -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) {
@ -461,6 +476,13 @@ public abstract class ASTVisitor {
return PROCESS_CONTINUE;
}
/**
* @since 5.8
*/
public int leave(ICPPASTDecltypeSpecifier decltypeSpecifier) {
return PROCESS_CONTINUE;
}
/**
* @deprecated use {@link IASTTranslationUnit#getComments()}, instead.
*/

View file

@ -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,9 +91,19 @@ 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
*/
@ -97,9 +118,19 @@ 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.
*/

View file

@ -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);

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.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;
}

View file

@ -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

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.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);
}
}
}

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.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);
}

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.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

View file

@ -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()) {

View file

@ -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 (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) {
@ -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;
}

View file

@ -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;

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.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) {

View file

@ -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) {

View file

@ -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();
}
}

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.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;
}

View file

@ -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;
}

View file

@ -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()) {