diff options
Diffstat (limited to 'core/org.eclipse.cdt.core/parser')
32 files changed, 560 insertions, 218 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java index ab3523e7e88..1854a195176 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTConversionName.java @@ -11,7 +11,6 @@ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; -import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTTypeId; /** @@ -20,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPASTConversionName extends IASTName { +public interface ICPPASTConversionName extends ICPPASTName { public static final ASTNodeProperty TYPE_ID=new ASTNodeProperty( "IASTArrayDeclarator.TYPE_ID - IASTTypeId for ICPPASTConversionName"); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTDecltypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTDecltypeSpecifier.java new file mode 100644 index 00000000000..8931012add8 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTDecltypeSpecifier.java @@ -0,0 +1,26 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +/** + * C++ AST node for decltype-specifiers. + * + * Currently, this class is only used to represent decltype-specifiers + * in qualified names, not in decl-specifiers (in decl-specifiers, + * a decltype-specifier is represented as an ICPPASTSimpleDeclSpecifier). + * + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + * @since 5.6 + */ +public interface ICPPASTDecltypeSpecifier extends ICPPASTNameSpecifier { + ICPPASTExpression getDecltypeExpression(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTName.java new file mode 100644 index 00000000000..bcb2e55fd2d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTName.java @@ -0,0 +1,28 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTName; + +/** + * AST node for names in C++ translation units. + * + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + * @since 5.6 + */ +public interface ICPPASTName extends IASTName, ICPPASTNameSpecifier { + @Override + public ICPPASTName copy(); + + @Override + public ICPPASTName copy(CopyStyle style); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNameSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNameSpecifier.java new file mode 100644 index 00000000000..1c5cc664150 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTNameSpecifier.java @@ -0,0 +1,52 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.core.dom.ast.cpp; + +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; + +/** + * AST node for elements of the qualifier in a qualified name. + * + * A name-specifier can either be a name, or a decltype-specifier. + * + * Note that a decltype-specifier can only appear as the first + * element of a qualifier, but this constraint is not encoded + * in the AST. + * + * @noimplement This interface is not intended to be implemented by clients. + * @noextend This interface is not intended to be extended by clients. + * @since 5.6 + */ +public interface ICPPASTNameSpecifier extends IASTNode { + public static final ICPPASTNameSpecifier[] EMPTY_NAME_SPECIFIER_ARRAY = {}; + + @Override + public ICPPASTNameSpecifier copy(); + + @Override + public ICPPASTNameSpecifier copy(CopyStyle style); + + public char[] toCharArray(); + + /** + * If the name-specifier is a name, returns the binding named. + * If the name-specifier is a decltype-specifier, return the type + * if it's a binding, otherwise return null. + */ + public IBinding resolveBinding(); + + /** + * Similar to resolveBinding(), but only performs the first phase + * of binding resolution for two-phase bindings. + */ + public IBinding resolvePreBinding(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java index 344960f2a06..597a1827321 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTOperatorName.java @@ -11,14 +11,12 @@ *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; -import org.eclipse.cdt.core.dom.ast.IASTName; - /** * This interface represents a C++ overloaded operator member function name. * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPASTOperatorName extends IASTName { +public interface ICPPASTOperatorName extends ICPPASTName { /** * @since 5.1 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java index 06ba50d891b..d0a9752f92f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTQualifiedName.java @@ -20,12 +20,12 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPASTQualifiedName extends IASTName, IASTNameOwner { +public interface ICPPASTQualifiedName extends ICPPASTName, IASTNameOwner { /** - * Each IASTName segment has property being <code>SEGMENT_NAME</code>. + * Each ICPPASTNameSpecifier segment has property being <code>SEGMENT_NAME</code>. */ public static final ASTNodeProperty SEGMENT_NAME = new ASTNodeProperty( - "ICPPASTQualifiedName.SEGMENT_NAME - An IASTName segment"); //$NON-NLS-1$ + "ICPPASTQualifiedName.SEGMENT_NAME - An ICPPASTNameSpecifier segment"); //$NON-NLS-1$ /** * Adds a name segment. @@ -33,15 +33,56 @@ public interface ICPPASTQualifiedName extends IASTName, IASTNameOwner { * @param name {@code IASTName} */ public void addName(IASTName name); + + /** + * Adds a segment to the end of the qualifier. + * + * @since 5.6 + */ + public void addNameSpecifier(ICPPASTNameSpecifier nameSpecifier); + + /** + * Sets the last name. + * + * @since 5.6 + */ + public void setLastName(ICPPASTName name); /** * Returns all name segments. * - * @return {@code IASTName[]} + * @return <code>IASTName []</code> + * + * @deprecated This cannot represent all qualified names in C++11, + * where the first segment of a qualifier name may be a decltype-specifier. + * Use {@link #getLastName()} and {@link #getQualifier()} instead. + * If called on a name where a segment is a decltype-specifier, + * UnsupportedOperationException is thrown. */ + @Deprecated public IASTName[] getNames(); /** + * Returns all segments of the name but the last. + * + * @since 5.6 + */ + public ICPPASTNameSpecifier[] getQualifier(); + + /** + * Returns all segments of the name. + * + * This method is less efficient than calling getQualifier() and + * getLastName() separately, because it constructs a new array. + * It is provided mainly to ease transition of client code from + * getNames() to getQualifier() and getLastName(). + * + * @noreference This method is not intended to be referenced by clients. + * @since 5.6 + */ + public ICPPASTNameSpecifier[] getAllSegments(); + + /** * The last name is often semantically significant. */ @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplateId.java index 469ab2fd2ca..2a730faa0f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplateId.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTTemplateId.java @@ -22,7 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; * @noextend This interface is not intended to be extended by clients. * @noimplement This interface is not intended to be implemented by clients. */ -public interface ICPPASTTemplateId extends IASTName, IASTNameOwner { +public interface ICPPASTTemplateId extends ICPPASTName, IASTNameOwner { /** * TEMPLATE_NAME is the IASTName. */ 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 101613b3ba4..49db5b0839c 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 @@ -110,6 +110,11 @@ public interface ICPPNodeFactory extends INodeFactory { @Override public ICPPASTDeclarator newDeclarator(IASTName name); + /** + * @since 5.6 + */ + public ICPPASTDecltypeSpecifier newDecltypeSpecifier(ICPPASTExpression decltypeExpression); + public ICPPASTDeleteExpression newDeleteExpression(IASTExpression operand); @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java index d9b96c6ca88..46b86d1f30a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java @@ -247,10 +247,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements } else { CPPASTImplicitName ctorName = new CPPASTImplicitName(ctor.getNameCharArray(), this); ctorName.setBinding(ctor); - IASTName id = name; - if (id instanceof ICPPASTQualifiedName) { - id = ((ICPPASTQualifiedName) id).getLastName(); - } + IASTName id = name.getLastName(); ctorName.setOffsetAndLength((ASTNode) id); implicitNames = new IASTImplicitName[] { ctorName }; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java index 82406fdc64b..afe67b15d14 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java @@ -313,7 +313,7 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator, IAST ctorName.setBinding(ctor); IASTName id = name; if (id instanceof ICPPASTQualifiedName) { - id = ((ICPPASTQualifiedName) id).getLastName(); + id = id.getLastName(); } ctorName.setOffsetAndLength((ASTNode) id); implicitNames = new IASTImplicitName[] { ctorName }; 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 new file mode 100644 index 00000000000..2fd1b0e4a18 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDecltypeSpecifier.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2013 Nathan Ridge + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Nathan Ridge - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDecltypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; +import org.eclipse.cdt.core.parser.Keywords; +import org.eclipse.cdt.internal.core.dom.parser.ASTNode; + +/** + * Implementation of ICPPASTDecltypeSpecifier. + */ +public class CPPASTDecltypeSpecifier extends ASTNode implements ICPPASTDecltypeSpecifier { + private ICPPASTExpression fDecltypeExpression; + private char[] fSignature; + + public CPPASTDecltypeSpecifier(ICPPASTExpression decltypeExpression) { + fDecltypeExpression = decltypeExpression; + fDecltypeExpression.setParent(this); + } + + @Override + public ICPPASTExpression getDecltypeExpression() { + return fDecltypeExpression; + } + + @Override + public CPPASTDecltypeSpecifier copy() { + return copy(CopyStyle.withoutLocations); + } + + @Override + public CPPASTDecltypeSpecifier copy(CopyStyle style) { + CPPASTDecltypeSpecifier copy = new CPPASTDecltypeSpecifier((ICPPASTExpression) fDecltypeExpression.copy(style)); + copy.setOffsetAndLength(this); + if (style == CopyStyle.withLocations) { + copy.setCopyLocation(this); + } + return copy; + } + + @Override + public char[] toCharArray() { + if (fSignature == null) { + StringBuilder buffer = new StringBuilder(); + buffer.append(Keywords.cDECLTYPE); + buffer.append(Keywords.cpLPAREN); + buffer.append(fDecltypeExpression.getEvaluation().getSignature()); + buffer.append(Keywords.cpRPAREN); + final int len = buffer.length(); + fSignature = new char[len]; + buffer.getChars(0, len, fSignature, 0); + } + return fSignature; + } + + @Override + public boolean accept(ASTVisitor visitor) { + return fDecltypeExpression.accept(visitor); + } + + @Override + public IBinding resolveBinding() { + IType type = fDecltypeExpression.getExpressionType(); + if (type instanceof IBinding) + return (IBinding) type; + return null; + } + + @Override + public IBinding resolvePreBinding() { + return resolveBinding(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index d90230333e2..03e511c30f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; +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.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; @@ -268,13 +269,14 @@ public class CPPASTFieldReference extends ASTNode ICPPTemplateArgument[] args= null; IASTName n= name; if (n instanceof ICPPASTQualifiedName) { - IASTName[] ns= ((ICPPASTQualifiedName) n).getNames(); - if (ns.length < 2) + ICPPASTQualifiedName qn= (ICPPASTQualifiedName) n; + ICPPASTNameSpecifier[] ns= qn.getQualifier(); + if (ns.length < 1) return EvalFixed.INCOMPLETE; - qualifier= ns[ns.length - 2].resolveBinding(); + qualifier= ns[ns.length - 1].resolveBinding(); if (qualifier instanceof IProblemBinding) return EvalFixed.INCOMPLETE; - n= ns[ns.length - 1]; + n= qn.getLastName(); } if (n instanceof ICPPASTTemplateId) { try { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java index ccf58470346..f7c240a7566 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNameBase.java @@ -19,6 +19,8 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; +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.ICPPASTQualifiedName; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; @@ -31,7 +33,7 @@ import org.eclipse.core.runtime.Assert; * Common base class for all sorts of c++ names: unqualified, qualified, operator and conversion * names plus template-ids */ -public abstract class CPPASTNameBase extends ASTNode implements IASTName { +public abstract class CPPASTNameBase extends ASTNode implements ICPPASTName { protected static final Pattern WHITESPACE_SEQ = Pattern.compile("\\s+"); //$NON-NLS-1$ /** @@ -161,8 +163,8 @@ public abstract class CPPASTNameBase extends ASTNode implements IASTName { ICPPASTQualifiedName qn= (ICPPASTQualifiedName) parent; if (qn.isFullyQualified()) return true; - IASTName[] qns = qn.getNames(); - if (qns.length > 0 && qns[0] == this) + ICPPASTNameSpecifier[] qualifier = qn.getQualifier(); + if (qualifier.length > 0 && qualifier[0] == this) return false; return true; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java index ab1d0b4cb13..6492dd8ea83 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2011 IBM Corporation and others. + * Copyright (c) 2004, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) + * Nathan Ridge *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -31,6 +32,8 @@ import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; +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.ICPPASTOperatorName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -55,13 +58,22 @@ import org.eclipse.core.runtime.Assert; */ public class CPPASTQualifiedName extends CPPASTNameBase implements ICPPASTQualifiedName, ICPPASTCompletionContext { - private IASTName[] names; - private int namesPos= -1; - private boolean isFullyQualified; - private char[] signature; + private ICPPASTNameSpecifier[] fQualifier; + private int fQualifierPos = -1; + private ICPPASTName fLastName; + private boolean fIsFullyQualified; + private char[] fSignature; + /** + * @deprecated Prefer CPPASTQualifierName(ICPPASTName) instead. + */ + @Deprecated public CPPASTQualifiedName() { } + + public CPPASTQualifiedName(ICPPASTName lastName) { + setLastName(lastName); + } @Override public CPPASTQualifiedName copy() { @@ -71,10 +83,12 @@ public class CPPASTQualifiedName extends CPPASTNameBase @Override public CPPASTQualifiedName copy(CopyStyle style) { CPPASTQualifiedName copy = new CPPASTQualifiedName(); - for (IASTName name : getNames()) { - copy.addName(name == null ? null : name.copy(style)); + if (fLastName != null) + copy.addName(fLastName.copy(style)); + for (ICPPASTNameSpecifier nameSpecifier : getQualifier()) { + copy.addNameSpecifier(nameSpecifier == null ? null : nameSpecifier.copy(style)); } - copy.setFullyQualified(isFullyQualified); + copy.setFullyQualified(fIsFullyQualified); copy.setOffsetAndLength(this); if (style == CopyStyle.withLocations) { copy.setCopyLocation(this); @@ -113,69 +127,116 @@ public class CPPASTQualifiedName extends CPPASTNameBase @Override public void addName(IASTName name) { - assertNotFrozen(); - assert !(name instanceof ICPPASTQualifiedName); - if (name != null) { - names = ArrayUtil.appendAt(IASTName.class, names, ++namesPos, name); - name.setParent(this); - name.setPropertyInParent(SEGMENT_NAME); + if (fLastName != null) + addNameSpecifier(fLastName); + setLastName((ICPPASTName) name); + } + + @Override + public void setLastName(ICPPASTName lastName) { + assertNotFrozen(); + assert !(lastName instanceof ICPPASTQualifiedName); + fLastName = lastName; + fLastName.setParent(this); + fLastName.setPropertyInParent(SEGMENT_NAME); + } + + @Override + public void addNameSpecifier(ICPPASTNameSpecifier nameSpecifier) { + assertNotFrozen(); + assert !(nameSpecifier instanceof ICPPASTQualifiedName); + if (nameSpecifier != null) { + fQualifier = ArrayUtil.appendAt(ICPPASTNameSpecifier.class, fQualifier, ++fQualifierPos, nameSpecifier); + nameSpecifier.setParent(this); + nameSpecifier.setPropertyInParent(SEGMENT_NAME); } } @Override + public ICPPASTNameSpecifier[] getQualifier() { + if (fQualifierPos < 0) + return ICPPASTNameSpecifier.EMPTY_NAME_SPECIFIER_ARRAY; + + fQualifier = ArrayUtil.trimAt(ICPPASTNameSpecifier.class, fQualifier, fQualifierPos); + return fQualifier; + } + + @Override + public ICPPASTNameSpecifier[] getAllSegments() { + ICPPASTNameSpecifier[] result = new ICPPASTNameSpecifier[fQualifierPos + (fLastName == null ? 1 : 2)]; + int idx = 0; + for (ICPPASTNameSpecifier nameSpecifier : getQualifier()) + result[idx++] = nameSpecifier; + if (fLastName != null) + result[fQualifierPos + 1] = fLastName; + return result; + } + + @Override + @Deprecated public IASTName[] getNames() { - if (namesPos < 0) - return IASTName.EMPTY_NAME_ARRAY; - - names = ArrayUtil.trimAt(IASTName.class, names, namesPos); - return names; + IASTName[] result = new IASTName[fQualifierPos + (fLastName == null ? 1 : 2)]; + int idx = 0; + for (ICPPASTNameSpecifier nameSpecifier : getQualifier()) { + if (nameSpecifier instanceof IASTName) { + result[idx++] = (IASTName) nameSpecifier; + } else { + throw new UnsupportedOperationException("Can't use getNames() on a " + //$NON-NLS-1$ + "qualified name that includes a decltype-specifier. Use " + //$NON-NLS-1$ + "getQualifier() and getLastName() instead."); //$NON-NLS-1$ + } + } + if (fLastName != null) + result[fQualifierPos + 1] = fLastName; + return result; } @Override public IASTName getLastName() { - if (namesPos < 0) - return null; - - return names[namesPos]; + return fLastName; } @Override public char[] getSimpleID() { - return names[namesPos].getSimpleID(); + return fLastName.getSimpleID(); } @Override public char[] getLookupKey() { - return names[namesPos].getLookupKey(); + return fLastName.getLookupKey(); } @Override public char[] toCharArray() { - if (signature == null) { + if (fSignature == null) { StringBuilder buf= new StringBuilder(); - for (int i = 0; i <= namesPos; i++) { - if (i > 0 || isFullyQualified) { + for (int i = 0; i <= fQualifierPos; i++) { + if (i > 0 || fIsFullyQualified) { buf.append(Keywords.cpCOLONCOLON); } - buf.append(names[i].toCharArray()); + buf.append(fQualifier[i].toCharArray()); + } + if (fQualifierPos >= 0 || fIsFullyQualified) { + buf.append(Keywords.cpCOLONCOLON); } + buf.append(fLastName.toCharArray()); final int len= buf.length(); - signature= new char[len]; - buf.getChars(0, len, signature, 0); + fSignature= new char[len]; + buf.getChars(0, len, fSignature, 0); } - return signature; + return fSignature; } @Override public boolean isFullyQualified() { - return isFullyQualified; + return fIsFullyQualified; } @Override public void setFullyQualified(boolean isFullyQualified) { assertNotFrozen(); - this.isFullyQualified = isFullyQualified; + this.fIsFullyQualified = isFullyQualified; } /** @@ -197,16 +258,12 @@ public class CPPASTQualifiedName extends CPPASTNameBase break; } } - for (int i = 0; i <= namesPos; i++) { - final IASTName name = names[i]; - if (i == namesPos) { - // Pointer-to-member qualified names have a dummy name as the last segment - // of the name, don't visit it. - if (name.getLookupKey().length > 0 && !name.accept(action)) - return false; - } else if (!name.accept(action)) + for (ICPPASTNameSpecifier nameSpecifier : getQualifier()) + if (!nameSpecifier.accept(action)) return false; - } + // pointer-to-member qualified names have a dummy name as the last part of the name, don't visit it + if (fLastName != null && fLastName.getLookupKey().length > 0 && !fLastName.accept(action)) + return false; if (action.shouldVisitNames) { switch (action.leave(this)) { @@ -236,8 +293,8 @@ public class CPPASTQualifiedName extends CPPASTNameBase @Override public int getRoleForName(IASTName n) { - for (int i=0; i < namesPos; ++i) { - if (names[i] == n) + for (int i=0; i <= fQualifierPos; ++i) { + if (fQualifier[i] == n) return r_reference; } if (getLastName() == n) { @@ -271,8 +328,8 @@ public class CPPASTQualifiedName extends CPPASTNameBase public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); - if (namesPos > 0) { - IBinding binding = names[namesPos - 1].resolveBinding(); + if (fQualifierPos >= 0) { + IBinding binding = fQualifier[fQualifierPos].resolveBinding(); if (binding instanceof ICPPClassType) { ICPPClassType classType = (ICPPClassType) binding; final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration; @@ -349,7 +406,7 @@ public class CPPASTQualifiedName extends CPPASTNameBase return filtered; } - private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) { + private static boolean nameMatches(char[] potential, char[] name, boolean isPrefix) { if (isPrefix) return ContentAssistMatcherFactory.getInstance().match(name, potential); return CharArrayUtils.equals(potential, name); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index d08793f4d25..eef19258fc3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -42,6 +42,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.ICPPASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; @@ -169,9 +170,22 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { // Check whether the qualification matches. IBinding b= getClassType(); final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) name; - final IASTName[] names= qname.getNames(); - for (int i = names.length - 1; --i >= 0;) { - if (b == null || !CharArrayUtils.equals(names[i].getLookupKey(), b.getNameCharArray())) + final ICPPASTNameSpecifier[] qualifier = qname.getQualifier(); + for (int i = qualifier.length; --i >= 0;) { + if (b == null) + return; + + char[] segmentName; + if (qualifier[i] instanceof IASTName) { + segmentName = ((IASTName) qualifier[i]).getLookupKey(); + } else { + IBinding segmentBinding = qualifier[i].resolveBinding(); + if (segmentBinding == null) + return; + segmentName = segmentBinding.getNameCharArray(); + } + + if (!CharArrayUtils.equals(segmentName, b.getNameCharArray())) return; b= b.getOwner(); 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 10fcdb8cea5..1e1d77fd62b 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 @@ -412,8 +412,7 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp private IASTName stripQualifier(IASTName name) { if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); - name = ns[ns.length - 1]; + name = ((ICPPASTQualifiedName)name).getLastName(); } return name; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index acd531befc0..609079c9ed7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -223,12 +223,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt protected IASTName getASTName() { IASTDeclarator dtor = (definition != null) ? definition : declarations[0]; dtor= ASTQueries.findInnermostDeclarator(dtor); - IASTName name= dtor.getName(); - if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); - name = ns[ns.length - 1]; - } - return name; + return dtor.getName().getLastName(); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java index d7c48d63df8..34b53ea71a9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethod.java @@ -131,8 +131,7 @@ public class CPPMethod extends CPPFunction implements ICPPMethod { dtor= ASTQueries.findInnermostDeclarator(dtor); IASTName name= dtor.getName(); if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - name = ns[ns.length - 1]; + name = name.getLastName(); } return name; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java index 54c580a3518..c4b2729e587 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java @@ -26,13 +26,16 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFileSet; @@ -158,7 +161,7 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace public boolean canDenoteNamespaceMember(ICPPASTQualifiedName name) { IScope scope= this; - IASTName[] segments= name.getNames(); + ICPPASTNameSpecifier[] segments= name.getQualifier(); try { for (int i= segments.length - 1; --i >= 0;) { if (scope == null) @@ -167,10 +170,18 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace if (scopeName == null) return false; - IASTName segmentName = segments[i]; - if (segmentName instanceof ICPPASTTemplateId || - !CharArrayUtils.equals(scopeName.getSimpleID(), segmentName.getSimpleID())) { - return false; + if (segments[i] instanceof IASTName) { + IASTName segmentName = (IASTName) segments[i]; + if (segmentName instanceof ICPPASTTemplateId || + !CharArrayUtils.equals(scopeName.getSimpleID(), segmentName.getSimpleID())) { + return false; + } + } else { + IBinding segmentBinding = segments[i].resolveBinding(); + if (segmentBinding instanceof ICPPTemplateInstance || + !CharArrayUtils.equals(scopeName.getSimpleID(), segmentBinding.getNameCharArray())) { + return false; + } } scope= scope.getParent(); } 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 fedcacd8a32..26a382a2794 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 @@ -65,10 +65,12 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; +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.ICPPASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; @@ -267,6 +269,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory { } @Override + public ICPPASTDecltypeSpecifier newDecltypeSpecifier(ICPPASTExpression decltypeExpression) { + return new CPPASTDecltypeSpecifier(decltypeExpression); + } + + @Override public IASTDefaultStatement newDefaultStatement() { return new CPPASTDefaultStatement(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java index 2c253c00595..432601f7ed4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java @@ -12,11 +12,12 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +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.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; @@ -70,26 +71,27 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe @Override public IType getMemberOfClass() { if (classType == null) { - IASTName name; + ICPPASTNameSpecifier nameSpec; IBinding binding= null; ICPPASTPointerToMember pm = operator; if (pm == null) { - name= new CPPASTName(); + nameSpec = new CPPASTName(); } else { - name = pm.getName(); - if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - if (ns.length > 1) - name = ns[ns.length - 2]; + nameSpec = (ICPPASTName) pm.getName(); + if (nameSpec instanceof ICPPASTQualifiedName) { + ICPPASTQualifiedName qname = ((ICPPASTQualifiedName) nameSpec); + ICPPASTNameSpecifier[] qualifier = qname.getQualifier(); + if (qualifier.length > 0) + nameSpec = qualifier[qualifier.length - 1]; else - name = ns[ns.length - 1]; + nameSpec = (ICPPASTName) qname.getLastName(); } - binding = name.resolvePreBinding(); + binding = nameSpec.resolvePreBinding(); } if (binding instanceof IType) { classType = (IType) binding; } else { - classType = new CPPClassType.CPPClassTypeProblem(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray()); + classType = new CPPClassType.CPPClassTypeProblem(nameSpec, IProblemBinding.SEMANTIC_INVALID_TYPE, nameSpec.toCharArray()); } } return classType; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index 452640243af..79f92c900bf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -238,10 +238,9 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC @Override public void addDefinition(IASTNode node) { if (node instanceof ICPPASTCompositeTypeSpecifier) { - node = ((ICPPASTCompositeTypeSpecifier)node).getName(); + node = ((ICPPASTCompositeTypeSpecifier) node).getName(); if (node instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName)node).getNames(); - node = ns[ns.length - 1]; + node = ((ICPPASTQualifiedName) node).getLastName(); } } if (!(node instanceof IASTName)) @@ -256,10 +255,9 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC @Override public void addDeclaration(IASTNode node) { if (node instanceof ICPPASTElaboratedTypeSpecifier) { - node = ((ICPPASTElaboratedTypeSpecifier)node).getName(); + node = ((ICPPASTElaboratedTypeSpecifier) node).getName(); if (node instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName)node).getNames(); - node = ns[ns.length - 1]; + node = ((ICPPASTQualifiedName) node).getLastName(); } } if (!(node instanceof IASTName)) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclaration.java index 79b68c06656..8c54d532670 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclaration.java @@ -31,8 +31,7 @@ public class CPPUsingDeclaration extends PlatformObject implements ICPPUsingDecl public CPPUsingDeclaration(IASTName name, IBinding[] bindings) { if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - name = ns[ns.length - 1]; + name = name.getLastName(); } this.name = name; this.delegates= bindings; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index a32d30b02d9..652399337e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -55,8 +55,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt public CPPVariable(IASTName name) { boolean isDef = name == null ? false : name.isDefinition(); if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); - name = ns[ns.length - 1]; + name = name.getLastName(); } if (isDef) { 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 0af4aabf979..b8981c921cc 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 @@ -79,6 +79,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; +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.ICPPASTEnumerationSpecifier; @@ -96,6 +97,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression.CaptureDefault; 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; @@ -243,7 +246,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return ambiguousQualifiedName(ctx); ICPPASTQualifiedName qname= null; - IASTName name= null; + ICPPASTNameSpecifier nameSpec= null; final int offset= LA(1).getOffset(); int endOffset= offset; if (LT(1) == IToken.tCOLONCOLON) { @@ -272,20 +275,28 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.tCOMPLETION: case IToken.tEOC: IToken nt= consume(); - name = buildName(destructorOffset, nt); + nameSpec = (ICPPASTName) buildName(destructorOffset, nt); break; case IToken.t_operator: - name= operatorId(); + nameSpec= (ICPPASTName) operatorId(); + break; + + case IToken.t_decltype: + // A decltype-specifier must be the first component of a qualified name. + if (qname != null) + throwBacktrack(LA(1)); + + nameSpec = decltypeSpecifier(); break; default: if (!haveName || destructorOffset >= 0 || keywordTemplate) { throwBacktrack(LA(1)); } - name= nodeFactory.newName(CharArrayUtils.EMPTY); + nameSpec= (ICPPASTName) nodeFactory.newName(CharArrayUtils.EMPTY); if (qname != null) { - qname.addName(name); + addNameSpecifier(qname, nameSpec); } break loop; } @@ -293,7 +304,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { haveName= true; // Check for template-id - if (LTcatchEOF(1) == IToken.tLT) { + if (nameSpec instanceof IASTName && LTcatchEOF(1) == IToken.tLT) { + IASTName name = (IASTName) nameSpec; final boolean inBinaryExpression = ctx != CastExprCtx.eNotInBExpr; final int haveArgs = haveTemplateArguments(inBinaryExpression); boolean templateID= true; @@ -308,13 +320,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (haveArgs == -1) throwBacktrack(LA(1)); - name= addTemplateArguments(name, strat); + nameSpec= (ICPPASTName) addTemplateArguments(name, strat); } } - endOffset= calculateEndOffset(name); + endOffset= calculateEndOffset(nameSpec); if (qname != null) { - qname.addName(name); + addNameSpecifier(qname, nameSpec); } if (LTcatchEOF(1) != IToken.tCOLONCOLON) @@ -326,14 +338,25 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { endOffset= consume().getEndOffset(); // :: if (qname == null) { qname= nodeFactory.newQualifiedName(); - qname.addName(name); + addNameSpecifier(qname, nameSpec); } } if (qname != null) { setRange(qname, offset, endOffset); - name= qname; + nameSpec= qname; } - return name; + if (!(nameSpec instanceof IASTName)) { + // decltype-specifier without following :: + throwBacktrack(nameSpec); + } + return (IASTName) nameSpec; + } + + private void addNameSpecifier(ICPPASTQualifiedName qname, ICPPASTNameSpecifier nameSpec) { + if (nameSpec instanceof IASTName) + qname.addName((IASTName) nameSpec); + else + qname.addNameSpecifier(nameSpec); } private IASTName buildName(int destructorOffset, IToken nt) { @@ -393,6 +416,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { } /** + * Parses a decltype-specifier. + */ + private ICPPASTDecltypeSpecifier decltypeSpecifier() throws EndOfFileException, BacktrackException { + int start = consume(IToken.t_decltype).getOffset(); + consume(IToken.tLPAREN); + ICPPASTExpression decltypeExpression = (ICPPASTExpression) expression(); + int end = consume(IToken.tRPAREN).getEndOffset(); + ICPPASTDecltypeSpecifier decltypeSpec = nodeFactory.newDecltypeSpecifier(decltypeExpression); + setRange(decltypeSpec, start, end); + return decltypeSpec; + } + + /** * Makes a fast check whether there could be template arguments. * -1: no, 0: ambiguous, 1: yes */ @@ -2968,6 +3004,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { if (encounteredRawType || encounteredTypename) throwBacktrack(LA(1)); + // A decltype-specifier could be the first element + // in a qualified name, in which case we'll have + // a named-type-specifier. + IToken marked = mark(); + try { + identifier = qualifiedName(); + endOffset = calculateEndOffset(identifier); + encounteredTypename = true; + break; + } catch (BacktrackException e) { + backup(marked); + } + + // Otherwise we have a simple-decl-specifier. simpleType= IASTSimpleDeclSpecifier.t_decltype; consume(IToken.t_decltype); consume(IToken.tLPAREN); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index c59ad4c0ed0..776c548a250 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -809,7 +809,7 @@ public class CPPSemantics { ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) parent.getParent(); IASTName n = compSpec.getName(); if (n instanceof ICPPASTQualifiedName) { - n = ((ICPPASTQualifiedName) n).getLastName(); + n = n.getLastName(); } scope = CPPVisitor.getContainingScope(n); } else { @@ -1321,7 +1321,7 @@ public class CPPSemantics { } if (parent instanceof ICPPASTQualifiedName) { ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent; - if (qname.isFullyQualified() || qname.getNames()[0] != node) + if (qname.isFullyQualified() || qname.getQualifier()[0] != node) return null; } } @@ -1702,7 +1702,7 @@ public class CPPSemantics { ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration; IASTName name = using.getName(); if (name instanceof ICPPASTQualifiedName) { - name = ((ICPPASTQualifiedName) name).getLastName(); + name = name.getLastName(); } ASTInternal.addName(scope, name); } else if (declaration instanceof ICPPASTNamespaceDefinition) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 3806b7a1b41..1a176a0b525 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -60,6 +60,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.ICPPASTExpression; +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.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; @@ -601,8 +602,8 @@ public class CPPTemplates { if (name instanceof ICPPASTQualifiedName) { int idx = templates.length; int i = 0; - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - for (IASTName element : ns) { + ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier(); + for (ICPPASTNameSpecifier element : qualifier) { if (element instanceof ICPPASTTemplateId) { ++i; if (i == idx) { @@ -612,7 +613,7 @@ public class CPPTemplates { } } if (binding == null) - binding = ns[ns.length - 1].resolveBinding(); + binding = name.getLastName().resolveBinding(); } else { binding = name.resolveBinding(); } @@ -1527,9 +1528,9 @@ public class CPPTemplates { // skip one tdecl= getDirectlyEnclosingTemplateDeclaration(tdecl); } - final IASTName[] ns= qname.getNames(); - for (int i = ns.length - 2; tdecl != null && i >= 0; i--) { - final IASTName n = ns[i]; + final ICPPASTNameSpecifier[] qualifier= qname.getQualifier(); + for (int i = qualifier.length - 1; tdecl != null && i >= 0; i--) { + final ICPPASTNameSpecifier n = qualifier[i]; if (n == name) { return tdecl; } @@ -1579,23 +1580,23 @@ public class CPPTemplates { // Count dependent-ids CharArraySet tparnames= collectTemplateParameterNames(outerMostTDecl); int depIDCount= 0; - IASTName owner= null; - final IASTName[] ns= qname.getNames(); - for (int i = 0; i < ns.length - 1; i++) { - IASTName n= ns[i]; + IBinding owner= null; + final ICPPASTNameSpecifier[] qualifier= qname.getQualifier(); + for (int i = 0; i < qualifier.length; i++) { + ICPPASTNameSpecifier n= qualifier[i]; if (n instanceof ICPPASTTemplateId) { if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) { depIDCount++; } } if (depIDCount == 0) { - owner= n; + owner= n.resolveBinding(); } } if (qname.getLastName() instanceof ICPPASTTemplateId || paramTDeclCount > depIDCount // not enough template ids - || ns.length < 2 // ::name + || qualifier.length < 1 // ::name ) { lastIsTemplate= true; depIDCount++; @@ -1606,7 +1607,7 @@ public class CPPTemplates { nestingLevel= 0; if (owner != null) { int consumesTDecl= 0; - IBinding b= owner.resolveBinding(); + IBinding b= owner; if (b instanceof IType) { IType t= SemanticUtil.getNestedType((IType) b, TDEF); if (t instanceof IBinding) @@ -1721,7 +1722,8 @@ public class CPPTemplates { if (names.containsKey(name.getLookupKey())) { IASTNode parent= name.getParent(); if (parent instanceof ICPPASTQualifiedName) { - if (((ICPPASTQualifiedName) parent).getNames()[0] != name) { + ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) parent).getQualifier(); + if (qualifier.length > 0 && qualifier[0] != name) { return PROCESS_CONTINUE; } result[0]= true; @@ -1841,12 +1843,12 @@ public class CPPTemplates { } if (name != null) { if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); + ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier(); IASTDeclaration currDecl = decl; - for (int j = 0; j < ns.length; j++) { - if (ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length) { + for (ICPPASTNameSpecifier segment : qualifier) { + if (segment instanceof ICPPASTTemplateId) { if (currDecl == templateDecl) { - return ns[j]; + return (IASTName) segment; } if (!(currDecl instanceof ICPPASTTemplateDeclaration)) { return null; @@ -1854,6 +1856,9 @@ public class CPPTemplates { currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration(); } } + if (currDecl == templateDecl) { + return name.getLastName(); + } } else { return name; } 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 9fb71d60e3f..82c5b548b47 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 @@ -111,6 +111,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; 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.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; @@ -316,8 +317,8 @@ public class CPPVisitor extends ASTQueries { } private static boolean declaresMemberInClassOrNamespace(ICPPASTQualifiedName qname) { - IASTName[] names= qname.getNames(); - if (names.length < 2) + ICPPASTNameSpecifier[] qualifier= qname.getQualifier(); + if (qualifier.length == 0) return false; IASTNode parent= qname.getParent(); @@ -346,7 +347,7 @@ public class CPPVisitor extends ASTQueries { if (inScope == null) return false; - IBinding pb= names[names.length - 2].resolvePreBinding(); + IBinding pb= qualifier[qualifier.length - 1].resolvePreBinding(); if (pb instanceof IProblemBinding) return false; @@ -451,8 +452,7 @@ public class CPPVisitor extends ASTQueries { IASTName name = elabType.getName(); if (name instanceof ICPPASTQualifiedName) { qualified = true; - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - name = ns[ns.length - 1]; + name = name.getLastName(); } if (parent instanceof IASTSimpleDeclaration) { IASTDeclarator[] dtors = ((IASTSimpleDeclaration) parent).getDeclarators(); @@ -592,11 +592,7 @@ public class CPPVisitor extends ASTQueries { } private static IBinding createBinding(ICPPASTCompositeTypeSpecifier compType) { - IASTName name = compType.getName(); - if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - name = ns[ns.length - 1]; - } + IASTName name = compType.getName().getLastName(); if (name instanceof ICPPASTTemplateId) return CPPTemplates.createBinding((ICPPASTTemplateId) name); @@ -701,10 +697,7 @@ public class CPPVisitor extends ASTQueries { final IASTDeclarator typeRelevantDtor= findTypeRelevantDeclarator(declarator); - IASTName name= declarator.getName(); - if (name instanceof ICPPASTQualifiedName) { - name= ((ICPPASTQualifiedName) name).getLastName(); - } + IASTName name= declarator.getName().getLastName(); // in case the binding was created starting from another name within the declarator. IBinding candidate= name.getBinding(); @@ -938,13 +931,13 @@ public class CPPVisitor extends ASTQueries { if (parent instanceof IASTDeclarator) { if (isConstructorDtor((IASTDeclarator) parent)) { if (name instanceof ICPPASTQualifiedName) { - IASTName[] names = ((ICPPASTQualifiedName) name).getNames(); - if (names.length >= 2) { - IBinding b= names[names.length - 2].resolvePreBinding(); + ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier(); + if (qualifier.length >= 1) { + IBinding b= qualifier[qualifier.length - 1].resolvePreBinding(); if (b instanceof IType) { IType classType= getNestedType((IType) b, TDEF); if (classType instanceof ICPPClassType) { - final char[] dtorName = names[names.length - 1].getLookupKey(); + final char[] dtorName = name.getLastName().getLookupKey(); final char[] className = ((ICPPClassType) classType).getNameCharArray(); return CharArrayUtils.equals(dtorName, className); } @@ -1068,8 +1061,7 @@ public class CPPVisitor extends ASTQueries { IASTDeclarator dtor = (IASTDeclarator) parent; IASTName name = dtor.getName(); if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - return getContainingScope(ns[ns.length - 1]); + return getContainingScope(name.getLastName()); } } else if (parent instanceof ICPPASTConstructorChainInitializer) { // The initializer for the member initializer is resolved in @@ -1107,8 +1099,7 @@ public class CPPVisitor extends ASTQueries { dtor = dtor.getNestedDeclarator(); IASTName name = dtor.getName(); if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - return getContainingScope(ns[ns.length - 1]); + return getContainingScope(name.getLastName()); } } } else if (parent instanceof ICPPASTTemplateId && @@ -1129,12 +1120,7 @@ public class CPPVisitor extends ASTQueries { } } else if (node instanceof ICPPASTBaseSpecifier) { ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) node.getParent(); - IASTName n = compSpec.getName(); - if (n instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) n).getNames(); - n = ns[ns.length - 1]; - } - + IASTName n = compSpec.getName().getLastName(); return getContainingScope(n); } else if (node instanceof IASTEnumerator) { node= node.getParent(); @@ -1200,10 +1186,11 @@ public class CPPVisitor extends ASTQueries { if (parent instanceof ICPPASTQualifiedName) { final ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent; - final IASTName[] names = qname.getNames(); + final ICPPASTNameSpecifier[] segments= qname.getAllSegments(); int i = 0; - for (; i < names.length; i++) { - if (names[i] == name) break; + for (; i < segments.length; i++) { + if (segments[i] == name) + break; } final IASTTranslationUnit tu = parent.getTranslationUnit(); if (i == 0) { @@ -1219,7 +1206,7 @@ public class CPPVisitor extends ASTQueries { } else if (i > 0) { // For template functions we may need to resolve a template parameter // as a parent of an unknown type used as parameter type. - IBinding binding = names[i - 1].resolvePreBinding(); + IBinding binding = segments[i - 1].resolvePreBinding(); // 7.1.3-7 Unwrap typedefs, delete cv-qualifiers. if (binding instanceof ITypedef) { @@ -1249,7 +1236,7 @@ public class CPPVisitor extends ASTQueries { } if (done) { if (scope == null) { - return new CPPScope.CPPScopeProblem(names[i - 1], IProblemBinding.SEMANTIC_BAD_SCOPE); + return new CPPScope.CPPScopeProblem(segments[i - 1], IProblemBinding.SEMANTIC_BAD_SCOPE, null); } return scope; } @@ -1310,11 +1297,7 @@ public class CPPVisitor extends ASTQueries { return fdef.getScope(); IASTFunctionDeclarator fnDeclarator = fdef.getDeclarator(); - IASTName name = findInnermostDeclarator(fnDeclarator).getName(); - if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - name = ns[ns.length - 1]; - } + IASTName name = findInnermostDeclarator(fnDeclarator).getName().getLastName(); return getContainingScope(name); } @@ -1819,11 +1802,7 @@ public class CPPVisitor extends ASTQueries { private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) { IType[] pTypes = createParameterTypes(fnDtor); - IASTName name = fnDtor.getName(); - if (name instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); - name = ns[ns.length - 1]; - } + IASTName name = fnDtor.getName().getLastName(); if (name instanceof ICPPASTConversionName) { returnType = createType(((ICPPASTConversionName) name).getTypeId()); } else { @@ -2281,11 +2260,7 @@ public class CPPVisitor extends ASTQueries { } if (node instanceof IASTFunctionDeclarator) { ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node; - IASTName funcName = findInnermostDeclarator(dtor).getName(); - if (funcName instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) funcName).getNames(); - funcName = ns[ns.length - 1]; - } + IASTName funcName = findInnermostDeclarator(dtor).getName().getLastName(); IScope s = getContainingScope(funcName); while (s instanceof ICPPTemplateScope) { s = s.getParent(); @@ -2521,16 +2496,16 @@ public class CPPVisitor extends ASTQueries { IASTNode node= name.getLastName(); while (node instanceof IASTName) { if (node instanceof ICPPASTQualifiedName) { - IASTName[] qn= ((ICPPASTQualifiedName) node).getNames(); - int i= qn.length; + ICPPASTNameSpecifier[] segments = ((ICPPASTQualifiedName) node).getAllSegments(); + int i = segments.length; while (--i >= 0) { - if (qn[i] == name) { + if (segments[i] == name) { break; } } if (--i < 0) break; - IBinding binding = qn[i].resolveBinding(); + IBinding binding = segments[i].resolveBinding(); if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { binding = ((CPPASTTranslationUnit) name.getTranslationUnit()).mapToAST((ICPPClassType) binding, name); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 6769b5848e0..a33756d8b07 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -54,6 +54,7 @@ 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.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; +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.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -162,11 +163,11 @@ public class LookupData extends ScopeLookupData { } else { nameParent= parent.getParent(); } - final IASTName[] names = qn.getNames(); + final ICPPASTNameSpecifier[] qualifier = qn.getQualifier(); if (qn.isFullyQualified()) { qualified= true; - } else if (names.length > 0) { - if (names[0] != tn) { + } else if (qualifier.length > 0) { + if (qualifier[0] != tn) { qualified= true; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/DeclarationGeneratorImpl.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/DeclarationGeneratorImpl.java index 49d25e0451a..654a08ab043 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/DeclarationGeneratorImpl.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/DeclarationGeneratorImpl.java @@ -39,6 +39,7 @@ import org.eclipse.cdt.core.dom.ast.INodeFactory; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; @@ -289,13 +290,12 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator { ICPPASTQualifiedName newQualifiedName = ((ICPPNodeFactory) factory).newQualifiedName(); - int nbQualifiedNames = fullQualifiedName.getNames().length; - if (nbQualifiedNames > 1) { - for (int i = 0; i < nbQualifiedNames - 1; i++) { - newQualifiedName.addName(fullQualifiedName.getNames()[i].copy(CopyStyle.withLocations)); - } + ICPPASTNameSpecifier[] qualifier = fullQualifiedName.getQualifier(); + int nbQualifiedNames = qualifier.length; + for (int i = 0; i < nbQualifiedNames; i++) { + newQualifiedName.addNameSpecifier(qualifier[i].copy(CopyStyle.withLocations)); } - newQualifiedName.addName(tempId); + newQualifiedName.setLastName(tempId); return factory.newTypedefNameSpecifier(newQualifiedName); } else { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/NameWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/NameWriter.java index a6af2b9e589..f66d337c4c4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/NameWriter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/NameWriter.java @@ -15,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; +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.ICPPASTTemplateId; import org.eclipse.cdt.core.parser.Keywords; @@ -85,9 +86,9 @@ public class NameWriter extends NodeWriter { } private boolean isDependentName(ICPPASTQualifiedName qname, ICPPASTTemplateId tempId) { - IASTName[] names = qname.getNames(); - for (int i = 0; i < names.length; ++i){ - if (names[i] == tempId){ + ICPPASTNameSpecifier[] segments = qname.getAllSegments(); + for (int i = 0; i < segments.length; ++i){ + if (segments[i] == tempId){ return isDependentName(qname, tempId, i); } } @@ -98,10 +99,10 @@ public class NameWriter extends NodeWriter { if (i <= 0){ return false; } - if (qname.getNames()[i - 1] instanceof ICPPASTTemplateId) { + if (qname.getQualifier()[i - 1] instanceof ICPPASTTemplateId) { return true; } - IBinding binding = qname.getNames()[i - 1].resolveBinding(); + IBinding binding = qname.getQualifier()[i - 1].resolveBinding(); if (binding instanceof CPPTemplateTypeParameter) { return true; } @@ -121,12 +122,10 @@ public class NameWriter extends NodeWriter { if (qname.isFullyQualified()) { scribe.print(COLON_COLON); } - IASTName[] nodes = qname.getNames(); - for (int i = 0; i < nodes.length; ++i) { - nodes[i].accept(visitor); - if (i + 1 < nodes.length) { - scribe.print(COLON_COLON); - } + for (ICPPASTNameSpecifier segment : qname.getQualifier()) { + segment.accept(visitor); + scribe.print(COLON_COLON); } + qname.getLastName().accept(visitor); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java index e616d235ac6..79d56e6af7d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/IndexerASTVisitor.java @@ -89,10 +89,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor { } private IASTName getLastInQualified(IASTName name) { - if (name instanceof ICPPASTQualifiedName) { - name= ((ICPPASTQualifiedName) name).getLastName(); - } - return name; + return name.getLastName(); } private void pop(IASTNode node) { |