1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 09:15:38 +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.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
/** /**
@ -83,9 +84,9 @@ public class NamingConventionFunctionChecker extends AbstractIndexAstChecker imp
name = cppAstName.getLastName().toString(); name = cppAstName.getLastName().toString();
if (name.startsWith("~")) // destructor //$NON-NLS-1$ if (name.startsWith("~")) // destructor //$NON-NLS-1$
return null; return null;
IASTName[] names = cppAstName.getNames(); ICPPASTNameSpecifier[] qualifier = cppAstName.getQualifier();
if (names.length >= 2) { if (qualifier.length > 0) {
if (names[names.length - 1].toString().equals(names[names.length - 2].toString())) { if (cppAstName.getLastName().toString().equals(qualifier[qualifier.length - 1].toString())) {
// constructor // constructor
return null; return null;
} }

View file

@ -35,6 +35,7 @@ public class ASTComparer extends Assert {
// Exponential complexity // Exponential complexity
"getOperand2", // duplicates getInitOperand2() "getOperand2", // duplicates getInitOperand2()
"getChildren", "getChildren",
"getAllSegments", // duplicates getQualifier()
// Can be different in copy // Can be different in copy
"isFrozen", "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.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; 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.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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
@ -340,9 +341,16 @@ public class AST2CPPTests extends AST2TestBase {
parseAndCheckBindings(getAboveComment(), CPP, true); 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 { 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();
parseAndCheckBindings("class A { int m; }; \n A * a; int A::*pm; \n int f(){} \n int f(int); \n int x = f(a->*pm);");
} }
// class A { int m(int); }; // class A { int m(int); };
@ -555,10 +563,10 @@ public class AST2CPPTests extends AST2TestBase {
ICPPMethod f1 = (ICPPMethod) name_f1.resolveBinding(); ICPPMethod f1 = (ICPPMethod) name_f1.resolveBinding();
ICPPMethod f2 = (ICPPMethod) name_f2.resolveBinding(); ICPPMethod f2 = (ICPPMethod) name_f2.resolveBinding();
IASTName[] names = name_f2.getNames(); ICPPASTNameSpecifier[] qualifier = name_f2.getQualifier();
assertEquals(names.length, 2); assertEquals(qualifier.length, 1);
IASTName qn1 = names[0]; IASTName qn1 = (IASTName) qualifier[0];
IASTName qn2 = names[1]; IASTName qn2 = name_f2.getLastName();
ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding(); ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding();
ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding(); ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding();
@ -603,10 +611,10 @@ public class AST2CPPTests extends AST2TestBase {
ICPPField i1 = (ICPPField) name_i.resolveBinding(); ICPPField i1 = (ICPPField) name_i.resolveBinding();
ICPPField i2 = (ICPPField) name_i2.resolveBinding(); ICPPField i2 = (ICPPField) name_i2.resolveBinding();
IASTName[] names = name_f2.getNames(); ICPPASTNameSpecifier[] qualifier = name_f2.getQualifier();
assertEquals(names.length, 2); assertEquals(qualifier.length, 1);
IASTName qn1 = names[0]; IASTName qn1 = (IASTName) qualifier[0];
IASTName qn2 = names[1]; IASTName qn2 = name_f2.getLastName();
ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding(); ICPPClassType A2 = (ICPPClassType) qn1.resolveBinding();
ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding(); ICPPMethod f3 = (ICPPMethod) qn2.resolveBinding();
@ -645,8 +653,8 @@ public class AST2CPPTests extends AST2TestBase {
IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[2]; IASTFunctionDefinition def = (IASTFunctionDefinition) tu.getDeclarations()[2];
ICPPASTQualifiedName name_f2 = (ICPPASTQualifiedName) def.getDeclarator().getName(); ICPPASTQualifiedName name_f2 = (ICPPASTQualifiedName) def.getDeclarator().getName();
IASTName name_B2 = name_f2.getNames()[0]; IASTName name_B2 = (IASTName) name_f2.getQualifier()[0];
IASTName name_f3 = name_f2.getNames()[1]; IASTName name_f3 = name_f2.getLastName();
IASTCompoundStatement compound = (IASTCompoundStatement) def.getBody(); IASTCompoundStatement compound = (IASTCompoundStatement) def.getBody();
IASTExpressionStatement statement = (IASTExpressionStatement) compound.getStatements()[0]; IASTExpressionStatement statement = (IASTExpressionStatement) compound.getStatements()[0];
@ -1729,10 +1737,10 @@ public class AST2CPPTests extends AST2TestBase {
IASTIdExpression id = (IASTIdExpression) e.getInitializerClause(); IASTIdExpression id = (IASTIdExpression) e.getInitializerClause();
ICPPASTQualifiedName name = (ICPPASTQualifiedName) id.getName(); ICPPASTQualifiedName name = (ICPPASTQualifiedName) id.getName();
assertTrue(name.isFullyQualified()); assertTrue(name.isFullyQualified());
assertEquals(name.getNames().length, 3); assertEquals(name.getQualifier().length, 2);
assertEquals(name.getNames()[0].toString(), "ABC"); assertEquals(name.getQualifier()[0].toString(), "ABC");
assertEquals(name.getNames()[1].toString(), "DEF"); assertEquals(name.getQualifier()[1].toString(), "DEF");
assertEquals(name.getNames()[2].toString(), "ghi"); assertEquals(name.getLastName().toString(), "ghi");
} }
// namespace Y { void f(float); } // namespace Y { void f(float); }
@ -10336,4 +10344,16 @@ public class AST2CPPTests extends AST2TestBase {
public void testGNUSyncBuiltins_bug389578() throws Exception { public void testGNUSyncBuiltins_bug389578() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true); 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); tu.accept(col);
ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0); ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0);
IASTName[] ns = qn.getNames(); IASTName lastName = qn.getLastName();
assertTrue(ns[1] instanceof ICPPASTTemplateId); assertTrue(lastName instanceof ICPPASTTemplateId);
assertEquals(ns[1].toString(), "B<T>"); assertEquals(lastName.toString(), "B<T>");
} }
// template <class T> struct A{ // template <class T> struct A{
@ -5199,6 +5199,9 @@ public class AST2TemplateTests extends AST2TestBase {
assertEquals("CT<char, char>", names[0].toString()); 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 { public void testBug316704() throws Exception {
StringBuilder code= new StringBuilder("typedef if_< bool,"); StringBuilder code= new StringBuilder("typedef if_< bool,");
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {

View file

@ -666,9 +666,9 @@ public class DOMLocationTests extends AST2TestBase {
tu.accept( col ); tu.accept( col );
ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0); ICPPASTQualifiedName qn = (ICPPASTQualifiedName) col.getName(0);
IASTName[] ns = qn.getNames(); IASTName lastName = qn.getLastName();
assertTrue(ns[1] instanceof ICPPASTTemplateId); assertTrue(lastName instanceof ICPPASTTemplateId);
ICPPASTTemplateId templateId= (ICPPASTTemplateId) ns[1]; ICPPASTTemplateId templateId= (ICPPASTTemplateId) lastName;
IASTName templateIdName= templateId.getTemplateName(); IASTName templateIdName= templateId.getTemplateName();
assertEquals("test", templateIdName.getRawSignature()); //$NON-NLS-1$ 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.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; 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.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.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; 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.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.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
@ -667,6 +669,22 @@ public class ASTStringUtil {
return appendNameString(buffer, name, true); 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) { private static StringBuilder appendSimpleNameString(StringBuilder buffer, IASTName name) {
return appendNameString(buffer, name, false); return appendNameString(buffer, name, false);
} }
@ -675,12 +693,12 @@ public class ASTStringUtil {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
final ICPPASTQualifiedName qualifiedName= (ICPPASTQualifiedName)name; final ICPPASTQualifiedName qualifiedName= (ICPPASTQualifiedName)name;
if (qualified) { if (qualified) {
final IASTName[] names= qualifiedName.getNames(); final ICPPASTNameSpecifier[] segments= qualifiedName.getAllSegments();
for (int i = 0; i < names.length; i++) { for (int i = 0; i < segments.length; i++) {
if (i > 0) { if (i > 0) {
buffer.append(Keywords.cpCOLONCOLON); buffer.append(Keywords.cpCOLONCOLON);
} }
appendQualifiedNameString(buffer, names[i]); appendQualifiedNameString(buffer, segments[i]);
} }
} else { } else {
buffer.append(qualifiedName.getLastName()); 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.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; 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.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.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; 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.ICPPASTQualifiedName;
@ -872,10 +873,10 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// try to avoid expensive resolution of scope and binding // try to avoid expensive resolution of scope and binding
boolean isMethod= parent instanceof IStructure; boolean isMethod= parent instanceof IStructure;
if (!isMethod && name instanceof ICPPASTQualifiedName) { if (!isMethod && name instanceof ICPPASTQualifiedName) {
final IASTName[] names= ((ICPPASTQualifiedName)name).getNames();
if (isTemplate) { if (isTemplate) {
for (IASTName name2 : names) { final ICPPASTNameSpecifier[] segments= ((ICPPASTQualifiedName)name).getAllSegments();
if (name2 instanceof ICPPASTTemplateId) { for (ICPPASTNameSpecifier segment : segments) {
if (segment instanceof ICPPASTTemplateId) {
isMethod= true; isMethod= true;
break; break;
} }
@ -942,8 +943,13 @@ public class CModelBuilder2 implements IContributedModelBuilder {
isConstructor= parent.getElementName().equals(simpleName); isConstructor= parent.getElementName().equals(simpleName);
} else if (name instanceof ICPPASTQualifiedName) { } else if (name instanceof ICPPASTQualifiedName) {
final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name; final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name;
final IASTName[] names= quName.getNames(); final ICPPASTNameSpecifier[] qualifier= quName.getQualifier();
isConstructor= names.length >= 2 && simpleName.equals(ASTStringUtil.getSimpleName(names[names.length-2])); if (qualifier.length == 0)
isConstructor = false;
else {
ICPPASTNameSpecifier nameSpec= qualifier[qualifier.length - 1];
isConstructor= nameSpec instanceof IASTName && simpleName.equals(ASTStringUtil.getSimpleName((IASTName) nameSpec));
}
} else { } else {
isConstructor= false; isConstructor= false;
} }
@ -955,11 +961,15 @@ public class CModelBuilder2 implements IContributedModelBuilder {
// strip namespace qualifier if parent is same namespace // strip namespace qualifier if parent is same namespace
if (name instanceof ICPPASTQualifiedName && parent instanceof INamespace) { if (name instanceof ICPPASTQualifiedName && parent instanceof INamespace) {
final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name; final ICPPASTQualifiedName quName= (ICPPASTQualifiedName)name;
final IASTName[] names= quName.getNames(); final ICPPASTNameSpecifier[] qualifier= quName.getQualifier();
if (names.length >= 2 && parent.getElementName().equals(ASTStringUtil.getSimpleName(names[names.length-2]))) { if (qualifier.length >= 1) {
ICPPASTNameSpecifier nameSpec = qualifier[qualifier.length - 1];
if (nameSpec instanceof IASTName
&& parent.getElementName().equals(ASTStringUtil.getSimpleName((IASTName) nameSpec))) {
functionName= simpleName; functionName= simpleName;
} }
} }
}
if (isTemplate) { if (isTemplate) {
// template function // template function
element= new FunctionTemplate(parent, functionName); element= new FunctionTemplate(parent, functionName);

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; 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. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented 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( public static final ASTNodeProperty TYPE_ID=new ASTNodeProperty(
"IASTArrayDeclarator.TYPE_ID - IASTTypeId for ICPPASTConversionName"); //$NON-NLS-1$ "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; 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. * This interface represents a C++ overloaded operator member function name.
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented 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 * @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. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented 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( 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. * Adds a name segment.
@ -34,13 +34,54 @@ public interface ICPPASTQualifiedName extends IASTName, IASTNameOwner {
*/ */
public void addName(IASTName name); 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. * 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(); 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. * 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. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented 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. * TEMPLATE_NAME is the IASTName.
*/ */

