Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2017-01-27 01:00:10 -0500
committerNathan Ridge2017-02-12 11:26:17 -0500
commitb2b1e17b379b6e7c9af9174cc7862382efeaec82 (patch)
tree83971090cf4f09e410741dd18f3e2b6a670aedd7
parenta0820d3efd61ee1d6240bdc1017677296267aefc (diff)
downloadorg.eclipse.cdt-b2b1e17b379b6e7c9af9174cc7862382efeaec82.tar.gz
org.eclipse.cdt-b2b1e17b379b6e7c9af9174cc7862382efeaec82.tar.xz
org.eclipse.cdt-b2b1e17b379b6e7c9af9174cc7862382efeaec82.zip
Bug 511122 - Instantiation of dependent destructor name
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java47
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java16
3 files changed, 73 insertions, 6 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
index c2ad03351a..6b846e33a3 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java
@@ -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();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
index db8b8407ba..79e4d7e5c6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java
@@ -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;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java
index 36c5bf8274..58bef145dd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java
@@ -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());

Back to the top