diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java index 4b111b51fa8..ae20e9dc72e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -33,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; /** * The context that determines access to private and protected class members. @@ -236,6 +238,9 @@ public class AccessContext { if (bases != null) { for (ICPPBase base : bases) { IBinding baseClass = base.getBaseClass(); + if (baseClass instanceof ICPPDeferredClassInstance) { + baseClass = ((ICPPDeferredClassInstance) baseClass).getTemplateDefinition(); + } if (!(baseClass instanceof ICPPClassType)) { continue; } @@ -254,9 +259,16 @@ public class AccessContext { LookupData data = new LookupData(name); isUnqualifiedLookup= !data.qualified; - ICPPScope scope= CPPSemantics.getLookupScope(name); + ICPPScope scope = CPPSemantics.getLookupScope(name); while (scope != null && !(scope instanceof ICPPClassScope)) { - scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit()); + if (scope instanceof ICPPInternalUnknownScope) { + IType scopeType = ((ICPPInternalUnknownScope) scope).getScopeType(); + if (scopeType instanceof ICPPDeferredClassInstance) { + return ((ICPPDeferredClassInstance) scopeType).getClassTemplate(); + } + } else { + scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit()); + } } if (scope instanceof ICPPClassScope) { return ((ICPPClassScope) scope).getClassType(); 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 d6663d6a837..4c94e10651b 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 @@ -743,7 +743,7 @@ public class CompletionTests extends AbstractContentAssistTest { // using TParam = T; // }; // }; - // + // // struct NestingTest: Parent { // struct A : Nested { // TP/*cursor*/ @@ -754,6 +754,24 @@ public class CompletionTests extends AbstractContentAssistTest { assertCompletionResults(fCursorOffset, expected, ID); } + // template + // class Parent { + // struct NestedHidden {}; + // protected: + // struct NestedProtected {}; + // public: + // struct NestedPublic {}; + // }; + // + // template + // class NestingTest: Parent { + // Parent::/*cursor*/ + // }; + public void testNestedBaseTemplateMembersFromUnknownScope_456752() throws Exception { + final String[] expected = { "NestedProtected", "NestedPublic" }; + assertCompletionResults(fCursorOffset, expected, ID); + } + // struct A {}; // // template