diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java index afde4aaeeae..fae5b672666 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java @@ -524,7 +524,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest { // struct Base::Datum; // error: Datum undefined // struct Base::Data* pBase; // OK: refers to nested Data public void test3_4_4s3() throws Exception { - parse(getAboveComment(), ParserLanguage.CPP, true, 0); + String[] problems= {"::Glob", "Glob", "Base::Datum", "Datum"}; + parse(getAboveComment(), ParserLanguage.CPP, problems); } // static void f(); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 81550fef653..ea5a472b683 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -9554,4 +9554,32 @@ public class AST2CPPTests extends AST2BaseTest { public void testAmbiguityResolution_Bug359364() throws Exception { parseAndCheckBindings(); } + + // template struct C { + // C(const C& c) {} + // }; + // struct D { + // typedef const D& TD; + // D(TD c) {} + // }; + // struct E { + // E(); + // }; + // typedef E F; + // F::E(){} + public void testImplicitCtors_360223() throws Exception { + BindingAssertionHelper bh= getAssertionHelper(); + ICPPClassType c= bh.assertNonProblem("C", 0); + ICPPConstructor[] ctors = c.getConstructors(); + assertEquals(1, ctors.length); + assertFalse(ctors[0].isImplicit()); + + c= bh.assertNonProblem("D", 0); + ctors = c.getConstructors(); + assertEquals(1, ctors.length); + assertFalse(ctors[0].isImplicit()); + + IBinding ctor= bh.assertNonProblem("E(){}", 1); + assertTrue(ctor instanceof ICPPConstructor); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 50970756265..ca6240ec93e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -3761,17 +3761,17 @@ public class AST2TemplateTests extends AST2BaseTest { // ~DumbPtr (); // }; // template - // DumbPtr::DumbPtr/**/ (const DumbPtr& aObj) { + // DumbPtr::DumbPtr/**/ (const DumbPtr& aObj) { // } // template - // DumbPtr::~DumbPtr/**/ () { + // DumbPtr::~DumbPtr/**/ () { // } public void testCtorWithTemplateID_259600() throws Exception { final String code = getAboveComment(); parseAndCheckBindings(code); BindingAssertionHelper bh= new BindingAssertionHelper(code, true); - ICPPConstructor ctor= bh.assertNonProblem("DumbPtr/**/", 10); - ICPPMethod dtor= bh.assertNonProblem("~DumbPtr/**/", 11); + ICPPConstructor ctor= bh.assertNonProblem("DumbPtr/**/", 7); + ICPPMethod dtor= bh.assertNonProblem("~DumbPtr/**/", 8); } // template class XT { @@ -5562,4 +5562,16 @@ public class AST2TemplateTests extends AST2BaseTest { final String code= getAboveComment(); parseAndCheckBindings(code); } + + // template struct B { + // void m(); + // }; + // template struct C : B { + // using B::m; + // void m(); + // }; + // template void C::m() {} + public void testDependentUsingDeclaration() throws Exception { + parseAndCheckBindings(); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java index 8e30a70c3ce..5e0277075f3 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/CompleteParser2Tests.java @@ -655,7 +655,7 @@ public class CompleteParser2Tests extends BaseTestCase { public void testNestedClassname() throws Exception { - IASTTranslationUnit tu = parse( "namespace A { } \n class A::B { };"); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( "namespace A { \n class A::B { };}"); //$NON-NLS-1$ CPPNameCollector col = new CPPNameCollector(); tu.accept( col ); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java index 18dded3ab59..3b052cc546d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCompositeTests.java @@ -35,6 +35,7 @@ import org.eclipse.cdt.core.testplugin.CProjectHelper; import org.eclipse.cdt.core.testplugin.CTestPlugin; import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.core.testplugin.util.TestSourceReader; +import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.runtime.CoreException; @@ -458,9 +459,10 @@ class ProjectBuilder { CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER) : CProjectHelper.createCCProject(name, "bin", IPDOMManager.ID_NO_INDEXER); + IFile lastFile= null; for (Iterator i = path2content.entrySet().iterator(); i.hasNext();) { Map.Entry entry = (Map.Entry) i.next(); - TestSourceReader.createFile(result.getProject(), new Path((String)entry.getKey()), (String) entry.getValue()); + lastFile= TestSourceReader.createFile(result.getProject(), new Path((String)entry.getKey()), (String) entry.getValue()); } IProjectDescription desc = result.getProject().getDescription(); @@ -468,6 +470,10 @@ class ProjectBuilder { result.getProject().setDescription(desc, new NullProgressMonitor()); CCorePlugin.getIndexManager().setIndexerId(result, IPDOMManager.ID_FAST_INDEXER); + if (lastFile != null) { + IIndex index= CCorePlugin.getIndexManager().getIndex(result); + TestSourceReader.waitUntilFileIsIndexed(index, lastFile, 2000); + } BaseTestCase.waitForIndexer(result); return result; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 382288893f0..4a6d8243e02 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -15,6 +15,10 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; + import java.util.ArrayList; import java.util.List; @@ -39,10 +43,9 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; @@ -51,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; @@ -106,7 +110,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { ICPPParameter[] ps = new ICPPParameter[] { new CPPParameter(pType, 0) }; int i= 0; - ImplicitsAnalysis ia= new ImplicitsAnalysis(compTypeSpec); + ImplicitsAnalysis ia= new ImplicitsAnalysis(compTypeSpec, clsType); implicits= new ICPPMethod[ia.getImplicitsToDeclareCount()]; if (!ia.hasUserDeclaredConstructor()) { @@ -405,10 +409,12 @@ class ImplicitsAnalysis { private boolean hasUserDeclaredCopyConstructor; private boolean hasUserDeclaredCopyAssignmentOperator; private boolean hasUserDeclaredDestructor; + private ICPPClassType classType; - ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compSpec) { + ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compSpec, ICPPClassType clsType) { + classType= clsType; + ICPPASTFunctionDeclarator[] ctors= getUserDeclaredCtorOrDtor(compSpec, true); - hasUserDeclaredConstructor= ctors.length> 0; hasUserDeclaredCopyConstructor= false; hasUserDeclaredCopyAssignmentOperator= false; @@ -418,7 +424,7 @@ class ImplicitsAnalysis { ICPPASTFunctionDeclarator dcltor= ctors[i]; IASTParameterDeclaration[] ps = dcltor.getParameters(); if (ps.length >= 1) { - if (paramHasTypeReferenceToTheAssociatedClassType(ps[0], compSpec.getName().getRawSignature())) { + if (hasTypeReferenceToClassType(ps[0])) { // and all remaining arguments have initializers for (int j = 1; j < ps.length; j++) { if (ps[j].getDeclarator().getInitializer() == null) { @@ -441,7 +447,7 @@ class ImplicitsAnalysis { + (!hasUserDeclaredCopyAssignmentOperator ? 1 : 0); } - private static ICPPASTFunctionDeclarator[] getUserDeclaredCtorOrDtor(ICPPASTCompositeTypeSpecifier compSpec, boolean constructor) { + private ICPPASTFunctionDeclarator[] getUserDeclaredCtorOrDtor(ICPPASTCompositeTypeSpecifier compSpec, boolean constructor) { List result= new ArrayList(); IASTDeclaration[] members = compSpec.getMembers(); char[] name = compSpec.getName().getLookupKey(); @@ -483,7 +489,7 @@ class ImplicitsAnalysis { return result.toArray(new ICPPASTFunctionDeclarator[result.size()]); } - private static ICPPASTFunctionDeclarator[] getUserDeclaredCopyAssignmentOperators(ICPPASTCompositeTypeSpecifier compSpec) { + private ICPPASTFunctionDeclarator[] getUserDeclaredCopyAssignmentOperators(ICPPASTCompositeTypeSpecifier compSpec) { List result= new ArrayList(); IASTDeclaration[] members = compSpec.getMembers(); IASTDeclarator dcltor = null; @@ -504,7 +510,7 @@ class ImplicitsAnalysis { continue; IASTParameterDeclaration[] ps = ((ICPPASTFunctionDeclarator)dcltor).getParameters(); - if (ps.length != 1 || !paramHasTypeReferenceToTheAssociatedClassType(ps[0], null)) + if (ps.length != 1 || !hasTypeReferenceToClassType(ps[0])) continue; result.add((ICPPASTFunctionDeclarator)dcltor); @@ -512,25 +518,20 @@ class ImplicitsAnalysis { return result.toArray(new ICPPASTFunctionDeclarator[result.size()]); } - /** - * @param compSpec the name the parameter must have in order to match, or null for any name - * @param dec - * @return whether the specified parameter is a reference to the associated class type, and - * (optionally) if it has the specified name - */ - private static boolean paramHasTypeReferenceToTheAssociatedClassType(IASTParameterDeclaration dec, String name) { - boolean result= false; - IASTDeclarator pdtor= ASTQueries.findTypeRelevantDeclarator(dec.getDeclarator()); - if (pdtor != null && pdtor.getPointerOperators().length == 1 && - pdtor.getPointerOperators()[0] instanceof ICPPASTReferenceOperator && - pdtor.getParent() == dec && - dec.getDeclSpecifier() instanceof ICPPASTNamedTypeSpecifier) { - ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) dec.getDeclSpecifier(); - if (name == null || name.equals(nts.getName().getRawSignature())) { - result= true; + private boolean hasTypeReferenceToClassType(IASTParameterDeclaration dec) { + if (dec instanceof ICPPASTParameterDeclaration) { + IType t= CPPVisitor.createType((ICPPASTParameterDeclaration) dec, false); + if (t != null) { + t= SemanticUtil.getNestedType(t, TDEF); + if (t instanceof ICPPReferenceType) { + if (!((ICPPReferenceType) t).isRValueReference()) { + t= SemanticUtil.getNestedType(t, TDEF|REF|CVTYPE); + return classType.isSameType(t); + } + } } } - return result; + return false; } public boolean hasUserDeclaredConstructor() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index cda3df93d12..b52271bd506 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -1222,10 +1222,10 @@ public class CPPSemantics { // For index scopes the point of declaration is ignored. bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet); } - return expandUsingDeclarationsAndRemoveObjects(bindings, data.typesOnly); + return expandUsingDeclarationsAndRemoveObjects(bindings, data); } - private static IBinding[] expandUsingDeclarationsAndRemoveObjects(final IBinding[] bindings, boolean removeObjects) { + private static IBinding[] expandUsingDeclarationsAndRemoveObjects(final IBinding[] bindings, LookupData data) { if (bindings == null || bindings.length == 0) return IBinding.EMPTY_BINDING_ARRAY; @@ -1233,9 +1233,9 @@ public class CPPSemantics { if (b == null) break; - if (b instanceof ICPPUsingDeclaration || (removeObjects && isObject(b))) { + if (b instanceof ICPPUsingDeclaration || (data.typesOnly && isObject(b))) { List result= new ArrayList(bindings.length); - expandUsingDeclarations(bindings, removeObjects, result); + expandUsingDeclarations(bindings, data, result); return result.toArray(new IBinding[result.size()]); } } @@ -1246,18 +1246,21 @@ public class CPPSemantics { return !(b instanceof IType || b instanceof ICPPNamespace); } - private static void expandUsingDeclarations(IBinding[] bindings, boolean removeObjects, List result) { + private static void expandUsingDeclarations(IBinding[] bindings, LookupData data, List result) { if (bindings != null) { for (IBinding b : bindings) { if (b == null) return; + // Lookup for a declaration shall ignore the using declarations. if (b instanceof ICPPUsingDeclaration) { - for (IBinding d : ((ICPPUsingDeclaration) b).getDelegates()) { - if (d != null && !(removeObjects && isObject(d))) { - result.add(d); + if (data.forDeclaration() == null) { + for (IBinding d : ((ICPPUsingDeclaration) b).getDelegates()) { + if (d != null && !(data.typesOnly && isObject(d))) { + result.add(d); + } } } - } else if (!(removeObjects && isObject(b))) { + } else if (!(data.typesOnly && isObject(b))) { result.add(b); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 11f3deb5ed0..bdc7c70adcf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import java.util.ArrayList; import java.util.Collections; @@ -54,7 +55,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; @@ -91,7 +91,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; @@ -254,16 +253,18 @@ public class CPPTemplates { static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) { try { IScope scope; - ICPPASTFunctionDefinition func= CPPVisitor.findEnclosingFunctionDefinition(name); - if (func != null) { - name= ASTQueries.findInnermostDeclarator(func.getDeclarator()).getName().getLastName(); - scope= CPPVisitor.getContainingScope(name); - } else { - scope= CPPVisitor.getContainingScope(name); - if (!(scope instanceof IASTInternalScope)) - return null; + IASTNode node= name; + while (node != null) { + if (node.getPropertyInParent() == IASTFunctionDefinition.DECLARATOR) + break; + if (node instanceof IASTFunctionDefinition) { + name= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName(); + break; + } + node= node.getParent(); } - + + scope= CPPVisitor.getContainingScope(name); while (scope != null) { if (scope instanceof ISemanticProblem) return null; @@ -1231,12 +1232,12 @@ public class CPPTemplates { tdecl= getDirectlyEnclosingTemplateDeclaration(tdecl); } } - // not enough template declartaions + // not enough template declarations return null; } public static void associateTemplateDeclarations(ICPPASTInternalTemplateDeclaration tdecl) { - // find innermost template declaration + // Find innermost template declaration IASTDeclaration decl= tdecl.getDeclaration(); while (decl instanceof ICPPASTInternalTemplateDeclaration) { tdecl= (ICPPASTInternalTemplateDeclaration) decl; @@ -1244,111 +1245,119 @@ public class CPPTemplates { } final ICPPASTInternalTemplateDeclaration innerMostTDecl= tdecl; - // find name declared within the template declaration - IASTName name= getNameForDeclarationInTemplateDeclaration(decl); + // Find name declared within the template declaration + final IASTName declName= getNameForDeclarationInTemplateDeclaration(decl); - // count template declarations - int tdeclcount= 1; - IASTNode node= tdecl.getParent(); + // Count non-empty template declarations + int instDeclCount= 0; + int tdeclCount= 0; + IASTNode node= tdecl; while (node instanceof ICPPASTInternalTemplateDeclaration) { - tdeclcount++; tdecl = (ICPPASTInternalTemplateDeclaration) node; node= node.getParent(); + if (tdecl.getTemplateParameters().length == 0) { + instDeclCount++; + } else { + instDeclCount= 0; + } + tdeclCount++; } final ICPPASTInternalTemplateDeclaration outerMostTDecl= tdecl; + final int paramTDeclCount = tdeclCount-instDeclCount; - // determine association of names with template declarations + // Determine association of names with template declarations boolean lastIsTemplate= true; - int missingTemplateDecls= 0; - if (name instanceof ICPPASTQualifiedName) { - ICPPASTQualifiedName qname= (ICPPASTQualifiedName) name; - final IASTName lastName = qname.getLastName(); - final boolean lastIsID = lastName instanceof ICPPASTTemplateId; + int nestingLevel; + if (declName instanceof ICPPASTQualifiedName) { + ICPPASTQualifiedName qname= (ICPPASTQualifiedName) declName; - // count template-ids - int idcount= 0; + // Count dependent-ids + CharArraySet tparnames= collectTemplateParameterNames(outerMostTDecl); + int depIDCount= 0; + IASTName owner= null; final IASTName[] ns= qname.getNames(); - for (final IASTName n : ns) { + for (int i = 0; i < ns.length-1; i++) { + IASTName n= ns[i]; if (n instanceof ICPPASTTemplateId) { - idcount++; - } - } - - boolean isCtorWithTemplateID= false; - if (lastIsID && ns.length > 1) { - IASTName secondLastName= ns[ns.length-2]; - if (secondLastName instanceof ICPPASTTemplateId) { - final char[] lastNamesLookupKey = lastName.getLookupKey(); - if (CharArrayUtils.equals(lastNamesLookupKey, ((ICPPASTTemplateId) secondLastName).getLookupKey()) || - (lastNamesLookupKey.length > 0 && lastNamesLookupKey[0] == '~')) { - isCtorWithTemplateID= true; - idcount--; + if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) { + depIDCount++; } + } + if (depIDCount == 0) { + owner= n; } } - if (lastIsID && !isCtorWithTemplateID) { - missingTemplateDecls= idcount-tdeclcount; + if (qname.getLastName() instanceof ICPPASTTemplateId + || paramTDeclCount > depIDCount // not enough template ids + || ns.length < 2 // ::name + ) { + lastIsTemplate= true; + depIDCount++; } else { - missingTemplateDecls= idcount+1-tdeclcount; - if (missingTemplateDecls > 0) { - // last name is probably not a template - missingTemplateDecls--; - lastIsTemplate= false; - CharArraySet tparnames= collectTemplateParameterNames(outerMostTDecl); - int j= 0; - for (IASTName n : ns) { - if (n instanceof ICPPASTTemplateId) { - // if we find a dependent id, there can be no explicit specialization. - ICPPASTTemplateId id= (ICPPASTTemplateId) n; - if (usesTemplateParameter(id, tparnames)) - break; - - if (j++ == missingTemplateDecls) { - IBinding b= n.resolveBinding(); - if (b instanceof ICPPTemplateInstance && b instanceof ICPPClassType) { - if (((ICPPTemplateInstance) b).isExplicitSpecialization()) { - // For a template-id of an explicit specialization. - // we don't have a template declaration. (see 14.7.3.5) - missingTemplateDecls++; - lastIsTemplate= true; - } - } - break; - } - } + lastIsTemplate= false; + } + + nestingLevel= 0; + if (owner != null) { + int consumesTDecl= 0; + IBinding b= owner.resolveBinding(); + if (b instanceof IType) { + IType t= SemanticUtil.getNestedType((IType) b, TDEF); + if (t instanceof IBinding) + b= (IBinding) t; + } + while (b != null) { + if (b instanceof ICPPTemplateInstance) { + nestingLevel++; + if (!((ICPPTemplateInstance) b).isExplicitSpecialization()) + consumesTDecl++; + } else if (b instanceof ICPPClassTemplate || b instanceof ICPPClassTemplatePartialSpecialization) { + nestingLevel++; + consumesTDecl++; } + b= b.getOwner(); } - } - } - - if (missingTemplateDecls < 0) { - missingTemplateDecls= 0; // too many template declarations - } - - // determine nesting level of parent - int level= missingTemplateDecls; - if (!isFriendFunctionDeclaration(innerMostTDecl.getDeclaration())) { - node= outerMostTDecl.getParent(); - while (node != null) { - if (node instanceof ICPPASTInternalTemplateDeclaration) { - level+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; - break; + if (depIDCount > 0) { + nestingLevel+= depIDCount; + } else if (consumesTDecl < tdeclCount && !lastIsTemplate) { + nestingLevel++; + lastIsTemplate= true; } - node= node.getParent(); - } - } - - tdecl= outerMostTDecl; - while(true) { - tdecl.setNestingLevel((short) level++); - tdecl.setAssociatedWithLastName(false); - node= tdecl.getDeclaration(); - if (node instanceof ICPPASTInternalTemplateDeclaration) { - tdecl= (ICPPASTInternalTemplateDeclaration) node; } else { - break; + nestingLevel+= depIDCount; + node= outerMostTDecl.getParent(); + while (node != null) { + if (node instanceof ICPPASTInternalTemplateDeclaration) { + nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; + break; + } + node= node.getParent(); + } } + } else { + nestingLevel= 1; + lastIsTemplate= true; + if (!isFriendFunctionDeclaration(innerMostTDecl.getDeclaration())) { + node= outerMostTDecl.getParent(); + while (node != null) { + if (node instanceof ICPPASTInternalTemplateDeclaration) { + nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; + break; + } + node= node.getParent(); + } + } + } + + node= innerMostTDecl; + while(node instanceof ICPPASTInternalTemplateDeclaration) { + if (--nestingLevel < 0) + nestingLevel= 0; + tdecl= (ICPPASTInternalTemplateDeclaration) node; + tdecl.setNestingLevel((short) nestingLevel); + tdecl.setAssociatedWithLastName(false); + node= tdecl.getParent(); } innerMostTDecl.setAssociatedWithLastName(lastIsTemplate); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index dbe1fb318cc..571b28ac652 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -241,35 +241,8 @@ public class CPPVisitor extends ASTQueries { return CPPSemantics.resolveBinding(name); parent = parent.getParent(); - binding = CPPSemantics.resolveBinding(name); - if (binding instanceof IProblemBinding && !(parent instanceof ICPPASTNamespaceAlias)) { - final IASTName[] ns = qname.getNames(); - if (ns.length > 1 && ns[ns.length - 2].getBinding() instanceof IProblemBinding) - return binding; - - if (((IProblemBinding) binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND) { - IASTNode node = getContainingBlockItem(name.getParent()); - ASTNodeProperty prop= node.getPropertyInParent(); - while (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) { - node= node.getParent(); - prop= node.getPropertyInParent(); - } - if (prop != IASTCompositeTypeSpecifier.MEMBER_DECLARATION && - prop != ICPPASTNamespaceDefinition.OWNED_DECLARATION) { - return binding; - } - IScope scope= getContainingScope(qname); - while (scope instanceof ICPPTemplateScope) { - try { - scope= scope.getParent(); - } catch (DOMException e) { - return binding; - } - } - if (scope != getContainingScope(name)) - return binding; - } - } else { + if (!declaresMemberInClassOrNamespace(qname)) { + binding = CPPSemantics.resolveBinding(name); if (parent instanceof IASTCompositeTypeSpecifier) { if (binding instanceof IIndexBinding) { // Need to create an AST binding @@ -319,6 +292,52 @@ public class CPPVisitor extends ASTQueries { return null; } + private static boolean declaresMemberInClassOrNamespace(ICPPASTQualifiedName qname) { + IASTName[] names= qname.getNames(); + if (names.length < 2) + return false; + + IBinding pb= names[names.length-2].resolvePreBinding(); + if (pb instanceof IProblemBinding) + return false; + + IScope scope= null; + if (pb instanceof IType) { + IType t= SemanticUtil.getNestedType((IType) pb, TDEF); + if (t instanceof ICPPClassType) { + scope= ((ICPPClassType) t).getCompositeScope(); + } + } else if (pb instanceof ICPPNamespace) { + scope= ((ICPPNamespace)pb).getNamespaceScope(); + } + if (scope == null) + return false; + + IASTNode parent= qname.getParent(); + IASTNode decl= null; + if (parent instanceof IASTCompositeTypeSpecifier) { + decl= parent.getParent(); + } else if (parent instanceof IASTDeclarator) { + decl= ASTQueries.findOutermostDeclarator((IASTDeclarator) parent).getParent(); + } + while (decl != null) { + ASTNodeProperty prop = decl.getPropertyInParent(); + if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { + return scope == ((ICPPASTCompositeTypeSpecifier) decl.getParent()).getScope(); + } + if (prop == ICPPASTNamespaceDefinition.OWNED_DECLARATION) { + return scope == ((ICPPASTNamespaceDefinition) decl.getParent()).getScope(); + } + + if (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) { + decl= decl.getParent(); + } else { + return false; + } + } + return false; + } + private static IBinding createBinding(IASTGotoStatement gotoStatement) { ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope(gotoStatement.getName()); IASTName name = gotoStatement.getName(); @@ -801,21 +820,12 @@ public class CPPVisitor extends ASTQueries { } public static boolean isConstructor(IScope containingScope, IASTDeclarator declarator) { - if (containingScope == null || !(containingScope instanceof ICPPClassScope)) - return false; - - IASTNode node = ASTInternal.getPhysicalNodeOfScope(containingScope); - if (!(node instanceof ICPPASTCompositeTypeSpecifier)) { - return false; + if (containingScope instanceof ICPPClassScope && isConstructorDtor(declarator)) { + ICPPClassType classType= ((ICPPClassScope) containingScope).getClassType(); + final char[] dtorName = findInnermostDeclarator(declarator).getName().getLookupKey(); + return CharArrayUtils.equals(dtorName, classType.getNameCharArray()); } - - ICPPASTCompositeTypeSpecifier clsTypeSpec = (ICPPASTCompositeTypeSpecifier) node; - IASTName clsName = clsTypeSpec.getName(); - if (clsName instanceof ICPPASTQualifiedName) { - IASTName[] names = ((ICPPASTQualifiedName) clsName).getNames(); - clsName = names[names.length - 1]; - } - return isConstructor(clsName, declarator); + return false; } public static boolean isConstructorDeclaration(IASTName name) { @@ -836,35 +846,39 @@ public class CPPVisitor extends ASTQueries { parent= name.getParent(); } if (parent instanceof IASTDeclarator) { - IASTDeclarator dtor= findTypeRelevantDeclarator((IASTDeclarator) parent); - if (dtor instanceof ICPPASTFunctionDeclarator) { + if (isConstructorDtor((IASTDeclarator) parent)) { if (name instanceof ICPPASTQualifiedName) { IASTName[] names = ((ICPPASTQualifiedName) name).getNames(); if (names.length >= 2) { - return CPPVisitor.isConstructor(names[names.length - 2], dtor); - } - } else { - while (parent != null && !(parent instanceof ICPPASTCompositeTypeSpecifier)) { - parent= parent.getParent(); + IBinding b= names[names.length-2].resolvePreBinding(); + if (b instanceof IType) { + IType classType= getNestedType((IType) b, TDEF); + if (classType instanceof ICPPClassType) { + final char[] dtorName = names[names.length-1].getLookupKey(); + final char[] className = ((ICPPClassType) classType).getNameCharArray(); + return CharArrayUtils.equals(dtorName, className); + } + } } + return false; + } + while (parent != null) { if (parent instanceof ICPPASTCompositeTypeSpecifier) { - IASTName compName= ((ICPPASTCompositeTypeSpecifier) parent).getName().getLastName(); - return CPPVisitor.isConstructor(compName, dtor); + final char[] className= ((ICPPASTCompositeTypeSpecifier) parent).getName().getLastName().getLookupKey(); + final char[] dtorName = name.getLookupKey(); + return CharArrayUtils.equals(dtorName, className); } + parent= parent.getParent(); } } } return false; } - public static boolean isConstructor(IASTName parentName, IASTDeclarator declarator) { + private static boolean isConstructorDtor(IASTDeclarator declarator) { if (declarator == null || !(declarator instanceof IASTFunctionDeclarator)) return false; - IASTName name = findInnermostDeclarator(declarator).getName(); - if (!CharArrayUtils.equals(name.getLookupKey(), parentName.getLookupKey())) - return false; - IASTDeclSpecifier declSpec = null; IASTNode parent = findOutermostDeclarator(declarator).getParent(); if (parent instanceof IASTSimpleDeclaration) { @@ -877,7 +891,6 @@ public class CPPVisitor extends ASTQueries { } return false; - } public static IScope getContainingNonTemplateScope(final IASTNode inputNode) { @@ -1072,21 +1085,7 @@ public class CPPVisitor extends ASTQueries { } return null; } - - /** - * Returns enclosing function definition, or null if the given node - * is not part of a function definition. - */ - public static ICPPASTFunctionDefinition findEnclosingFunctionDefinition(IASTNode node) { - while (node != null) { - if (node instanceof ICPPASTFunctionDefinition) { - return (ICPPASTFunctionDefinition) node; - } - node= node.getParent(); - } - return null; - } - + public static IScope getContainingScope(IASTName name) { return getContainingScope(name, null); }