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:
parent
b0d05b60ce
commit
66f92bb582
2 changed files with 73 additions and 7 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue