1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Bug 380751 - Members of decltype types cannot be used

Change-Id: Ie6113d44647a222e063ab2ab27f3dc9d994f98fc
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/15451
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Nathan Ridge 2013-08-14 01:48:56 -04:00 committed by Sergey Prigogin
parent cf3f7a8897
commit e9d295e1a6
53 changed files with 717 additions and 311 deletions

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
/**
@ -83,9 +84,9 @@ public class NamingConventionFunctionChecker extends AbstractIndexAstChecker imp
name = cppAstName.getLastName().toString();
if (name.startsWith("~")) // destructor //$NON-NLS-1$
return null;
IASTName[] names = cppAstName.getNames();
if (names.length >= 2) {
if (names[names.length - 1].toString().equals(names[names.length - 2].toString())) {
ICPPASTNameSpecifier[] qualifier = cppAstName.getQualifier();
if (qualifier.length > 0) {
if (cppAstName.getLastName().toString().equals(qualifier[qualifier.length - 1].toString())) {
// constructor
return null;
}

View file

@ -33,8 +33,9 @@ public class ASTComparer extends Assert {
"getLastName",
// Exponential complexity
"getOperand2", // duplicates getInitOperand2()
"getOperand2", // duplicates getInitOperand2()
"getChildren",
"getAllSegments", // duplicates getQualifier()
// Can be different in copy
"isFrozen",

View file

@ -97,6 +97,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
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.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
@ -340,9 +341,16 @@ public class AST2CPPTests extends AST2TestBase {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
// class A {
// int m;
// };
// A* a;
// int A::*pm;
// int f(){}
// int f(int);
// int x = f(a->*pm);
public void testBug43579() throws Exception {
parseAndCheckBindings("class A { int m; }; \n A * a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a->*pm);");
parseAndCheckBindings("class A { int m; }; \n A * a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a->*pm);");
parseAndCheckBindings();
}
// class A { int m(int); };
@ -555,10 +563,10 @@ public class AST2CPPTests extends AST2TestBase {
ICPPMethod f1 = (ICPPMethod) name_f1.resolveBinding();
ICPPMethod f2 = (ICPPMethod) name_f2.resolveBinding();
IASTName[] names = name_f2.getNames();
assertEquals(names.length, 2);
IASTName qn1 = names[0];
IASTName qn2 = names[1];
ICPPASTNameSpecifier[] qualifier = name_f2.getQualifier();
assertEquals(qualifier.length, 1);
IASTName qn1 = (IASTName) qualifier[0];
IASTName qn2 = name_f2.getLastName();
ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding();
ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding();
@ -603,10 +611,10 @@ public class AST2CPPTests extends AST2TestBase {
ICPPField i1 = (ICPPField) name_i.resolveBinding();
ICPPField i2 = (ICPPField) name_i2.resolveBinding();
IASTName[] names = name_f2.getNames();
assertEquals(names.length, 2);
IASTName qn1 = names[0];
IASTName qn2 = names[1];
ICPPASTNameSpecifier[] qualifier = name_f2.getQualifier();
assertEquals(qualifier.length, 1);
IASTName qn1 = (IASTName) qualifier[0];
IASTName qn2 = name_f2.getLastName();
ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding();
ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding();
@ -645,8 +653,8 @@ public class AST2CPPTests extends AST2TestBase {
IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[2];
ICPPASTQualifiedName name_f2 = (ICPPASTQualifiedName) def.getDeclarator().getName();
IASTName name_B2 = name_f2.getNames()[0];
IASTName name_f3 = name_f2.getNames()[1];
IASTName name_B2 = (IASTName) name_f2.getQualifier()[0];
IASTName name_f3 = name_f2.getLastName();
IASTCompoundStatement compound = (IASTCompoundStatement) def.getBody();
IASTExpressionStatement statement = (IASTExpressionStatement) compound.getStatements()[0];
@ -1729,10 +1737,10 @@ public class AST2CPPTests extends AST2TestBase {
IASTIdExpression id = (IASTIdExpression) e.getInitializerClause();
ICPPASTQualifiedName name = (ICPPASTQualifiedName) id.getName();
assertTrue(name.isFullyQualified());
assertEquals(name.getNames().length, 3);
assertEquals(name.getNames()[0].toString(), "ABC");
assertEquals(name.getNames()[1].toString(), "DEF");
assertEquals(name.getNames()[2].toString(), "ghi");
assertEquals(name.getQualifier().length, 2);
assertEquals(name.getQualifier()[0].toString(), "ABC");
assertEquals(name.getQualifier()[1].toString(), "DEF");
assertEquals(name.getLastName().toString(), "ghi");
}
// namespace Y { void f(float); }
@ -10336,4 +10344,16 @@ public class AST2CPPTests extends AST2TestBase {
public void testGNUSyncBuiltins_bug389578() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
// class Waldo {
// typedef int type;
// };
//
// int main() {
// Waldo w;
// decltype(w)::type i;
// }
public void testDecltypeInNameQualifier_bug380751() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -1825,9 +1825,9 @@ public class AST2TemplateTests extends AST2TestBase {
tu.accept(col);
ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0);
IASTName[] ns = qn.getNames();
assertTrue(ns[1] instanceof ICPPASTTemplateId);
assertEquals(ns[1].toString(), "B<T>");
IASTName lastName = qn.getLastName();
assertTrue(lastName instanceof ICPPASTTemplateId);
assertEquals(lastName.toString(), "B<T>");
}
// template <class T> struct A{
@ -5199,6 +5199,9 @@ public class AST2TemplateTests extends AST2TestBase {
assertEquals("CT<char, char>", names[0].toString());
}
// NOTE: If, after refactoring some AST code, this test hangs, check
// if any methods that were added during the refactoring need
// to be added to ASTComparer.methodsToIgnore.
public void testBug316704() throws Exception {
StringBuilder code= new StringBuilder("typedef if_< bool,");
for (int i = 0; i < 50; i++) {

View file

@ -666,9 +666,9 @@ public class DOMLocationTests extends AST2TestBase {
tu.accept( col );
ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0);
IASTName[] ns = qn.getNames();
assertTrue(ns[1] instanceof ICPPASTTemplateId);
ICPPASTTemplateId templateId= (ICPPASTTemplateId) ns[1];
IASTName lastName = qn.getLastName();
assertTrue(lastName instanceof ICPPASTTemplateId);
ICPPASTTemplateId templateId= (ICPPASTTemplateId) lastName;
IASTName templateIdName= templateId.getTemplateName();
assertEquals("test", templateIdName.getRawSignature()); //$NON-NLS-1$

View file

@ -54,9 +54,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
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.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.ICPPASTPackExpansionExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
@ -666,6 +668,22 @@ public class ASTStringUtil {
private static StringBuilder appendQualifiedNameString(StringBuilder buffer, IASTName name) {
return appendNameString(buffer, name, true);
}
private static StringBuilder appendDecltypeSpecifier(StringBuilder buffer, ICPPASTDecltypeSpecifier decltypeSpec) {
buffer.append(Keywords.DECLTYPE);
buffer.append(Keywords.cpLPAREN);
appendExpressionString(buffer, decltypeSpec.getDecltypeExpression());
buffer.append(Keywords.cpRPAREN);
return buffer;
}
private static StringBuilder appendQualifiedNameString(StringBuilder buffer, ICPPASTNameSpecifier nameSpec) {
if (nameSpec instanceof IASTName)
appendQualifiedNameString(buffer, (IASTName) nameSpec);
else if (nameSpec instanceof ICPPASTDecltypeSpecifier)
appendDecltypeSpecifier(buffer, (ICPPASTDecltypeSpecifier) nameSpec);
return buffer;
}
private static StringBuilder appendSimpleNameString(StringBuilder buffer, IASTName name) {
return appendNameString(buffer, name, false);
@ -675,12 +693,12 @@ public class ASTStringUtil {
if (name instanceof ICPPASTQualifiedName) {
final ICPPASTQualifiedName qualifiedName= (ICPPASTQualifiedName)name;
if (qualified) {
final IASTName[] names= qualifiedName.getNames();
for (int i = 0; i < names.length; i++) {
final ICPPASTNameSpecifier[] segments= qualifiedName.getAllSegments();
for (int i = 0; i < segments.length; i++) {
if (i > 0) {
buffer.append(Keywords.cpCOLONCOLON);
}
appendQualifiedNameString(buffer, names[i]);
appendQualifiedNameString(buffer, segments[i]);
}
} else {
buffer.append(qualifiedName.getLastName());

View file

@ -55,6 +55,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.ICPPASTFunctionDeclarator;
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.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -872,10 +873,10 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// try to avoid expensive resolution of scope and binding
boolean isMethod= parent instanceof IStructure;
if (!isMethod && name instanceof ICPPASTQualifiedName) {
final IASTName[] names= ((ICPPASTQualifiedName)name).getNames();
if (isTemplate) {
for (IASTName name2 : names) {
if (name2 instanceof ICPPASTTemplateId) {
final ICPPASTNameSpecifier[] segments= ((ICPPASTQualifiedName)name).getAllSegments();
for (ICPPASTNameSpecifier segment : segments) {
if (segment instanceof ICPPASTTemplateId) {
isMethod= true;
break;
}
@ -942,8 +943,13 @@ public class CModelBuilder2 implements IContributedModelBuilder {
isConstructor= parent.getElementName().equals(simpleName);
} else if (name instanceof ICPPASTQualifiedName) {
final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name;
final IASTName[] names= quName.getNames();
isConstructor= names.length >= 2 && simpleName.equals(ASTStringUtil.getSimpleName(names[names.length-2]));
final ICPPASTNameSpecifier[] qualifier= quName.getQualifier();
if (qualifier.length == 0)
isConstructor = false;
else {
ICPPASTNameSpecifier nameSpec= qualifier[qualifier.length - 1];
isConstructor= nameSpec instanceof IASTName && simpleName.equals(ASTStringUtil.getSimpleName((IASTName) nameSpec));
}
} else {
isConstructor= false;
}
@ -955,9 +961,13 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// strip namespace qualifier if parent is same namespace
if (name instanceof ICPPASTQualifiedName && parent instanceof INamespace) {
final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name;
final IASTName[] names= quName.getNames();
if (names.length >= 2 && parent.getElementName().equals(ASTStringUtil.getSimpleName(names[names.length-2]))) {
functionName= simpleName;
final ICPPASTNameSpecifier[] qualifier= quName.getQualifier();
if (qualifier.length >= 1) {
ICPPASTNameSpecifier nameSpec = qualifier[qualifier.length - 1];
if (nameSpec instanceof IASTName
&& parent.getElementName().equals(ASTStringUtil.getSimpleName((IASTName) nameSpec))) {
functionName= simpleName;
}
}
}
if (isTemplate) {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,14 +33,55 @@ 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.
*/

