diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java index 7c155a08974..b04a84a8b1f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java @@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.model.IEnumeration; import org.eclipse.cdt.core.parser.Keywords; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -378,19 +379,21 @@ public class CPPASTQualifiedName extends CPPASTNameBase return false; } - private List filterClassScopeBindings(ICPPClassType classType, - IBinding[] bindings, final boolean isDeclaration) { + private List filterClassScopeBindings(ICPPClassType classType, IBinding[] bindings, + final boolean isDeclaration) { List filtered = new ArrayList(); - final boolean canBeFieldAccess= canBeFieldAccess(classType); + final boolean canBeFieldAccess = canBeFieldAccess(classType); + final IBinding templateDefinition = (classType instanceof ICPPTemplateInstance) + ? ((ICPPTemplateInstance) classType).getTemplateDefinition() : null; for (final IBinding binding : bindings) { if (binding instanceof IField) { IField field = (IField) binding; - if (!canBeFieldAccess && !field.isStatic()) + if (!canBeFieldAccess && !field.isStatic()) continue; } else if (binding instanceof ICPPMethod) { ICPPMethod method = (ICPPMethod) binding; - if (method.isImplicit()) + if (method.isImplicit()) continue; if (!isDeclaration) { if (method.isDestructor() || method instanceof ICPPConstructor @@ -400,14 +403,17 @@ public class CPPASTQualifiedName extends CPPASTNameBase } else if (binding instanceof IEnumerator || binding instanceof IEnumeration) { if (isDeclaration) continue; + } else if (templateDefinition == binding) { + // This solves bug 456101 (template instance refering to itself). + // A:: should not get a binding to its own template definition. + continue; } else if (binding instanceof IType) { - IType type = (IType) binding; - if (type.isSameType(classType)) + if (classType.isSameType((IType) binding)) continue; - } + } filtered.add(binding); } - + return filtered; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 8a42fb8cdb5..a2ee3172027 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -154,6 +154,7 @@ public class CompletionTests extends AbstractContentAssistTest { // T add(T tOther) { // return fTField + tOther; // } + // class NestedClass{}; // }; // // bug 109480 // class Printer @@ -1442,6 +1443,32 @@ public class CompletionTests extends AbstractContentAssistTest { assertContentAssistResults(fCursorOffset, expected, true, DISPLAY); } + // template + // struct TestTemplate { + // class NestedClass {}; + // }; + // template + // struct TestTemplate { + // class NestedClass {}; + // }; + // template<> + // struct TestTemplate { + // class NestedClass {}; + // }; + // template + // class TestTemplateSelfReference : TestTemplate::/*cursor*/ + public void testTemplateSelfReference_bug456101() throws Exception { + final String[] expected = { "NestedClass" }; + assertContentAssistResults(fCursorOffset, expected, true, DISPLAY); + } + + // template + // class TestTemplateSelfReference : TClass::/*cursor*/ + public void testTemplateSelfReferencePDOM_bug456101() throws Exception { + final String[] expected = { "NestedClass" }; + assertContentAssistResults(fCursorOffset, expected, true, DISPLAY); + } + // namespace N { // void foo(int); // }