1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-19 06:55:23 +02:00

Bug 511122 - Instantiation of dependent destructor name

Change-Id: I090439b6c525cae3bf054f65f67190811232d64c
This commit is contained in:
Nathan Ridge 2017-01-27 01:00:10 -05:00
parent a0820d3efd
commit b2b1e17b37
3 changed files with 73 additions and 6 deletions

View file

@ -9961,4 +9961,20 @@ public class AST2TemplateTests extends AST2TestBase {
public void testNoexceptSpecifierInTypeTemplateArgument_511186() throws Exception {
parseAndCheckBindings();
}
// class C {};
// typedef C D;
//
// template <typename T, typename = decltype(T().~T())>
// void test();
//
// void foo() {
// test<C>();
// test<const C>();
// test<D>();
// test<const D>();
// }
public void testDependentDestructorName_511122() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -3163,4 +3163,51 @@ public class CPPTemplates {
}
return exec;
}
/**
* Instantiate a plain name (simple-id).
* Only destructor names require instantiation, e.g. the name "~T", when instantiated
* with a parameter map that maps T to C, needs to become "~C".
*
* @param name the name to be instantiated
* @param context the instantiation context
* @param enclosingTemplate The enclosing template definition. This is required because the
* instantiation context doesn't actually store parameter names, so
* we need to walk the chain of enclosing templates to find potential
* template parameter names.
* @return The instantiated name. If the provided name is not a destructor name, or if
* the type named by the destructor name is not mapped to anything in the
* instantiation context's parameter map, the provided name is returned unchanged.
*/
public static char[] instantiateName(char[] name, InstantiationContext context, IBinding enclosingTemplate) {
if (name == null || name.length == 0 || name[0] != '~') {
return name;
}
String typename = new String(name).substring(1);
ICPPTemplateParameterMap map = context.getParameterMap();
IBinding enclosing = enclosingTemplate;
while (enclosing != null) {
if (enclosing instanceof ICPPTemplateDefinition) {
for (ICPPTemplateParameter param : ((ICPPTemplateDefinition) enclosing).getTemplateParameters()) {
if (param instanceof ICPPTemplateTypeParameter) {
if (param.getName().equals(typename)) {
ICPPTemplateArgument arg = map.getArgument(param);
if (arg instanceof CPPTemplateTypeArgument) {
IType argType = arg.getTypeValue();
argType = SemanticUtil.getNestedType(argType, CVTYPE | TDEF);
if (argType instanceof ICPPClassType) {
StringBuilder result = new StringBuilder();
result.append('~');
result.append(((ICPPClassType) argType).getName());
return result.toString().toCharArray();
}
}
}
}
}
}
enclosing = enclosing.getOwner();
}
return name;
}
}

View file

@ -346,6 +346,9 @@ public class EvalID extends CPPDependentEvaluation {
if (templateArgs != null) {
templateArgs = instantiateArguments(templateArgs, context, false);
}
char[] name = fName;
name = CPPTemplates.instantiateName(name, context, getTemplateDefinition());
ICPPEvaluation fieldOwner = fFieldOwner;
if (fieldOwner != null) {
@ -372,7 +375,7 @@ public class EvalID extends CPPDependentEvaluation {
boolean nameOwnerStillDependent = false;
if (nameOwner instanceof ICPPClassType) {
ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, null, templateArgs, null, context.getPoint());
ICPPEvaluation eval = resolveName(name, (ICPPClassType) nameOwner, null, templateArgs, null, context.getPoint());
if (eval != null)
return eval;
if (CPPTemplates.isDependentType((ICPPClassType) nameOwner)) {
@ -395,7 +398,8 @@ public class EvalID extends CPPDependentEvaluation {
IType fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF);
IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE);
if (fieldOwnerClassType instanceof ICPPClassType) {
ICPPEvaluation eval = resolveName((ICPPClassType) fieldOwnerClassType, fieldOwner, templateArgs, fieldOwnerClassTypeCV, context.getPoint());
ICPPEvaluation eval = resolveName(name, (ICPPClassType) fieldOwnerClassType, fieldOwner,
templateArgs, fieldOwnerClassTypeCV, context.getPoint());
if (eval != null)
return eval;
if (!CPPTemplates.isDependentType(fieldOwnerClassType))
@ -403,7 +407,7 @@ public class EvalID extends CPPDependentEvaluation {
}
}
return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, fIsPointerDeref, templateArgs,
return new EvalID(fieldOwner, nameOwner, name, fAddressOf, fQualified, fIsPointerDeref, templateArgs,
getTemplateDefinition());
}
@ -420,9 +424,9 @@ public class EvalID extends CPPDependentEvaluation {
return newEvalID;
}
private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPEvaluation ownerEval, ICPPTemplateArgument[] templateArgs,
IType impliedObjectType, IASTNode point) {
LookupData data = new LookupData(fName, templateArgs, point);
private ICPPEvaluation resolveName(char[] name, ICPPClassType nameOwner, ICPPEvaluation ownerEval,
ICPPTemplateArgument[] templateArgs, IType impliedObjectType, IASTNode point) {
LookupData data = new LookupData(name, templateArgs, point);
data.qualified = fQualified;
try {
CPPSemantics.lookup(data, nameOwner.getCompositeScope());