From 19db352cb98a7ae83f4e817dbf88fe93683bfe44 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Wed, 2 Oct 2013 12:17:43 -0700 Subject: [PATCH] Bug 418479 - IllegalArgumentException on template alias member of template class --- .../internal/core/model/CModelBuilder2.java | 5 +++++ .../parser/cpp/semantics/AccessContext.java | 18 +++++++++++++++- .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 3 +++ .../text/contentassist2/CompletionTests.java | 21 +++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java index 7504b29e517..8cd3f106297 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/CModelBuilder2.java @@ -48,6 +48,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; 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.cpp.ICPPASTAliasDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; @@ -333,6 +334,8 @@ public class CModelBuilder2 implements IContributedModelBuilder { // TODO [cmodel] template specialization? } else if (declaration instanceof ICPPASTExplicitTemplateInstantiation) { // TODO [cmodel] explicit template instantiation? + } else if (declaration instanceof ICPPASTAliasDeclaration) { + // TODO [cmodel] alias declaration? } else if (declaration instanceof ICPPASTUsingDeclaration) { createUsingDeclaration(parent, (ICPPASTUsingDeclaration) declaration); } else if (declaration instanceof ICPPASTUsingDirective) { @@ -399,6 +402,8 @@ public class CModelBuilder2 implements IContributedModelBuilder { setBodyPosition((SourceManipulation)element, templateDeclaration); } } + } else if (declaration instanceof ICPPASTAliasDeclaration) { + createDeclaration(parent, declaration); } else if (declaration instanceof ICPPASTTemplateDeclaration) { // strange: template decl inside template decl createTemplateDeclaration(parent, (ICPPASTTemplateDeclaration) declaration); 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 3793c5aae5e..22b8d3be778 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 @@ -17,13 +17,17 @@ import org.eclipse.cdt.core.dom.ast.IASTName; 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.cpp.ICPPAliasTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; 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; @@ -88,6 +92,16 @@ public class AccessContext { if (binding instanceof ICPPMember) { bindingVisibility = ((ICPPMember) binding).getVisibility(); } else { + while (binding instanceof ICPPSpecialization) { + binding = ((ICPPSpecialization) binding).getSpecializedBinding(); + } + if (binding instanceof ICPPClassTemplatePartialSpecialization) { + // A class template partial specialization inherits the visibility of its primary class template. + binding = ((ICPPClassTemplatePartialSpecialization) binding).getPrimaryClassTemplate(); + } + if (binding instanceof ICPPAliasTemplateInstance) { + binding = ((ICPPAliasTemplateInstance) binding).getTemplateDefinition(); + } IBinding owner = binding.getOwner(); if (owner instanceof ICPPClassType) { bindingVisibility = ((ICPPClassType) owner).getVisibility(binding); @@ -152,7 +166,9 @@ public class AccessContext { return false; accessLevel = getMemberAccessLevel(derivedClass, accessLevel); - if (owner.isSameType(derivedClass)) { + if (owner.isSameType(derivedClass) || + (derivedClass instanceof ICPPClassSpecialization && + owner.equals(((ICPPClassSpecialization) derivedClass).getSpecializedBinding()))) { return isAccessible(bindingVisibility, accessLevel); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 63fc781e11c..670467a1336 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -519,6 +519,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { if (binding instanceof ICPPClassTemplatePartialSpecialization) { // A class template partial specialization inherits the visibility of its primary class template. binding = ((ICPPClassTemplatePartialSpecialization) binding).getPrimaryClassTemplate(); + } + if (binding instanceof ICPPAliasTemplateInstance) { + binding = ((ICPPAliasTemplateInstance) binding).getTemplateDefinition(); } if (binding instanceof CPPImplicitMethod) return ICPPClassType.v_public; 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 fb022813803..967333ca142 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 @@ -659,6 +659,27 @@ public class CompletionTests extends AbstractContentAssistTest { assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_ID_STRINGS); } + // struct A {}; + // + // template + // struct B {}; + // + // template + // struct C { + // using D = U; + // + // template + // using E = B; + // }; + // + // void test() { + // C::/*cursor*/ + // } + public void testAliasTemplate_418479() throws Exception { + final String[] expected = { "D", "E" }; + assertContentAssistResults(fCursorOffset, expected, true, COMPARE_ID_STRINGS); + } + //using namespace ns;void gfunc(){NSC/*cursor*/ public void testUsingDirective() throws Exception { final String[] expected= { "NSCONST" };