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 3ad314bd0fa..8b7058858c0 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 @@ -7713,4 +7713,39 @@ public class AST2TemplateTests extends AST2TestBase { ICPPField privateMemberVariable = bh.assertNonProblem("specializedPrivateVariable"); assertVisibility(ICPPClassType.v_private, aTemplateSpecialization.getVisibility(privateMemberVariable)); } + + // template + // class A { + // int defaultMemberVariable; + // public: + // int publicMemberVariable; + // protected: + // int protectedMemberVariable; + // private: + // int privateMemberVariable; + // }; + // + // void test(A* a) { + // a->defaultMemberVariable = 0; + // a->publicMemberVariable = 0; + // a->protectedMemberVariable = 0; + // a->privateMemberVariable = 0; + // } + public void testInstanceMemberAccessibility() throws Exception { + BindingAssertionHelper bh = getAssertionHelper(); + + ICPPClassType aTemplate = bh.assertNonProblem("A"); + + ICPPField defaultMemberVariable = bh.assertNonProblemOnFirstIdentifier("defaultMemberVariable ="); + assertVisibility(ICPPClassType.v_private, aTemplate.getVisibility(defaultMemberVariable)); + + ICPPField publicMemberVariable = bh.assertNonProblemOnFirstIdentifier("publicMemberVariable ="); + assertVisibility(ICPPClassType.v_public, aTemplate.getVisibility(publicMemberVariable)); + + ICPPField protectedMemberVariable = bh.assertNonProblemOnFirstIdentifier("protectedMemberVariable ="); + assertVisibility(ICPPClassType.v_protected, aTemplate.getVisibility(protectedMemberVariable)); + + ICPPField privateMemberVariable = bh.assertNonProblemOnFirstIdentifier("privateMemberVariable ="); + assertVisibility(ICPPClassType.v_private, aTemplate.getVisibility(privateMemberVariable)); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index b2cb6e9f2db..21a1b7b34bb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -15,7 +15,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; - import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; @@ -54,6 +53,7 @@ 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.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexName; @@ -905,12 +905,23 @@ public class ClassTypeHelper { if (backup != null) { return backup.getVisibility(member); } + if (classType instanceof ICPPClassSpecialization) { + // A class instance doesn't have a definition. Delegate to the class template. + ICPPClassType specialized = ((ICPPClassSpecialization) classType).getSpecializedBinding(); + if (!specialized.equals(member.getOwner())) { + if (!(member instanceof ICPPSpecialization)) + throw new IllegalArgumentException(member.getName() + " is not a member of " + specialized.getName()); //$NON-NLS-1$ + member = ((ICPPSpecialization) member).getSpecializedBinding(); + } + return specialized.getVisibility(member); + } + return ICPPClassType.v_public; // Fallback visibility } } - int visibility = - classType.getKey() == ICPPClassType.k_class ? ICPPClassType.v_private : ICPPClassType.v_public; + int visibility = classType.getKey() == ICPPClassType.k_class ? + ICPPClassType.v_private : ICPPClassType.v_public; IASTDeclaration[] hostMembers = classType.getCompositeTypeSpecifier().getMembers(); for (IASTDeclaration hostMember : hostMembers) {