View file

@ -110,6 +110,11 @@ public interface ICPPNodeFactory extends INodeFactory {
@Override @Override
public ICPPASTDeclarator newDeclarator(IASTName name); public ICPPASTDeclarator newDeclarator(IASTName name);
/**
* @since 5.6
*/
public ICPPASTDecltypeSpecifier newDecltypeSpecifier(ICPPASTExpression decltypeExpression);
public ICPPASTDeleteExpression newDeleteExpression(IASTExpression operand); public ICPPASTDeleteExpression newDeleteExpression(IASTExpression operand);
@Override @Override

View file

@ -247,10 +247,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
} else { } else {
CPPASTImplicitName ctorName = new CPPASTImplicitName(ctor.getNameCharArray(), this); CPPASTImplicitName ctorName = new CPPASTImplicitName(ctor.getNameCharArray(), this);
ctorName.setBinding(ctor); ctorName.setBinding(ctor);
IASTName id = name; IASTName id = name.getLastName();
if (id instanceof ICPPASTQualifiedName) {
id = ((ICPPASTQualifiedName) id).getLastName();
}
ctorName.setOffsetAndLength((ASTNode) id); ctorName.setOffsetAndLength((ASTNode) id);
implicitNames = new IASTImplicitName[] { ctorName }; implicitNames = new IASTImplicitName[] { ctorName };
} }

View file

