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:
parent
b7ec8deec4
commit
42235704cb
19 changed files with 210 additions and 43 deletions
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
Loading…
Add table
Reference in a new issue