mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
237622: template parameter resolution in chain initialiser - apply fix and add tests
This commit is contained in:
parent
e4b026c274
commit
ddca2b93d1
4 changed files with 129 additions and 11 deletions
|
@ -2880,4 +2880,64 @@ public class AST2TemplateTests extends AST2BaseTest {
|
||||||
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
ba.assertProblem("A<int>", 6);
|
ba.assertProblem("A<int>", 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<int I>
|
||||||
|
// class That {
|
||||||
|
// public:
|
||||||
|
// That(int x) {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template<int T>
|
||||||
|
// class This : public That<T> {
|
||||||
|
// public:
|
||||||
|
// inline This();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <int I>
|
||||||
|
// inline This<I>::This() : That<I>(I) {
|
||||||
|
// }
|
||||||
|
public void testParameterReferenceInChainInitializer_a() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
|
||||||
|
// These intermediate assertions will not hold until deferred non-type arguments are
|
||||||
|
// correctly modelled
|
||||||
|
/*
|
||||||
|
ICPPClassType tid= ba.assertNonProblem("This<I>::T", 7, ICPPClassType.class);
|
||||||
|
assertFalse(tid instanceof ICPPSpecialization);
|
||||||
|
ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class);
|
||||||
|
assertFalse(th1sCtor instanceof ICPPSpecialization);ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
|
*/
|
||||||
|
|
||||||
|
ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I>(I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
|
ICPPClassType clazz= ba.assertNonProblem("That<I>(I)", 4, ICPPClassType.class);
|
||||||
|
ICPPConstructor ctor= ba.assertNonProblem("That<I>(I)", 7, ICPPConstructor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template<typename I>
|
||||||
|
// class That {
|
||||||
|
// public:
|
||||||
|
// That() {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template<typename T>
|
||||||
|
// class This : public That<T> {
|
||||||
|
// public:
|
||||||
|
// inline This();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template <typename I>
|
||||||
|
// inline This<I>::This() : That<I>() {
|
||||||
|
// }
|
||||||
|
public void testParameterReferenceInChainInitializer_b() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
|
||||||
|
ICPPClassType tid= ba.assertNonProblem("This<I>::T", 7, ICPPClassType.class);
|
||||||
|
assertFalse(tid instanceof ICPPSpecialization);
|
||||||
|
ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class);
|
||||||
|
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||||
|
|
||||||
|
ICPPTemplateTypeParameter np= ba.assertNonProblem("I>()", 1, ICPPTemplateTypeParameter.class);
|
||||||
|
ICPPClassType clazz= ba.assertNonProblem("That<I>()", 4, ICPPClassType.class);
|
||||||
|
ICPPConstructor ctor= ba.assertNonProblem("That<I>()", 7, ICPPConstructor.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1374,4 +1374,60 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
||||||
assertTrue(!a1.isSameType(a5c));
|
assertTrue(!a1.isSameType(a5c));
|
||||||
assertTrue(!a1.isSameType(a5d));
|
assertTrue(!a1.isSameType(a5d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template<int I>
|
||||||
|
// class That {
|
||||||
|
// public:
|
||||||
|
// That(int x) {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template<int T>
|
||||||
|
// class This : public That<T> {
|
||||||
|
// public:
|
||||||
|
// inline This();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// template <int I>
|
||||||
|
// inline This<I>::This() : That<I>(I) {
|
||||||
|
// }
|
||||||
|
public void testParameterReferenceInChainInitializer_a() throws Exception {
|
||||||
|
// These intermediate assertions will not hold until deferred non-type arguments are
|
||||||
|
// correctly modelled
|
||||||
|
/*
|
||||||
|
ICPPClassType tid= ba.assertNonProblem("This<I>::T", 7, ICPPClassType.class);
|
||||||
|
assertFalse(tid instanceof ICPPSpecialization);
|
||||||
|
ICPPConstructor th1sCtor= ba.assertNonProblem("This() :", 4, ICPPConstructor.class);
|
||||||
|
assertFalse(th1sCtor instanceof ICPPSpecialization);ICPPTemplateNonTypeParameter np= ba.assertNonProblem("I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
|
*/
|
||||||
|
|
||||||
|
ICPPTemplateNonTypeParameter np= getBindingFromASTName("I>(I)", 1, ICPPTemplateNonTypeParameter.class);
|
||||||
|
ICPPClassType clazz= getBindingFromASTName("That<I>(I)", 4, ICPPClassType.class);
|
||||||
|
ICPPConstructor ctor= getBindingFromASTName("That<I>(I)", 7, ICPPConstructor.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// template<typename I>
|
||||||
|
// class That {
|
||||||
|
// public:
|
||||||
|
// That() {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// template<typename T>
|
||||||
|
// class This : public That<T> {
|
||||||
|
// public:
|
||||||
|
// inline This();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// template <typename I>
|
||||||
|
// inline This<I>::This() : That<I>() {
|
||||||
|
// }
|
||||||
|
public void testParameterReferenceInChainInitializer_b() throws Exception {
|
||||||
|
ICPPClassType tid= getBindingFromASTName("This<I>::T", 7, ICPPClassType.class);
|
||||||
|
assertFalse(tid instanceof ICPPSpecialization);
|
||||||
|
ICPPConstructor th1sCtor= getBindingFromASTName("This() :", 4, ICPPConstructor.class);
|
||||||
|
assertFalse(th1sCtor instanceof ICPPSpecialization);
|
||||||
|
|
||||||
|
ICPPTemplateTypeParameter np= getBindingFromASTName("I>()", 1, ICPPTemplateTypeParameter.class);
|
||||||
|
ICPPClassType clazz= getBindingFromASTName("That<I>()", 4, ICPPClassType.class);
|
||||||
|
ICPPConstructor ctor= getBindingFromASTName("That<I>()", 7, ICPPConstructor.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,7 +167,8 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
|
||||||
|
|
||||||
public IBinding resolveTemplateParameter(ICPPASTTemplateParameter templateParameter) {
|
public IBinding resolveTemplateParameter(ICPPASTTemplateParameter templateParameter) {
|
||||||
IASTName name = CPPTemplates.getTemplateParameterName(templateParameter);
|
IASTName name = CPPTemplates.getTemplateParameterName(templateParameter);
|
||||||
IBinding binding = name.getBinding();
|
IASTName preferredName= name;
|
||||||
|
IBinding binding = name.getBinding();
|
||||||
if (binding != null)
|
if (binding != null)
|
||||||
return binding;
|
return binding;
|
||||||
|
|
||||||
|
@ -186,6 +187,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
|
||||||
ICPPASTTemplateParameter[] params = temp.getTemplateParameters();
|
ICPPASTTemplateParameter[] params = temp.getTemplateParameters();
|
||||||
if (params.length > i) {
|
if (params.length > i) {
|
||||||
IASTName paramName = CPPTemplates.getTemplateParameterName(params[i]);
|
IASTName paramName = CPPTemplates.getTemplateParameterName(params[i]);
|
||||||
|
preferredName= paramName;
|
||||||
if (paramName.getBinding() != null) {
|
if (paramName.getBinding() != null) {
|
||||||
binding = paramName.getBinding();
|
binding = paramName.getBinding();
|
||||||
name.setBinding(binding);
|
name.setBinding(binding);
|
||||||
|
@ -197,11 +199,11 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC
|
||||||
}
|
}
|
||||||
//create a new binding and set it for the corresponding parameter in all known decls
|
//create a new binding and set it for the corresponding parameter in all known decls
|
||||||
if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) {
|
if (templateParameter instanceof ICPPASTSimpleTypeTemplateParameter) {
|
||||||
binding = new CPPTemplateTypeParameter(name);
|
binding = new CPPTemplateTypeParameter(preferredName);
|
||||||
} else if (templateParameter instanceof ICPPASTParameterDeclaration) {
|
} else if (templateParameter instanceof ICPPASTParameterDeclaration) {
|
||||||
binding = new CPPTemplateNonTypeParameter(name);
|
binding = new CPPTemplateNonTypeParameter(preferredName);
|
||||||
} else {
|
} else {
|
||||||
binding = new CPPTemplateTemplateParameter(name);
|
binding = new CPPTemplateTemplateParameter(preferredName);
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = (declarations != null) ? declarations.length : 0;
|
int length = (declarations != null) ? declarations.length : 0;
|
||||||
|
|
|
@ -283,7 +283,7 @@ public class CPPSemantics {
|
||||||
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
|
ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName;
|
||||||
IType[] args = CPPTemplates.createTemplateArgumentArray(id);
|
IType[] args = CPPTemplates.createTemplateArgumentArray(id);
|
||||||
IBinding inst = ((ICPPInternalTemplateInstantiator)cls).instantiate(args);
|
IBinding inst = ((ICPPInternalTemplateInstantiator)cls).instantiate(args);
|
||||||
cls = inst instanceof ICPPClassType ? (ICPPClassType)inst : cls;
|
cls = inst instanceof ICPPClassType && !(inst instanceof ICPPDeferredTemplateInstance) ? (ICPPClassType)inst : cls;
|
||||||
}
|
}
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
try {
|
try {
|
||||||
|
@ -736,13 +736,13 @@ public class CPPSemantics {
|
||||||
|
|
||||||
ICPPScope parentScope = (ICPPScope) getParentScope(scope, data.tu);
|
ICPPScope parentScope = (ICPPScope) getParentScope(scope, data.tu);
|
||||||
if (parentScope instanceof ICPPTemplateScope) {
|
if (parentScope instanceof ICPPTemplateScope) {
|
||||||
IASTNode parent = node.getParent();
|
IASTNode declNode = node;
|
||||||
while (parent != null && !(parent instanceof ICPPASTTemplateDeclaration)) {
|
while (declNode != null && !(declNode instanceof ICPPASTTemplateDeclaration)) {
|
||||||
node = parent;
|
node = declNode;
|
||||||
parent = parent.getParent();
|
declNode = declNode.getParent();
|
||||||
}
|
}
|
||||||
if (parent != null) {
|
if (declNode != null) {
|
||||||
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) parent;
|
ICPPASTTemplateDeclaration templateDecl = (ICPPASTTemplateDeclaration) declNode;
|
||||||
ICPPTemplateScope templateScope = templateDecl.getScope();
|
ICPPTemplateScope templateScope = templateDecl.getScope();
|
||||||
if (templateScope.getTemplateDefinition() == ((ICPPTemplateScope)parentScope).getTemplateDefinition()) {
|
if (templateScope.getTemplateDefinition() == ((ICPPTemplateScope)parentScope).getTemplateDefinition()) {
|
||||||
parentScope = templateScope;
|
parentScope = templateScope;
|
||||||
|
|
Loading…
Add table
Reference in a new issue