1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 368610: Specialization of classes used as template args

This commit is contained in:
Markus Schorn 2012-01-16 15:28:11 +01:00
parent b0d05b60ce
commit 66f92bb582
2 changed files with 73 additions and 7 deletions

View file

@ -5750,4 +5750,54 @@ public class AST2TemplateTests extends AST2BaseTest {
assertEquals("A<S>::iterator_t", ASTTypeUtil.getType(v.getType(), true)); assertEquals("A<S>::iterator_t", ASTTypeUtil.getType(v.getType(), true));
parseAndCheckBindings(); 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();
}
} }

View file

@ -255,19 +255,23 @@ public class CPPTemplates {
static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) { static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) {
try { try {
IScope scope; IScope scope= null;
IASTNode node= name; IASTNode node= name;
while (node != null) { while (node != null) {
if (node.getPropertyInParent() == IASTFunctionDefinition.DECLARATOR) if (node.getPropertyInParent() == IASTCompositeTypeSpecifier.TYPE_NAME)
break; return null;
if (node instanceof IASTFunctionDefinition) { if (node instanceof IASTFunctionDefinition) {
name= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName(); name= ASTQueries.findInnermostDeclarator(((IASTFunctionDefinition) node).getDeclarator()).getName().getLastName();
scope= CPPVisitor.getContainingScope(name);
break;
}
if (node instanceof ICPPASTCompositeTypeSpecifier) {
scope= ((ICPPASTCompositeTypeSpecifier) node).getScope();
break; break;
} }
node= node.getParent(); node= node.getParent();
} }
scope= CPPVisitor.getContainingScope(name);
while (scope != null) { while (scope != null) {
if (scope instanceof ISemanticProblem) if (scope instanceof ISemanticProblem)
return null; return null;
@ -1139,6 +1143,12 @@ public class CPPTemplates {
} }
if (within != null && type instanceof IBinding) { 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 typeAsBinding= (IBinding) type;
IBinding owner= typeAsBinding.getOwner(); IBinding owner= typeAsBinding.getOwner();
if (owner instanceof IType) { if (owner instanceof IType) {
@ -1157,7 +1167,6 @@ public class CPPTemplates {
} }
} }
IType unwound= getNestedType(type, TDEF);
if (unwound instanceof ICPPTemplateInstance && !(unwound instanceof ICPPDeferredClassInstance)) { if (unwound instanceof ICPPTemplateInstance && !(unwound instanceof ICPPDeferredClassInstance)) {
// Argument of a class specialization can be a nested class subject to specialization. // Argument of a class specialization can be a nested class subject to specialization.
final ICPPTemplateInstance classInstance = (ICPPTemplateInstance) unwound; final ICPPTemplateInstance classInstance = (ICPPTemplateInstance) unwound;
@ -2098,8 +2107,15 @@ public class CPPTemplates {
if (param instanceof ICPPTemplateTemplateParameter) { if (param instanceof ICPPTemplateTemplateParameter) {
IType t= arg.getTypeValue(); IType t= arg.getTypeValue();
if (!(t instanceof ICPPTemplateDefinition)) while (!(t instanceof ICPPTemplateDefinition)) {
return null; 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[] pParams = null;
ICPPTemplateParameter[] aParams = null; ICPPTemplateParameter[] aParams = null;