@ -313,7 +313,7 @@ public class CPPASTDeclarator extends ASTNode implements ICPPASTDeclarator, IAST
ctorName.setBinding(ctor); ctorName.setBinding(ctor);
IASTName id = name; IASTName id = name;
if (id instanceof ICPPASTQualifiedName) { if (id instanceof ICPPASTQualifiedName) {
id = ((ICPPASTQualifiedName) id).getLastName(); id = id.getLastName();
} }
ctorName.setOffsetAndLength((ASTNode) id); ctorName.setOffsetAndLength((ASTNode) id);
implicitNames = new IASTImplicitName[] { ctorName }; 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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; 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.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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
@ -268,13 +269,14 @@ public class CPPASTFieldReference extends ASTNode
ICPPTemplateArgument[] args= null; ICPPTemplateArgument[] args= null;
IASTName n= name; IASTName n= name;
if (n instanceof ICPPASTQualifiedName) { if (n instanceof ICPPASTQualifiedName) {
IASTName[] ns= ((ICPPASTQualifiedName) n).getNames(); ICPPASTQualifiedName qn= (ICPPASTQualifiedName) n;
if (ns.length < 2) ICPPASTNameSpecifier[] ns= qn.getQualifier();
if (ns.length < 1)
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
qualifier= ns[ns.length - 2].resolveBinding(); qualifier= ns[ns.length - 1].resolveBinding();
if (qualifier instanceof IProblemBinding) if (qualifier instanceof IProblemBinding)
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
n= ns[ns.length - 1]; n= qn.getLastName();
} }
if (n instanceof ICPPASTTemplateId) { if (n instanceof ICPPASTTemplateId) {
try { 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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; 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.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; 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 * Common base class for all sorts of c++ names: unqualified, qualified, operator and conversion
* names plus template-ids * 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$ 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; ICPPASTQualifiedName qn= (ICPPASTQualifiedName) parent;
if (qn.isFullyQualified()) if (qn.isFullyQualified())
return true; return true;
IASTName[] qns = qn.getNames(); ICPPASTNameSpecifier[] qualifier = qn.getQualifier();
if (qns.length > 0 && qns[0] == this) if (qualifier.length > 0 && qualifier[0] == this)
return false; return false;
return true; 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 * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,6 +10,7 @@
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
* Nathan Ridge
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IScope;
import org.eclipse.cdt.core.dom.ast.IType; 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.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.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.ICPPASTTemplateId;
@ -55,14 +58,23 @@ import org.eclipse.core.runtime.Assert;
*/ */
public class CPPASTQualifiedName extends CPPASTNameBase public class CPPASTQualifiedName extends CPPASTNameBase
implements ICPPASTQualifiedName, ICPPASTCompletionContext { implements ICPPASTQualifiedName, ICPPASTCompletionContext {
private IASTName[] names; private ICPPASTNameSpecifier[] fQualifier;
private int namesPos= -1; private int fQualifierPos = -1;
private boolean isFullyQualified; private ICPPASTName fLastName;
private char[] signature; private boolean fIsFullyQualified;
private char[] fSignature;
/**
* @deprecated Prefer CPPASTQualifierName(ICPPASTName) instead.
*/
@Deprecated
public CPPASTQualifiedName() { public CPPASTQualifiedName() {
} }
public CPPASTQualifiedName(ICPPASTName lastName) {
setLastName(lastName);
}
@Override @Override
public CPPASTQualifiedName copy() { public CPPASTQualifiedName copy() {
return copy(CopyStyle.withoutLocations); return copy(CopyStyle.withoutLocations);
@ -71,10 +83,12 @@ public class CPPASTQualifiedName extends CPPASTNameBase
@Override @Override
public CPPASTQualifiedName copy(CopyStyle style) { public CPPASTQualifiedName copy(CopyStyle style) {
CPPASTQualifiedName copy = new CPPASTQualifiedName(); CPPASTQualifiedName copy = new CPPASTQualifiedName();
for (IASTName name : getNames()) { if (fLastName != null)
copy.addName(name == null ? null : name.copy(style)); 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); copy.setOffsetAndLength(this);
if (style == CopyStyle.withLocations) { if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this); copy.setCopyLocation(this);
@ -113,69 +127,116 @@ public class CPPASTQualifiedName extends CPPASTNameBase
@Override @Override
public void addName(IASTName name) { public void addName(IASTName name) {
if (fLastName != null)
addNameSpecifier(fLastName);
setLastName((ICPPASTName) name);
}
@Override
public void setLastName(ICPPASTName lastName) {
assertNotFrozen(); assertNotFrozen();
assert !(name instanceof ICPPASTQualifiedName); assert !(lastName instanceof ICPPASTQualifiedName);
if (name != null) { fLastName = lastName;
names = ArrayUtil.appendAt(IASTName.class, names, ++namesPos, name); fLastName.setParent(this);
name.setParent(this); fLastName.setPropertyInParent(SEGMENT_NAME);
name.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 @Override
public IASTName[] getNames() { public ICPPASTNameSpecifier[] getQualifier() {
if (namesPos < 0) if (fQualifierPos < 0)
return IASTName.EMPTY_NAME_ARRAY; return ICPPASTNameSpecifier.EMPTY_NAME_SPECIFIER_ARRAY;
names = ArrayUtil.trimAt(IASTName.class, names, namesPos); fQualifier = ArrayUtil.trimAt(ICPPASTNameSpecifier.class, fQualifier, fQualifierPos);
return names; 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() {
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 @Override
public IASTName getLastName() { public IASTName getLastName() {
if (namesPos < 0) return fLastName;
return null;
return names[namesPos];
} }
@Override @Override
public char[] getSimpleID() { public char[] getSimpleID() {
return names[namesPos].getSimpleID(); return fLastName.getSimpleID();
} }
@Override @Override
public char[] getLookupKey() { public char[] getLookupKey() {
return names[namesPos].getLookupKey(); return fLastName.getLookupKey();
} }
@Override @Override
public char[] toCharArray() { public char[] toCharArray() {
if (signature == null) { if (fSignature == null) {
StringBuilder buf= new StringBuilder(); StringBuilder buf= new StringBuilder();
for (int i = 0; i <= namesPos; i++) { for (int i = 0; i <= fQualifierPos; i++) {
if (i > 0 || isFullyQualified) { if (i > 0 || fIsFullyQualified) {
buf.append(Keywords.cpCOLONCOLON); 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(); final int len= buf.length();
signature= new char[len]; fSignature= new char[len];
buf.getChars(0, len, signature, 0); buf.getChars(0, len, fSignature, 0);
} }
return signature; return fSignature;
} }
@Override @Override
public boolean isFullyQualified() { public boolean isFullyQualified() {
return isFullyQualified; return fIsFullyQualified;
} }
@Override @Override
public void setFullyQualified(boolean isFullyQualified) { public void setFullyQualified(boolean isFullyQualified) {
assertNotFrozen(); assertNotFrozen();
this.isFullyQualified = isFullyQualified; this.fIsFullyQualified = isFullyQualified;
} }
/** /**
@ -197,16 +258,12 @@ public class CPPASTQualifiedName extends CPPASTNameBase
break; break;
} }
} }
for (int i = 0; i <= namesPos; i++) { for (ICPPASTNameSpecifier nameSpecifier : getQualifier())
final IASTName name = names[i]; if (!nameSpecifier.accept(action))
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; return false;
} else if (!name.accept(action)) // 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; return false;
}
if (action.shouldVisitNames) { if (action.shouldVisitNames) {
switch (action.leave(this)) { switch (action.leave(this)) {
@ -236,8 +293,8 @@ public class CPPASTQualifiedName extends CPPASTNameBase
@Override @Override
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
for (int i=0; i < namesPos; ++i) { for (int i=0; i <= fQualifierPos; ++i) {
if (names[i] == n) if (fQualifier[i] == n)
return r_reference; return r_reference;
} }
if (getLastName() == n) { if (getLastName() == n) {
@ -271,8 +328,8 @@ public class CPPASTQualifiedName extends CPPASTNameBase
public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) {
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
if (namesPos > 0) { if (fQualifierPos >= 0) {
IBinding binding = names[namesPos - 1].resolveBinding(); IBinding binding = fQualifier[fQualifierPos].resolveBinding();
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) binding; ICPPClassType classType = (ICPPClassType) binding;
final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration; final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration;
@ -349,7 +406,7 @@ public class CPPASTQualifiedName extends CPPASTNameBase
return filtered; return filtered;
} }
private boolean nameMatches(char[] potential, char[] name, boolean isPrefix) { private static boolean nameMatches(char[] potential, char[] name, boolean isPrefix) {
if (isPrefix) if (isPrefix)
return ContentAssistMatcherFactory.getInstance().match(name, potential); return ContentAssistMatcherFactory.getInstance().match(name, potential);
return CharArrayUtils.equals(potential, name); 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.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; 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.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.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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. // Check whether the qualification matches.
IBinding b= getClassType(); IBinding b= getClassType();
final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) name; final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) name;
final IASTName[] names= qname.getNames(); final ICPPASTNameSpecifier[] qualifier = qname.getQualifier();
for (int i = names.length - 1; --i >= 0;) { for (int i = qualifier.length; --i >= 0;) {
if (b == null || !CharArrayUtils.equals(names[i].getLookupKey(), b.getNameCharArray())) 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; return;
b= b.getOwner(); b= b.getOwner();

View file

@ -412,8 +412,7 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
private IASTName stripQualifier(IASTName name) { private IASTName stripQualifier(IASTName name) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); name = ((ICPPASTQualifiedName)name).getLastName();
name = ns[ns.length - 1];
} }
return name; return name;
} }

View file

@ -223,12 +223,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
protected IASTName getASTName() { protected IASTName getASTName() {
IASTDeclarator dtor = (definition != null) ? definition : declarations[0]; IASTDeclarator dtor = (definition != null) ? definition : declarations[0];
dtor= ASTQueries.findInnermostDeclarator(dtor); dtor= ASTQueries.findInnermostDeclarator(dtor);
IASTName name= dtor.getName(); return dtor.getName().getLastName();
if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
name = ns[ns.length - 1];
}
return name;
} }
@Override @Override

View file

@ -131,8 +131,7 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
dtor= ASTQueries.findInnermostDeclarator(dtor); dtor= ASTQueries.findInnermostDeclarator(dtor);
IASTName name= dtor.getName(); IASTName name= dtor.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); name = name.getLastName();
name = ns[ns.length - 1];
} }
return name; 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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; 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.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; 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.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; 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.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
@ -158,7 +161,7 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace
public boolean canDenoteNamespaceMember(ICPPASTQualifiedName name) { public boolean canDenoteNamespaceMember(ICPPASTQualifiedName name) {
IScope scope= this; IScope scope= this;
IASTName[] segments= name.getNames(); ICPPASTNameSpecifier[] segments= name.getQualifier();
try { try {
for (int i= segments.length - 1; --i >= 0;) { for (int i= segments.length - 1; --i >= 0;) {
if (scope == null) if (scope == null)
@ -167,11 +170,19 @@ public class CPPNamespaceScope extends CPPScope implements ICPPInternalNamespace
if (scopeName == null) if (scopeName == null)
return false; return false;
IASTName segmentName = segments[i]; if (segments[i] instanceof IASTName) {
IASTName segmentName = (IASTName) segments[i];
if (segmentName instanceof ICPPASTTemplateId || if (segmentName instanceof ICPPASTTemplateId ||
!CharArrayUtils.equals(scopeName.getSimpleID(), segmentName.getSimpleID())) { !CharArrayUtils.equals(scopeName.getSimpleID(), segmentName.getSimpleID())) {
return false; return false;
} }
} else {
IBinding segmentBinding = segments[i].resolveBinding();
if (segmentBinding instanceof ICPPTemplateInstance ||
!CharArrayUtils.equals(scopeName.getSimpleID(), segmentBinding.getNameCharArray())) {
return false;
}
}
scope= scope.getParent(); scope= scope.getParent();
} }
if (!name.isFullyQualified() || scope == null) { if (!name.isFullyQualified() || scope == null) {

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.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.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.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; 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.ICPPASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; 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.ICPPASTExpressionList;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
@ -266,6 +268,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
return new CPPASTDeclarator(name); return new CPPASTDeclarator(name);
} }
@Override
public ICPPASTDecltypeSpecifier newDecltypeSpecifier(ICPPASTExpression decltypeExpression) {
return new CPPASTDecltypeSpecifier(decltypeExpression);
}
@Override @Override
public IASTDefaultStatement newDefaultStatement() { public IASTDefaultStatement newDefaultStatement() {
return new CPPASTDefaultStatement(); return new CPPASTDefaultStatement();

View file

@ -12,11 +12,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; 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.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
@ -70,26 +71,27 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe
@Override @Override
public IType getMemberOfClass() { public IType getMemberOfClass() {
if (classType == null) { if (classType == null) {
IASTName name; ICPPASTNameSpecifier nameSpec;
IBinding binding= null; IBinding binding= null;
ICPPASTPointerToMember pm = operator; ICPPASTPointerToMember pm = operator;
if (pm == null) { if (pm == null) {
name= new CPPASTName(); nameSpec = new CPPASTName();
} else { } else {
name = pm.getName(); nameSpec = (ICPPASTName) pm.getName();
if (name instanceof ICPPASTQualifiedName) { if (nameSpec instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); ICPPASTQualifiedName qname = ((ICPPASTQualifiedName) nameSpec);
if (ns.length > 1) ICPPASTNameSpecifier[] qualifier = qname.getQualifier();
name = ns[ns.length - 2]; if (qualifier.length > 0)
nameSpec = qualifier[qualifier.length - 1];
else else
name = ns[ns.length - 1]; nameSpec = (ICPPASTName) qname.getLastName();
} }
binding = name.resolvePreBinding(); binding = nameSpec.resolvePreBinding();
} }
if (binding instanceof IType) { if (binding instanceof IType) {
classType = (IType) binding; classType = (IType) binding;
} else { } 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; return classType;

View file

@ -240,8 +240,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
if (node instanceof ICPPASTCompositeTypeSpecifier) { if (node instanceof ICPPASTCompositeTypeSpecifier) {
node = ((ICPPASTCompositeTypeSpecifier) node).getName(); node = ((ICPPASTCompositeTypeSpecifier) node).getName();
if (node instanceof ICPPASTQualifiedName) { if (node instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)node).getNames(); node = ((ICPPASTQualifiedName) node).getLastName();
node = ns[ns.length - 1];
} }
} }
if (!(node instanceof IASTName)) if (!(node instanceof IASTName))
@ -258,8 +257,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
if (node instanceof ICPPASTElaboratedTypeSpecifier) { if (node instanceof ICPPASTElaboratedTypeSpecifier) {
node = ((ICPPASTElaboratedTypeSpecifier) node).getName(); node = ((ICPPASTElaboratedTypeSpecifier) node).getName();
if (node instanceof ICPPASTQualifiedName) { if (node instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)node).getNames(); node = ((ICPPASTQualifiedName) node).getLastName();
node = ns[ns.length - 1];
} }
} }
if (!(node instanceof IASTName)) if (!(node instanceof IASTName))

View file

@ -31,8 +31,7 @@ public class CPPUsingDeclaration extends PlatformObject implements ICPPUsingDecl
public CPPUsingDeclaration(IASTName name, IBinding[] bindings) { public CPPUsingDeclaration(IASTName name, IBinding[] bindings) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); name = name.getLastName();
name = ns[ns.length - 1];
} }
this.name = name; this.name = name;
this.delegates= bindings; this.delegates= bindings;

View file

@ -55,8 +55,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
public CPPVariable(IASTName name) { public CPPVariable(IASTName name) {
boolean isDef = name == null ? false : name.isDefinition(); boolean isDef = name == null ? false : name.isDefinition();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); name = name.getLastName();
name = ns[ns.length - 1];
} }
if (isDef) { 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.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.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.ICPPASTDeleteExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; 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.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.ICPPASTLambdaExpression.CaptureDefault;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; 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.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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; 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.ICPPASTNamespaceDefinition;
@ -243,7 +246,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return ambiguousQualifiedName(ctx); return ambiguousQualifiedName(ctx);
ICPPASTQualifiedName qname= null; ICPPASTQualifiedName qname= null;
IASTName name= null; ICPPASTNameSpecifier nameSpec= null;
final int offset= LA(1).getOffset(); final int offset= LA(1).getOffset();
int endOffset= offset; int endOffset= offset;
if (LT(1) == IToken.tCOLONCOLON) { if (LT(1) == IToken.tCOLONCOLON) {
@ -272,20 +275,28 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IToken.tCOMPLETION: case IToken.tCOMPLETION:
case IToken.tEOC: case IToken.tEOC:
IToken nt= consume(); IToken nt= consume();
name = buildName(destructorOffset, nt); nameSpec = (ICPPASTName) buildName(destructorOffset, nt);
break; break;
case IToken.t_operator: 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; break;
default: default:
if (!haveName || destructorOffset >= 0 || keywordTemplate) { if (!haveName || destructorOffset >= 0 || keywordTemplate) {
throwBacktrack(LA(1)); throwBacktrack(LA(1));
} }
name= nodeFactory.newName(CharArrayUtils.EMPTY); nameSpec= (ICPPASTName) nodeFactory.newName(CharArrayUtils.EMPTY);
if (qname != null) { if (qname != null) {
qname.addName(name); addNameSpecifier(qname, nameSpec);
} }
break loop; break loop;
} }
@ -293,7 +304,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
haveName= true; haveName= true;
// Check for template-id // 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 boolean inBinaryExpression = ctx != CastExprCtx.eNotInBExpr;
final int haveArgs = haveTemplateArguments(inBinaryExpression); final int haveArgs = haveTemplateArguments(inBinaryExpression);
boolean templateID= true; boolean templateID= true;
@ -308,13 +320,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (haveArgs == -1) if (haveArgs == -1)
throwBacktrack(LA(1)); throwBacktrack(LA(1));
name= addTemplateArguments(name, strat); nameSpec= (ICPPASTName) addTemplateArguments(name, strat);
} }
} }
endOffset= calculateEndOffset(name); endOffset= calculateEndOffset(nameSpec);
if (qname != null) { if (qname != null) {
qname.addName(name); addNameSpecifier(qname, nameSpec);
} }
if (LTcatchEOF(1) != IToken.tCOLONCOLON) if (LTcatchEOF(1) != IToken.tCOLONCOLON)
@ -326,14 +338,25 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
endOffset= consume().getEndOffset(); // :: endOffset= consume().getEndOffset(); // ::
if (qname == null) { if (qname == null) {
qname= nodeFactory.newQualifiedName(); qname= nodeFactory.newQualifiedName();
qname.addName(name); addNameSpecifier(qname, nameSpec);
} }
} }
if (qname != null) { if (qname != null) {
setRange(qname, offset, endOffset); 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) { private IASTName buildName(int destructorOffset, IToken nt) {
@ -392,6 +415,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return result; 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. * Makes a fast check whether there could be template arguments.
* -1: no, 0: ambiguous, 1: yes * -1: no, 0: ambiguous, 1: yes
@ -2968,6 +3004,20 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (encounteredRawType || encounteredTypename) if (encounteredRawType || encounteredTypename)
throwBacktrack(LA(1)); 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; simpleType= IASTSimpleDeclSpecifier.t_decltype;
consume(IToken.t_decltype); consume(IToken.t_decltype);
consume(IToken.tLPAREN); consume(IToken.tLPAREN);

View file

@ -809,7 +809,7 @@ public class CPPSemantics {
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) parent.getParent(); ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) parent.getParent();
IASTName n = compSpec.getName(); IASTName n = compSpec.getName();
if (n instanceof ICPPASTQualifiedName) { if (n instanceof ICPPASTQualifiedName) {
n = ((ICPPASTQualifiedName) n).getLastName(); n = n.getLastName();
} }
scope = CPPVisitor.getContainingScope(n); scope = CPPVisitor.getContainingScope(n);
} else { } else {
@ -1321,7 +1321,7 @@ public class CPPSemantics {
} }
if (parent instanceof ICPPASTQualifiedName) { if (parent instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent; ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
if (qname.isFullyQualified() || qname.getNames()[0] != node) if (qname.isFullyQualified() || qname.getQualifier()[0] != node)
return null; return null;
} }
} }
@ -1702,7 +1702,7 @@ public class CPPSemantics {
ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration; ICPPASTUsingDeclaration using = (ICPPASTUsingDeclaration) declaration;
IASTName name = using.getName(); IASTName name = using.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
name = ((ICPPASTQualifiedName) name).getLastName(); name = name.getLastName();
} }
ASTInternal.addName(scope, name); ASTInternal.addName(scope, name);
} else if (declaration instanceof ICPPASTNamespaceDefinition) { } 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.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; 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.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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -601,8 +602,8 @@ public class CPPTemplates {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
int idx = templates.length; int idx = templates.length;
int i = 0; int i = 0;
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier();
for (IASTName element : ns) { for (ICPPASTNameSpecifier element : qualifier) {
if (element instanceof ICPPASTTemplateId) { if (element instanceof ICPPASTTemplateId) {
++i; ++i;
if (i == idx) { if (i == idx) {
@ -612,7 +613,7 @@ public class CPPTemplates {
} }
} }
if (binding == null) if (binding == null)
binding = ns[ns.length - 1].resolveBinding(); binding = name.getLastName().resolveBinding();
} else { } else {
binding = name.resolveBinding(); binding = name.resolveBinding();
} }
@ -1527,9 +1528,9 @@ public class CPPTemplates {
// skip one // skip one
tdecl= getDirectlyEnclosingTemplateDeclaration(tdecl); tdecl= getDirectlyEnclosingTemplateDeclaration(tdecl);
} }
final IASTName[] ns= qname.getNames(); final ICPPASTNameSpecifier[] qualifier= qname.getQualifier();
for (int i = ns.length - 2; tdecl != null && i >= 0; i--) { for (int i = qualifier.length - 1; tdecl != null && i >= 0; i--) {
final IASTName n = ns[i]; final ICPPASTNameSpecifier n = qualifier[i];
if (n == name) { if (n == name) {
return tdecl; return tdecl;
} }
@ -1579,23 +1580,23 @@ public class CPPTemplates {
// Count dependent-ids // Count dependent-ids
CharArraySet tparnames= collectTemplateParameterNames(outerMostTDecl); CharArraySet tparnames= collectTemplateParameterNames(outerMostTDecl);
int depIDCount= 0; int depIDCount= 0;
IASTName owner= null; IBinding owner= null;
final IASTName[] ns= qname.getNames(); final ICPPASTNameSpecifier[] qualifier= qname.getQualifier();
for (int i = 0; i < ns.length - 1; i++) { for (int i = 0; i < qualifier.length; i++) {
IASTName n= ns[i]; ICPPASTNameSpecifier n= qualifier[i];
if (n instanceof ICPPASTTemplateId) { if (n instanceof ICPPASTTemplateId) {
if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) { if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) {
depIDCount++; depIDCount++;
} }
} }
if (depIDCount == 0) { if (depIDCount == 0) {
owner= n; owner= n.resolveBinding();
} }
} }
if (qname.getLastName() instanceof ICPPASTTemplateId if (qname.getLastName() instanceof ICPPASTTemplateId
|| paramTDeclCount > depIDCount // not enough template ids || paramTDeclCount > depIDCount // not enough template ids
|| ns.length < 2 // ::name || qualifier.length < 1 // ::name
) { ) {
lastIsTemplate= true; lastIsTemplate= true;
depIDCount++; depIDCount++;
@ -1606,7 +1607,7 @@ public class CPPTemplates {
nestingLevel= 0; nestingLevel= 0;
if (owner != null) { if (owner != null) {
int consumesTDecl= 0; int consumesTDecl= 0;
IBinding b= owner.resolveBinding(); IBinding b= owner;
if (b instanceof IType) { if (b instanceof IType) {
IType t= SemanticUtil.getNestedType((IType) b, TDEF); IType t= SemanticUtil.getNestedType((IType) b, TDEF);
if (t instanceof IBinding) if (t instanceof IBinding)
@ -1721,7 +1722,8 @@ public class CPPTemplates {
if (names.containsKey(name.getLookupKey())) { if (names.containsKey(name.getLookupKey())) {
IASTNode parent= name.getParent(); IASTNode parent= name.getParent();
if (parent instanceof ICPPASTQualifiedName) { 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; return PROCESS_CONTINUE;
} }
result[0]= true; result[0]= true;
@ -1841,12 +1843,12 @@ public class CPPTemplates {
} }
if (name != null) { if (name != null) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier();
IASTDeclaration currDecl = decl; IASTDeclaration currDecl = decl;
for (int j = 0; j < ns.length; j++) { for (ICPPASTNameSpecifier segment : qualifier) {
if (ns[j] instanceof ICPPASTTemplateId || j + 1 == ns.length) { if (segment instanceof ICPPASTTemplateId) {
if (currDecl == templateDecl) { if (currDecl == templateDecl) {
return ns[j]; return (IASTName) segment;
} }
if (!(currDecl instanceof ICPPASTTemplateDeclaration)) { if (!(currDecl instanceof ICPPASTTemplateDeclaration)) {
return null; return null;
@ -1854,6 +1856,9 @@ public class CPPTemplates {
currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration(); currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration();
} }
} }
if (currDecl == templateDecl) {
return name.getLastName();
}
} else { } else {
return name; 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.ICPPASTLambdaExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; 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.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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; 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.ICPPASTNamespaceDefinition;
@ -316,8 +317,8 @@ public class CPPVisitor extends ASTQueries {
} }
private static boolean declaresMemberInClassOrNamespace(ICPPASTQualifiedName qname) { private static boolean declaresMemberInClassOrNamespace(ICPPASTQualifiedName qname) {
IASTName[] names= qname.getNames(); ICPPASTNameSpecifier[] qualifier= qname.getQualifier();
if (names.length < 2) if (qualifier.length == 0)
return false; return false;
IASTNode parent= qname.getParent(); IASTNode parent= qname.getParent();
@ -346,7 +347,7 @@ public class CPPVisitor extends ASTQueries {
if (inScope == null) if (inScope == null)
return false; return false;
IBinding pb= names[names.length - 2].resolvePreBinding(); IBinding pb= qualifier[qualifier.length - 1].resolvePreBinding();
if (pb instanceof IProblemBinding) if (pb instanceof IProblemBinding)
return false; return false;
@ -451,8 +452,7 @@ public class CPPVisitor extends ASTQueries {
IASTName name = elabType.getName(); IASTName name = elabType.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
qualified = true; qualified = true;
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); name = name.getLastName();
name = ns[ns.length - 1];
} }
if (parent instanceof IASTSimpleDeclaration) { if (parent instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration) parent).getDeclarators(); IASTDeclarator[] dtors = ((IASTSimpleDeclaration) parent).getDeclarators();
@ -592,11 +592,7 @@ public class CPPVisitor extends ASTQueries {
} }
private static IBinding createBinding(ICPPASTCompositeTypeSpecifier compType) { private static IBinding createBinding(ICPPASTCompositeTypeSpecifier compType) {
IASTName name = compType.getName(); IASTName name = compType.getName().getLastName();
if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
name = ns[ns.length - 1];
}
if (name instanceof ICPPASTTemplateId) if (name instanceof ICPPASTTemplateId)
return CPPTemplates.createBinding((ICPPASTTemplateId) name); return CPPTemplates.createBinding((ICPPASTTemplateId) name);
@ -701,10 +697,7 @@ public class CPPVisitor extends ASTQueries {
final IASTDeclarator typeRelevantDtor= findTypeRelevantDeclarator(declarator); final IASTDeclarator typeRelevantDtor= findTypeRelevantDeclarator(declarator);
IASTName name= declarator.getName(); IASTName name= declarator.getName().getLastName();
if (name instanceof ICPPASTQualifiedName) {
name= ((ICPPASTQualifiedName) name).getLastName();
}
// in case the binding was created starting from another name within the declarator. // in case the binding was created starting from another name within the declarator.
IBinding candidate= name.getBinding(); IBinding candidate= name.getBinding();
@ -938,13 +931,13 @@ public class CPPVisitor extends ASTQueries {
if (parent instanceof IASTDeclarator) { if (parent instanceof IASTDeclarator) {
if (isConstructorDtor((IASTDeclarator) parent)) { if (isConstructorDtor((IASTDeclarator) parent)) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] names = ((ICPPASTQualifiedName) name).getNames(); ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier();
if (names.length >= 2) { if (qualifier.length >= 1) {
IBinding b= names[names.length - 2].resolvePreBinding(); IBinding b= qualifier[qualifier.length - 1].resolvePreBinding();
if (b instanceof IType) { if (b instanceof IType) {
IType classType= getNestedType((IType) b, TDEF); IType classType= getNestedType((IType) b, TDEF);
if (classType instanceof ICPPClassType) { if (classType instanceof ICPPClassType) {
final char[] dtorName = names[names.length - 1].getLookupKey(); final char[] dtorName = name.getLastName().getLookupKey();
final char[] className = ((ICPPClassType) classType).getNameCharArray(); final char[] className = ((ICPPClassType) classType).getNameCharArray();
return CharArrayUtils.equals(dtorName, className); return CharArrayUtils.equals(dtorName, className);
} }
@ -1068,8 +1061,7 @@ public class CPPVisitor extends ASTQueries {
IASTDeclarator dtor = (IASTDeclarator) parent; IASTDeclarator dtor = (IASTDeclarator) parent;
IASTName name = dtor.getName(); IASTName name = dtor.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); return getContainingScope(name.getLastName());
return getContainingScope(ns[ns.length - 1]);
} }
} else if (parent instanceof ICPPASTConstructorChainInitializer) { } else if (parent instanceof ICPPASTConstructorChainInitializer) {
// The initializer for the member initializer is resolved in // The initializer for the member initializer is resolved in
@ -1107,8 +1099,7 @@ public class CPPVisitor extends ASTQueries {
dtor = dtor.getNestedDeclarator(); dtor = dtor.getNestedDeclarator();
IASTName name = dtor.getName(); IASTName name = dtor.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames(); return getContainingScope(name.getLastName());
return getContainingScope(ns[ns.length - 1]);
} }
} }
} else if (parent instanceof ICPPASTTemplateId && } else if (parent instanceof ICPPASTTemplateId &&
@ -1129,12 +1120,7 @@ public class CPPVisitor extends ASTQueries {
} }
} else if (node instanceof ICPPASTBaseSpecifier) { } else if (node instanceof ICPPASTBaseSpecifier) {
ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) node.getParent(); ICPPASTCompositeTypeSpecifier compSpec = (ICPPASTCompositeTypeSpecifier) node.getParent();
IASTName n = compSpec.getName(); IASTName n = compSpec.getName().getLastName();
if (n instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) n).getNames();
n = ns[ns.length - 1];
}
return getContainingScope(n); return getContainingScope(n);
} else if (node instanceof IASTEnumerator) { } else if (node instanceof IASTEnumerator) {
node= node.getParent(); node= node.getParent();
@ -1200,10 +1186,11 @@ public class CPPVisitor extends ASTQueries {
if (parent instanceof ICPPASTQualifiedName) { if (parent instanceof ICPPASTQualifiedName) {
final ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent; final ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent;
final IASTName[] names = qname.getNames(); final ICPPASTNameSpecifier[] segments= qname.getAllSegments();
int i = 0; int i = 0;
for (; i < names.length; i++) { for (; i < segments.length; i++) {
if (names[i] == name) break; if (segments[i] == name)
break;
} }
final IASTTranslationUnit tu = parent.getTranslationUnit(); final IASTTranslationUnit tu = parent.getTranslationUnit();
if (i == 0) { if (i == 0) {
@ -1219,7 +1206,7 @@ public class CPPVisitor extends ASTQueries {
} else if (i > 0) { } else if (i > 0) {
// For template functions we may need to resolve a template parameter // For template functions we may need to resolve a template parameter
// as a parent of an unknown type used as parameter type. // 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. // 7.1.3-7 Unwrap typedefs, delete cv-qualifiers.
if (binding instanceof ITypedef) { if (binding instanceof ITypedef) {
@ -1249,7 +1236,7 @@ public class CPPVisitor extends ASTQueries {
} }
if (done) { if (done) {
if (scope == null) { 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; return scope;
} }
@ -1310,11 +1297,7 @@ public class CPPVisitor extends ASTQueries {
return fdef.getScope(); return fdef.getScope();
IASTFunctionDeclarator fnDeclarator = fdef.getDeclarator(); IASTFunctionDeclarator fnDeclarator = fdef.getDeclarator();
IASTName name = findInnermostDeclarator(fnDeclarator).getName(); IASTName name = findInnermostDeclarator(fnDeclarator).getName().getLastName();
if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
name = ns[ns.length - 1];
}
return getContainingScope(name); return getContainingScope(name);
} }
@ -1819,11 +1802,7 @@ public class CPPVisitor extends ASTQueries {
private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) { private static IType createType(IType returnType, ICPPASTFunctionDeclarator fnDtor) {
IType[] pTypes = createParameterTypes(fnDtor); IType[] pTypes = createParameterTypes(fnDtor);
IASTName name = fnDtor.getName(); IASTName name = fnDtor.getName().getLastName();
if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
name = ns[ns.length - 1];
}
if (name instanceof ICPPASTConversionName) { if (name instanceof ICPPASTConversionName) {
returnType = createType(((ICPPASTConversionName) name).getTypeId()); returnType = createType(((ICPPASTConversionName) name).getTypeId());
} else { } else {
@ -2281,11 +2260,7 @@ public class CPPVisitor extends ASTQueries {
} }
if (node instanceof IASTFunctionDeclarator) { if (node instanceof IASTFunctionDeclarator) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node; ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node;
IASTName funcName = findInnermostDeclarator(dtor).getName(); IASTName funcName = findInnermostDeclarator(dtor).getName().getLastName();
if (funcName instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName) funcName).getNames();
funcName = ns[ns.length - 1];
}
IScope s = getContainingScope(funcName); IScope s = getContainingScope(funcName);
while (s instanceof ICPPTemplateScope) { while (s instanceof ICPPTemplateScope) {
s = s.getParent(); s = s.getParent();
@ -2521,16 +2496,16 @@ public class CPPVisitor extends ASTQueries {
IASTNode node= name.getLastName(); IASTNode node= name.getLastName();
while (node instanceof IASTName) { while (node instanceof IASTName) {
if (node instanceof ICPPASTQualifiedName) { if (node instanceof ICPPASTQualifiedName) {
IASTName[] qn= ((ICPPASTQualifiedName) node).getNames(); ICPPASTNameSpecifier[] segments = ((ICPPASTQualifiedName) node).getAllSegments();
int i= qn.length; int i = segments.length;
while (--i >= 0) { while (--i >= 0) {
if (qn[i] == name) { if (segments[i] == name) {
break; break;
} }
} }
if (--i < 0) if (--i < 0)
break; break;
IBinding binding = qn[i].resolveBinding(); IBinding binding = segments[i].resolveBinding();
if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) {
binding = ((CPPASTTranslationUnit) name.getTranslationUnit()).mapToAST((ICPPClassType) binding, name); 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.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; 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.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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@ -162,11 +163,11 @@ public class LookupData extends ScopeLookupData {
} else { } else {
nameParent= parent.getParent(); nameParent= parent.getParent();
} }
final IASTName[] names = qn.getNames(); final ICPPASTNameSpecifier[] qualifier = qn.getQualifier();
if (qn.isFullyQualified()) { if (qn.isFullyQualified()) {
qualified= true; qualified= true;
} else if (names.length > 0) { } else if (qualifier.length > 0) {
if (names[0] != tn) { if (qualifier[0] != tn) {
qualified= true; 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.IPointerType;
import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IQualifierType;
import org.eclipse.cdt.core.dom.ast.IType; 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.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
@ -289,13 +290,12 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
ICPPASTQualifiedName newQualifiedName = ICPPASTQualifiedName newQualifiedName =
((ICPPNodeFactory) factory).newQualifiedName(); ((ICPPNodeFactory) factory).newQualifiedName();
int nbQualifiedNames = fullQualifiedName.getNames().length; ICPPASTNameSpecifier[] qualifier = fullQualifiedName.getQualifier();
if (nbQualifiedNames > 1) { int nbQualifiedNames = qualifier.length;
for (int i = 0; i < nbQualifiedNames - 1; i++) { for (int i = 0; i < nbQualifiedNames; i++) {
newQualifiedName.addName(fullQualifiedName.getNames()[i].copy(CopyStyle.withLocations)); newQualifiedName.addNameSpecifier(qualifier[i].copy(CopyStyle.withLocations));
} }
} newQualifiedName.setLastName(tempId);
newQualifiedName.addName(tempId);
return factory.newTypedefNameSpecifier(newQualifiedName); return factory.newTypedefNameSpecifier(newQualifiedName);
} else { } 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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.Keywords;
@ -85,9 +86,9 @@ public class NameWriter extends NodeWriter {
} }
private boolean isDependentName(ICPPASTQualifiedName qname, ICPPASTTemplateId tempId) { private boolean isDependentName(ICPPASTQualifiedName qname, ICPPASTTemplateId tempId) {
IASTName[] names = qname.getNames(); ICPPASTNameSpecifier[] segments = qname.getAllSegments();
for (int i = 0; i < names.length; ++i){ for (int i = 0; i < segments.length; ++i){
if (names[i] == tempId){ if (segments[i] == tempId){
return isDependentName(qname, tempId, i); return isDependentName(qname, tempId, i);
} }
} }
@ -98,10 +99,10 @@ public class NameWriter extends NodeWriter {
if (i <= 0){ if (i <= 0){
return false; return false;
} }
if (qname.getNames()[i - 1] instanceof ICPPASTTemplateId) { if (qname.getQualifier()[i - 1] instanceof ICPPASTTemplateId) {
return true; return true;
} }
IBinding binding = qname.getNames()[i - 1].resolveBinding(); IBinding binding = qname.getQualifier()[i - 1].resolveBinding();
if (binding instanceof CPPTemplateTypeParameter) { if (binding instanceof CPPTemplateTypeParameter) {
return true; return true;
} }
@ -121,12 +122,10 @@ public class NameWriter extends NodeWriter {
if (qname.isFullyQualified()) { if (qname.isFullyQualified()) {
scribe.print(COLON_COLON); scribe.print(COLON_COLON);
} }
IASTName[] nodes = qname.getNames(); for (ICPPASTNameSpecifier segment : qname.getQualifier()) {
for (int i = 0; i < nodes.length; ++i) { segment.accept(visitor);
nodes[i].accept(visitor);
if (i + 1 < nodes.length) {
scribe.print(COLON_COLON); 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) { private IASTName getLastInQualified(IASTName name) {
if (name instanceof ICPPASTQualifiedName) { return name.getLastName();
name= ((ICPPASTQualifiedName) name).getLastName();
}
return name;
} }
private void pop(IASTNode node) { 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.ICPPASTFunctionWithTryBlock;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; 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.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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; 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.ICPPASTNamespaceDefinition;
@ -3422,16 +3423,15 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
if (node.isFullyQualified()) { if (node.isFullyQualified()) {
scribe.printNextToken(Token.tCOLONCOLON); scribe.printNextToken(Token.tCOLONCOLON);
} }
IASTName[] names= node.getNames(); for (ICPPASTNameSpecifier nameSpec : node.getQualifier()) {
for (int i = 0; i < names.length - 1; i++) { nameSpec.accept(this);
names[i].accept(this);
scribe.printNextToken(Token.tCOLONCOLON); scribe.printNextToken(Token.tCOLONCOLON);
} }
if (peekNextToken() == Token.tCOMPL) { if (peekNextToken() == Token.tCOMPL) {
// destructor // destructor
scribe.printNextToken(Token.tCOMPL, false); scribe.printNextToken(Token.tCOMPL, false);
} }
names[names.length - 1].accept(this); node.getLastName().accept(this);
return PROCESS_SKIP; 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.c.ICFunctionScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; 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.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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
@ -356,9 +357,9 @@ public class SemanticHighlightings {
if (node instanceof ICPPASTFunctionDeclarator) { if (node instanceof ICPPASTFunctionDeclarator) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qName= (ICPPASTQualifiedName) name; ICPPASTQualifiedName qName= (ICPPASTQualifiedName) name;
IASTName[] names= qName.getNames(); ICPPASTNameSpecifier[] qualifier= qName.getQualifier();
if (names.length > 1) { if (qualifier.length > 0) {
if (names[names.length - 2].getBinding() instanceof ICPPClassType) { if (qualifier[qualifier.length - 1].resolveBinding() instanceof ICPPClassType) {
return true; 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; 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.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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -177,7 +178,7 @@ public class MethodContext {
} }
private static ICPPClassType getClassBinding(ICPPASTQualifiedName qname) { 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(); ICPPClassType bind = (ICPPClassType)classname.resolveBinding();
return bind; 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.ICPPASTConversionName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; 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.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.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.ICPPASTTemplateDeclaration;
@ -594,8 +595,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
ICPPASTQualifiedName qname = new CPPASTQualifiedName(); ICPPASTQualifiedName qname = new CPPASTQualifiedName();
if (context.getType() == ContextType.METHOD) { if (context.getType() == ContextType.METHOD) {
if (context.getMethodQName() != null) { if (context.getMethodQName() != null) {
for (int i = 0; i < context.getMethodQName().getNames().length - 1; i++) { for (ICPPASTNameSpecifier segment : context.getMethodQName().getQualifier()) {
qname.addName(new CPPASTName(context.getMethodQName().getNames()[i].toCharArray())); 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;
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle; import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; 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.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
@ -116,8 +117,6 @@ public class AccessorDescriptor implements Comparable<AccessorDescriptor> {
} }
IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node; IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node;
CPPASTQualifiedName qname = new CPPASTQualifiedName(); return new CPPASTQualifiedName((ICPPASTName) comp.getName().copy(CopyStyle.withLocations));
qname.addName(comp.getName().copy(CopyStyle.withLocations));
return qname;
} }
} }

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.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; 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.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.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; 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.ICPPASTTemplateId;
@ -1114,9 +1115,9 @@ public class BindingClassifier {
// elsewhere). // elsewhere).
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
// All qualifying names must be defined. // All qualifying names must be defined.
IASTName[] names = ((ICPPASTQualifiedName) name).getNames(); ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier();
for (int i = 0; i < names.length - 1; i++) { for (ICPPASTNameSpecifier nameSpec : qualifier) {
defineBinding(names[i].resolveBinding()); 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.IFunction;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; 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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; 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) { private boolean match(IASTName name, ArrayList<String> usingChain, boolean excludeLast) {
IASTName[] names; ICPPASTNameSpecifier[] names;
if (name instanceof ICPPASTQualifiedName) { 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 { } else {
names = new IASTName[] { name }; names = new ICPPASTNameSpecifier[] { (ICPPASTName) name };
} }
if (names.length != usingChain.size() - (excludeLast ? 1 : 0)) { if (names.length != usingChain.size() - (excludeLast ? 1 : 0)) {
return false; 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.ICFunctionScope;
import org.eclipse.cdt.core.dom.ast.c.ICScope; 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.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.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
@ -173,9 +174,8 @@ public class ASTManager implements IDisposable {
public static IASTName getSimpleName(IASTName name) { public static IASTName getSimpleName(IASTName name) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName names[]= ((ICPPASTQualifiedName) name).getNames(); if (name.getLastName() != null) {
if (names.length > 0) { name= name.getLastName();
name= names[names.length - 1];
} }
} }
return name; return name;
@ -843,10 +843,7 @@ public class ASTManager implements IDisposable {
final int length = fArgument.getLength(); final int length = fArgument.getLength();
IASTName name= nodeSelector.findEnclosingName(offset, length); IASTName name= nodeSelector.findEnclosingName(offset, length);
if (name != null) { if (name != null) {
if (name instanceof ICPPASTQualifiedName) { name= name.getLastName();
IASTName[] na= ((ICPPASTQualifiedName) name).getNames();
name= na[na.length - 1];
}
} else { } else {
IASTNode node= nodeSelector.findEnclosingNode(offset, length); IASTNode node= nodeSelector.findEnclosingNode(offset, length);
if (node instanceof IASTPreprocessorMacroDefinition || if (node instanceof IASTPreprocessorMacroDefinition ||
@ -1192,8 +1189,8 @@ public class ASTManager implements IDisposable {
boolean problemInQualifier= false; boolean problemInQualifier= false;
IASTNode parent= name.getParent(); IASTNode parent= name.getParent();
if (parent instanceof ICPPASTQualifiedName) { if (parent instanceof ICPPASTQualifiedName) {
IASTName[] names= ((ICPPASTQualifiedName) parent).getNames(); ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) parent).getQualifier();
for (IASTName n : names) { for (ICPPASTNameSpecifier n : qualifier) {
if (n == name) if (n == name)
break; break;
final IBinding b = n.resolveBinding(); 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.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; 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; 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) { final public int visit(IASTName name) {
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
ICPPASTQualifiedName qn= (ICPPASTQualifiedName) name; ICPPASTQualifiedName qn= (ICPPASTQualifiedName) name;
IASTName[] names= qn.getNames(); ICPPASTNameSpecifier[] segments= qn.getAllSegments();
boolean visited= false; boolean visited= false;
for (int i = 0; i < names.length; i++) { for (int i = 0; i < segments.length; i++) {
if (checkLocation(names[i])) { if (segments[i] instanceof IASTName && checkLocation(segments[i])) {
if (visitName(names[i]) == PROCESS_ABORT) { if (visitName((IASTName) segments[i]) == PROCESS_ABORT) {
return PROCESS_ABORT; return PROCESS_ABORT;
} }
visited= true; visited= true;
} }
} }
if (!visited && names.length>0) { if (!visited) {
if (checkLocation(name)) { 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.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; 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.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; 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.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; 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.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompositeTypeSpecifier; 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.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.ui.refactoring.Container; import org.eclipse.cdt.internal.ui.refactoring.Container;
@ -52,12 +51,9 @@ public class InsertionPointFinder {
String decl_name = decl.getName().toString(); String decl_name = decl.getName().toString();
for(ICPPASTFunctionDefinition def: alldefinitionsoutside) { for(ICPPASTFunctionDefinition def: alldefinitionsoutside) {
String def_name = null; String def_name = null;
if (def.getDeclarator().getName() instanceof ICPPASTQualifiedName) { IASTName name = def.getDeclarator().getName();
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) def.getDeclarator().getName(); if (name != null)
def_name = qname.getNames()[1].toString(); def_name = name.getLastName().toString();
} else if (def.getDeclarator().getName() instanceof CPPASTName) {
def_name = def.getDeclarator().getName().toString();
}
if (decl_name.equals(def_name)) { if (decl_name.equals(def_name)) {
if (def.getParent() != null && def.getParent() instanceof ICPPASTTemplateDeclaration) { 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.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; 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.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.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
@ -327,19 +329,21 @@ public class ToggleFromInHeaderToImplementationStrategy implements IToggleRefact
(ICPPASTQualifiedName) new_definition.getDeclarator().getName(); (ICPPASTQualifiedName) new_definition.getDeclarator().getName();
ICPPASTQualifiedName qname_new = new CPPASTQualifiedName(); ICPPASTQualifiedName qname_new = new CPPASTQualifiedName();
boolean start = false; boolean start = false;
for(IASTName partname: qname.getNames()) { for(ICPPASTNameSpecifier partname: qname.getQualifier()) {
if (partname.toString().equals(ns.getName().toString())) { if (partname.toString().equals(ns.getName().toString())) {
start = true; start = true;
continue; continue;
} }
if (start) 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); new_definition.getDeclarator().setName(qname_new);
} }
} }
} }
}
private CPPASTNamespaceDefinition createNamespace(ICPPASTNamespaceDefinition parent_namespace) { private CPPASTNamespaceDefinition createNamespace(ICPPASTNamespaceDefinition parent_namespace) {
CPPASTNamespaceDefinition insertionParent = new CPPASTNamespaceDefinition( CPPASTNamespaceDefinition insertionParent = new CPPASTNamespaceDefinition(

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.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; 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.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.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
@ -120,7 +121,7 @@ public class ASTHelper {
public static ArrayList<ICPPASTNamespaceDefinition> getNamespaces(ICPPASTQualifiedName qualifiedName) { public static ArrayList<ICPPASTNamespaceDefinition> getNamespaces(ICPPASTQualifiedName qualifiedName) {
ArrayList<ICPPASTNamespaceDefinition> namespaces = new ArrayList<ICPPASTNamespaceDefinition>(); ArrayList<ICPPASTNamespaceDefinition> namespaces = new ArrayList<ICPPASTNamespaceDefinition>();
for (IASTName aktQualifiedPartName : qualifiedName.getNames()) { for (ICPPASTNameSpecifier aktQualifiedPartName : qualifiedName.getAllSegments()) {
IBinding binding = aktQualifiedPartName.resolveBinding(); IBinding binding = aktQualifiedPartName.resolveBinding();
for (IASTName aktResolvedName : qualifiedName.getTranslationUnit().getDefinitionsInAST(binding)) { for (IASTName aktResolvedName : qualifiedName.getTranslationUnit().getDefinitionsInAST(binding)) {
if (aktResolvedName.getParent() instanceof ICPPASTNamespaceDefinition) { 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.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable; 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.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.Keywords;
@ -69,22 +71,22 @@ public class NameHelper {
public static ICPPASTQualifiedName createQualifiedNameFor(IASTName declaratorName, public static ICPPASTQualifiedName createQualifiedNameFor(IASTName declaratorName,
ITranslationUnit declarationTu, int selectionOffset, ITranslationUnit insertFileTu, ITranslationUnit declarationTu, int selectionOffset, ITranslationUnit insertFileTu,
int insertLocation, CRefactoringContext astCache) throws CoreException { int insertLocation, CRefactoringContext astCache) throws CoreException {
ICPPASTQualifiedName qname = new CPPASTQualifiedName(); ICPPASTQualifiedName qname = new CPPASTQualifiedName(
(ICPPASTName) declaratorName.copy(CopyStyle.withLocations));
IASTName[] declarationNames = NamespaceHelper.getSurroundingNamespace(declarationTu, ICPPASTNameSpecifier[] declarationNames = NamespaceHelper.getSurroundingNamespace(declarationTu,
selectionOffset, astCache).getNames(); selectionOffset, astCache).getAllSegments();
IASTName[] implementationNames = NamespaceHelper.getSurroundingNamespace(insertFileTu, ICPPASTNameSpecifier[] implementationNames = NamespaceHelper.getSurroundingNamespace(insertFileTu,
insertLocation, astCache).getNames(); insertLocation, astCache).getAllSegments();
for (int i = 0; i < declarationNames.length; i++) { for (int i = 0; i < declarationNames.length; i++) {
if (i >= implementationNames.length) { if (i >= implementationNames.length) {
qname.addName(declarationNames[i]); qname.addNameSpecifier(declarationNames[i]);
} else if (!Arrays.equals(declarationNames[i].toCharArray(), implementationNames[i].toCharArray())) { } 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; 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.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock; 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.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.ICPPASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; 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.ICPPASTNamespaceDefinition;
@ -1334,8 +1335,9 @@ public class CPPBuildASTParserAction extends BuildASTParserAction {
ICPPASTQualifiedName newQualifiedName = nodeFactory.newQualifiedName(); ICPPASTQualifiedName newQualifiedName = nodeFactory.newQualifiedName();
newQualifiedName.addName(name); newQualifiedName.addName(name);
for(IASTName n : qualifiedName.getNames()) for(ICPPASTNameSpecifier n : qualifiedName.getQualifier())
newQualifiedName.addName(n); newQualifiedName.addNameSpecifier(n);
newQualifiedName.addName(qualifiedName.getLastName());
ParserUtil.setOffsetAndLength(newQualifiedName, offset(name), endOffset(qualifiedName.getLastName()) - offset(name)); ParserUtil.setOffsetAndLength(newQualifiedName, offset(name), endOffset(qualifiedName.getLastName()) - offset(name));