View file

@ -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.
*/

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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;
@ -266,6 +268,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
return new CPPASTDeclarator(name);
}
@Override
public ICPPASTDecltypeSpecifier newDecltypeSpecifier(ICPPASTExpression decltypeExpression) {
return new CPPASTDecltypeSpecifier(decltypeExpression);
}
@Override
public IASTDefaultStatement newDefaultStatement() {
return new CPPASTDefaultStatement();

View file

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

View file

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

View file

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

View file

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

View file

@ -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) {
@ -392,6 +415,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return result;
}
/**
* 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);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -118,6 +118,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement;
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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
@ -3422,16 +3423,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (node.isFullyQualified()) {
scribe.printNextToken(Token.tCOLONCOLON);
}
IASTName[] names= node.getNames();
for (int i = 0; i < names.length - 1; i++) {
names[i].accept(this);
for (ICPPASTNameSpecifier nameSpec : node.getQualifier()) {
nameSpec.accept(this);
scribe.printNextToken(Token.tCOLONCOLON);
}
if (peekNextToken() == Token.tCOMPL) {
// destructor
scribe.printNextToken(Token.tCOMPL, false);
}
names[names.length - 1].accept(this);
node.getLastName().accept(this);
return PROCESS_SKIP;
}

View file

@ -45,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
@ -356,9 +357,9 @@ public class SemanticHighlightings {
if (node instanceof ICPPASTFunctionDeclarator) {
if (name instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qName= (ICPPASTQualifiedName) name;
IASTName[] names= qName.getNames();
if (names.length > 1) {
if (names[names.length - 2].getBinding() instanceof ICPPClassType) {
ICPPASTNameSpecifier[] qualifier= qName.getQualifier();
if (qualifier.length > 0) {
if (qualifier[qualifier.length - 1].resolveBinding() instanceof ICPPClassType) {
return true;
}
}

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
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.ICPPClassType;
@ -177,7 +178,7 @@ public class MethodContext {
}
private static ICPPClassType getClassBinding(ICPPASTQualifiedName qname) {
IASTName classname = qname.getNames()[qname.getNames().length - 2];
ICPPASTNameSpecifier classname = qname.getQualifier()[qname.getQualifier().length - 1];
ICPPClassType bind = (ICPPClassType)classname.resolveBinding();
return bind;
}

View file

@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
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.ICPPASTFunctionDeclarator;
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.ICPPASTTemplateDeclaration;
@ -594,8 +595,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
if (context.getType() == ContextType.METHOD) {
if (context.getMethodQName() != null) {
for (int i = 0; i < context.getMethodQName().getNames().length - 1; i++) {
qname.addName(new CPPASTName(context.getMethodQName().getNames()[i].toCharArray()));
for (ICPPASTNameSpecifier segment : context.getMethodQName().getQualifier()) {
qname.addNameSpecifier(segment.copy());
}
}
}

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
@ -116,8 +117,6 @@ public class AccessorDescriptor implements Comparable<AccessorDescriptor> {
}
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node;
CPPASTQualifiedName qname = new CPPASTQualifiedName();
qname.addName(comp.getName().copy(CopyStyle.withLocations));
return qname;
return new CPPASTQualifiedName((ICPPASTName) comp.getName().copy(CopyStyle.withLocations));
}
}

View file

@ -80,6 +80,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
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.ICPPASTDeleteExpression;
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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -1114,9 +1115,9 @@ public class BindingClassifier {
// elsewhere).
if (name instanceof ICPPASTQualifiedName) {
// All qualifying names must be defined.
IASTName[] names = ((ICPPASTQualifiedName) name).getNames();
for (int i = 0; i < names.length - 1; i++) {
defineBinding(names[i].resolveBinding());
ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier();
for (ICPPASTNameSpecifier nameSpec : qualifier) {
defineBinding(nameSpec.resolveBinding());
}
}

View file

@ -55,6 +55,8 @@ import org.eclipse.cdt.core.dom.ast.IEnumerator;
import org.eclipse.cdt.core.dom.ast.IFunction;
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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
@ -476,11 +478,14 @@ public class IncludeCreator {
}
private boolean match(IASTName name, ArrayList<String> usingChain, boolean excludeLast) {
IASTName[] names;
ICPPASTNameSpecifier[] names;
if (name instanceof ICPPASTQualifiedName) {
names = ((ICPPASTQualifiedName) name).getNames();
// OK to use getNames() here. 'name' comes from a namespace-scope
// using-declaration or using-directive, which cannot contain
// decltype-specifiers.
names = ((ICPPASTQualifiedName) name).getAllSegments();
} else {
names = new IASTName[] { name };
names = new ICPPASTNameSpecifier[] { (ICPPASTName) name };
}
if (names.length != usingChain.size() - (excludeLast ? 1 : 0)) {
return false;

View file

@ -80,6 +80,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICFunctionPrototypeScope;
import org.eclipse.cdt.core.dom.ast.c.ICFunctionScope;
import org.eclipse.cdt.core.dom.ast.c.ICScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
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.ICPPASTTranslationUnit;
@ -173,9 +174,8 @@ public class ASTManager implements IDisposable {
public static IASTName getSimpleName(IASTName name) {
if (name instanceof ICPPASTQualifiedName) {
IASTName names[]= ((ICPPASTQualifiedName) name).getNames();
if (names.length > 0) {
name= names[names.length - 1];
if (name.getLastName() != null) {
name= name.getLastName();
}
}
return name;
@ -843,10 +843,7 @@ public class ASTManager implements IDisposable {
final int length = fArgument.getLength();
IASTName name= nodeSelector.findEnclosingName(offset, length);
if (name != null) {
if (name instanceof ICPPASTQualifiedName) {
IASTName[] na= ((ICPPASTQualifiedName) name).getNames();
name= na[na.length - 1];
}
name= name.getLastName();
} else {
IASTNode node= nodeSelector.findEnclosingNode(offset, length);
if (node instanceof IASTPreprocessorMacroDefinition ||
@ -1192,8 +1189,8 @@ public class ASTManager implements IDisposable {
boolean problemInQualifier= false;
IASTNode parent= name.getParent();
if (parent instanceof ICPPASTQualifiedName) {
IASTName[] names= ((ICPPASTQualifiedName) parent).getNames();
for (IASTName n : names) {
ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) parent).getQualifier();
for (ICPPASTNameSpecifier n : qualifier) {
if (n == name)
break;
final IBinding b = n.resolveBinding();

View file

@ -15,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
/**
@ -41,19 +42,19 @@ abstract public class ASTNameVisitor extends ASTVisitor {
final public int visit(IASTName name) {
if (name instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qn= (ICPPASTQualifiedName) name;
IASTName[] names= qn.getNames();
ICPPASTNameSpecifier[] segments= qn.getAllSegments();
boolean visited= false;
for (int i = 0; i < names.length; i++) {
if (checkLocation(names[i])) {
if (visitName(names[i]) == PROCESS_ABORT) {
for (int i = 0; i < segments.length; i++) {
if (segments[i] instanceof IASTName && checkLocation(segments[i])) {
if (visitName((IASTName) segments[i]) == PROCESS_ABORT) {
return PROCESS_ABORT;
}
visited= true;
}
}
if (!visited && names.length>0) {
if (!visited) {
if (checkLocation(name)) {
return visitName(names[names.length-1]);
return visitName(name.getLastName());
}
}
}

View file

@ -18,15 +18,14 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
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.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.ui.refactoring.Container;
@ -52,12 +51,9 @@ public class InsertionPointFinder {
String decl_name = decl.getName().toString();
for(ICPPASTFunctionDefinition def: alldefinitionsoutside) {
String def_name = null;
if (def.getDeclarator().getName() instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) def.getDeclarator().getName();
def_name = qname.getNames()[1].toString();
} else if (def.getDeclarator().getName() instanceof CPPASTName) {
def_name = def.getDeclarator().getName().toString();
}
IASTName name = def.getDeclarator().getName();
if (name != null)
def_name = name.getLastName().toString();
if (decl_name.equals(def_name)) {
if (def.getParent() != null && def.getParent() instanceof ICPPASTTemplateDeclaration) {

View file

@ -45,6 +45,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
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.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
@ -327,16 +329,18 @@ public class ToggleFromInHeaderToImplementationStrategy implements IToggleRefact
(ICPPASTQualifiedName) new_definition.getDeclarator().getName();
ICPPASTQualifiedName qname_new = new CPPASTQualifiedName();
boolean start = false;
for(IASTName partname: qname.getNames()) {
for(ICPPASTNameSpecifier partname: qname.getQualifier()) {
if (partname.toString().equals(ns.getName().toString())) {
start = true;
continue;
}
if (start)
qname_new.addName(partname);
qname_new.addNameSpecifier(partname);
}
if (start)
if (start) {
qname_new.setLastName((ICPPASTName) qname.getLastName());
new_definition.getDeclarator().setName(qname_new);
}
}
}
}

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
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.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -120,7 +121,7 @@ public class ASTHelper {
public static ArrayList<ICPPASTNamespaceDefinition> getNamespaces(ICPPASTQualifiedName qualifiedName) {
ArrayList<ICPPASTNamespaceDefinition> namespaces = new ArrayList<ICPPASTNamespaceDefinition>();
for (IASTName aktQualifiedPartName : qualifiedName.getNames()) {
for (ICPPASTNameSpecifier aktQualifiedPartName : qualifiedName.getAllSegments()) {
IBinding binding = aktQualifiedPartName.resolveBinding();
for (IASTName aktResolvedName : qualifiedName.getTranslationUnit().getDefinitionsInAST(binding)) {
if (aktResolvedName.getParent() instanceof ICPPASTNamespaceDefinition) {

View file

@ -23,6 +23,8 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
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.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.Keywords;
@ -69,22 +71,22 @@ public class NameHelper {
public static ICPPASTQualifiedName createQualifiedNameFor(IASTName declaratorName,
ITranslationUnit declarationTu, int selectionOffset, ITranslationUnit insertFileTu,
int insertLocation, CRefactoringContext astCache) throws CoreException {
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
ICPPASTQualifiedName qname = new CPPASTQualifiedName(
(ICPPASTName) declaratorName.copy(CopyStyle.withLocations));
IASTName[] declarationNames = NamespaceHelper.getSurroundingNamespace(declarationTu,
selectionOffset, astCache).getNames();
IASTName[] implementationNames = NamespaceHelper.getSurroundingNamespace(insertFileTu,
insertLocation, astCache).getNames();
ICPPASTNameSpecifier[] declarationNames = NamespaceHelper.getSurroundingNamespace(declarationTu,
selectionOffset, astCache).getAllSegments();
ICPPASTNameSpecifier[] implementationNames = NamespaceHelper.getSurroundingNamespace(insertFileTu,
insertLocation, astCache).getAllSegments();
for (int i = 0; i < declarationNames.length; i++) {
if (i >= implementationNames.length) {
qname.addName(declarationNames[i]);
qname.addNameSpecifier(declarationNames[i]);
} else if (!Arrays.equals(declarationNames[i].toCharArray(), implementationNames[i].toCharArray())) {
qname.addName(declarationNames[i]);
qname.addNameSpecifier(declarationNames[i]);
}
}
qname.addName(declaratorName.copy(CopyStyle.withLocations));
return qname;
}

View file

@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
@ -1334,8 +1335,9 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
ICPPASTQualifiedName newQualifiedName = nodeFactory.newQualifiedName();
newQualifiedName.addName(name);
for(IASTName n : qualifiedName.getNames())
newQualifiedName.addName(n);
for(ICPPASTNameSpecifier n : qualifiedName.getQualifier())
newQualifiedName.addNameSpecifier(n);
newQualifiedName.addName(qualifiedName.getLastName());
ParserUtil.setOffsetAndLength(newQualifiedName, offset(name), endOffset(qualifiedName.getLastName()) - offset(name));