mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-19 15:05:36 +02:00
Bug 511122 - Instantiation of dependent destructor name
Change-Id: I090439b6c525cae3bf054f65f67190811232d64c
This commit is contained in:
parent
a0820d3efd
commit
b2b1e17b37
3 changed files with 73 additions and 6 deletions
|
@ -9961,4 +9961,20 @@ public class AST2TemplateTests extends AST2TestBase {
|
||||||
public void testNoexceptSpecifierInTypeTemplateArgument_511186() throws Exception {
|
public void testNoexceptSpecifierInTypeTemplateArgument_511186() throws Exception {
|
||||||
parseAndCheckBindings();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3163,4 +3163,51 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
return exec;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,6 +346,9 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
if (templateArgs != null) {
|
if (templateArgs != null) {
|
||||||
templateArgs = instantiateArguments(templateArgs, context, false);
|
templateArgs = instantiateArguments(templateArgs, context, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char[] name = fName;
|
||||||
|
name = CPPTemplates.instantiateName(name, context, getTemplateDefinition());
|
||||||
|
|
||||||
ICPPEvaluation fieldOwner = fFieldOwner;
|
ICPPEvaluation fieldOwner = fFieldOwner;
|
||||||
if (fieldOwner != null) {
|
if (fieldOwner != null) {
|
||||||
|
@ -372,7 +375,7 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
|
|
||||||
boolean nameOwnerStillDependent = false;
|
boolean nameOwnerStillDependent = false;
|
||||||
if (nameOwner instanceof ICPPClassType) {
|
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)
|
if (eval != null)
|
||||||
return eval;
|
return eval;
|
||||||
if (CPPTemplates.isDependentType((ICPPClassType) nameOwner)) {
|
if (CPPTemplates.isDependentType((ICPPClassType) nameOwner)) {
|
||||||
|
@ -395,7 +398,8 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
IType fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF);
|
IType fieldOwnerClassTypeCV = SemanticUtil.getNestedType(fieldOwnerType, TDEF | REF);
|
||||||
IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE);
|
IType fieldOwnerClassType = SemanticUtil.getNestedType(fieldOwnerClassTypeCV, CVTYPE);
|
||||||
if (fieldOwnerClassType instanceof ICPPClassType) {
|
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)
|
if (eval != null)
|
||||||
return eval;
|
return eval;
|
||||||
if (!CPPTemplates.isDependentType(fieldOwnerClassType))
|
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());
|
getTemplateDefinition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,9 +424,9 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
return newEvalID;
|
return newEvalID;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPEvaluation ownerEval, ICPPTemplateArgument[] templateArgs,
|
private ICPPEvaluation resolveName(char[] name, ICPPClassType nameOwner, ICPPEvaluation ownerEval,
|
||||||
IType impliedObjectType, IASTNode point) {
|
ICPPTemplateArgument[] templateArgs, IType impliedObjectType, IASTNode point) {
|
||||||
LookupData data = new LookupData(fName, templateArgs, point);
|
LookupData data = new LookupData(name, templateArgs, point);
|
||||||
data.qualified = fQualified;
|
data.qualified = fQualified;
|
||||||
try {
|
try {
|
||||||
CPPSemantics.lookup(data, nameOwner.getCompositeScope());
|
CPPSemantics.lookup(data, nameOwner.getCompositeScope());
|
||||||
|
|
Loading…
Add table
Reference in a new issue