Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2012-01-16 09:28:11 -0500
committerMarkus Schorn2012-01-16 09:28:11 -0500
commit66f92bb58277c3cc845249c089b0bf28b9e0312e (patch)
tree11419c66087c1efbf4af5bb6525d1ffb87f7d521
parentb0d05b60ceb79d577858de138683adf07fb13987 (diff)
downloadorg.eclipse.cdt-66f92bb58277c3cc845249c089b0bf28b9e0312e.tar.gz
org.eclipse.cdt-66f92bb58277c3cc845249c089b0bf28b9e0312e.tar.xz
org.eclipse.cdt-66f92bb58277c3cc845249c089b0bf28b9e0312e.zip
Bug 368610: Specialization of classes used as template args
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java50
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java30
2 files changed, 73 insertions, 7 deletions
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 9d913dd1a9..57808cc766 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
@@ -5750,4 +5750,54 @@ public class AST2TemplateTests extends AST2BaseTest {
assertEquals("A<S>::iterator_t", ASTTypeUtil.getType(v.getType(), true));
parseAndCheckBindings();
}
+
+ // struct S {
+ // int x;
+ // };
+ // template <typename> struct iterator_base {
+ // S operator*();
+ // };
+ // template <typename> struct A {
+ // struct iterator : public iterator_base<iterator> {};
+ // };
+ // void test() {
+ // A<int>::iterator it;
+ // auto s = *it;
+ // s.x; // ERROR HERE: "Field 'x' could not be resolved"
+ // }
+ public void testSpecializationOfClassType_368610a() throws Exception {
+ parseAndCheckBindings();
+ }
+
+ // struct S {
+ // int x;
+ // };
+ // template <typename> struct iterator_base {
+ // S operator*();
+ // };
+ // template <typename> struct A {
+ // template<typename T> struct iterator : public iterator_base<iterator> {};
+ // };
+ // void test() {
+ // A<int>::iterator<int> it;
+ // auto s = *it;
+ // s.x; // ERROR HERE: "Field 'x' could not be resolved"
+ // }
+ public void testSpecializationOfClassType_368610b() throws Exception {
+ parseAndCheckBindings();
+ }
+
+ // template <template<typename T> class TT> struct CTT {
+ // int y;
+ // };
+ // template <typename T> struct CT {
+ // CTT<CT> someFunc();
+ // };
+ // void test2() {
+ // CT<int> x;
+ // x.someFunc().y;
+ // }
+ public void testSpecializationOfClassType_368610c() throws Exception {
+ parseAndCheckBindings();
+ }
}
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 4d6d2f36d9..8b514346c8 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
@@ -255,19 +255,23 @@ public class CPPTemplates {
static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) {
try {
- IScope scope;
+ IScope scope= null;
IASTNode node= name;
while (node != null) {
- if (node.getPropertyInParent() == IASTFunctionDefinition.DECLARATOR)
- break;
+ if (node.getPropertyInParent() == IASTCompositeTypeSpecifier.TYPE_NAME)
+ return null;
if (node instanceof IASTFunctionDefinition) {
name= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName();
+ scope= CPPVisitor.getContainingScope(name);
+ break;
+ }
+ if (node instanceof ICPPASTCompositeTypeSpecifier) {
+ scope= ((ICPPASTCompositeTypeSpecifier) node).getScope();
break;
}
node= node.getParent();
}
- scope= CPPVisitor.getContainingScope(name);
while (scope != null) {
if (scope instanceof ISemanticProblem)
return null;
@@ -1139,6 +1143,12 @@ public class CPPTemplates {
}
if (within != null && type instanceof IBinding) {
+ IType unwound= getNestedType(type, TDEF);
+ if (unwound instanceof ICPPClassType && unwound.isSameType(within.getSpecializedBinding())) {
+ // Convert (partial) class-templates (specializations) to the more specialized version.
+ if (within instanceof ICPPClassTemplate || !(unwound instanceof ICPPClassTemplate))
+ return within;
+ }
IBinding typeAsBinding= (IBinding) type;
IBinding owner= typeAsBinding.getOwner();
if (owner instanceof IType) {
@@ -1157,7 +1167,6 @@ public class CPPTemplates {
}
}
- IType unwound= getNestedType(type, TDEF);
if (unwound instanceof ICPPTemplateInstance && !(unwound instanceof ICPPDeferredClassInstance)) {
// Argument of a class specialization can be a nested class subject to specialization.
final ICPPTemplateInstance classInstance = (ICPPTemplateInstance) unwound;
@@ -2098,8 +2107,15 @@ public class CPPTemplates {
if (param instanceof ICPPTemplateTemplateParameter) {
IType t= arg.getTypeValue();
- if (!(t instanceof ICPPTemplateDefinition))
- return null;
+ while (!(t instanceof ICPPTemplateDefinition)) {
+ if (t instanceof ICPPClassSpecialization) {
+ // Undo the effect of specializing a template when the unqualified name
+ // is used within the template itself.
+ t= ((ICPPClassSpecialization) t).getSpecializedBinding();
+ } else {
+ return null;
+ }
+ }
ICPPTemplateParameter[] pParams = null;
ICPPTemplateParameter[] aParams = null;

Back to the top