summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVlad Ivanov2018-05-11 02:54:09 -0400
committerNathan Ridge2018-05-17 19:57:08 -0400
commit809aa570760680a4953f337d892ebe1b5c93d9da (patch)
tree714116f6a3abb8dc6720d0fd24d3f5401e9165d8
parentc16a31325b7c3ccce815f68aaec94bfae8177f65 (diff)
downloadorg.eclipse.cdt-809aa570760680a4953f337d892ebe1b5c93d9da.tar.gz
org.eclipse.cdt-809aa570760680a4953f337d892ebe1b5c93d9da.tar.xz
org.eclipse.cdt-809aa570760680a4953f337d892ebe1b5c93d9da.zip
Bug 519361: wrap template<auto> types for better type resolution
https://bugs.eclipse.org/bugs/show_bug.cgi?id=519361#c28 Change-Id: I0a2f5479bb853ca26156be5b22673abdc158efab Signed-off-by: Vlad Ivanov <vlad@ivanov.email>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoIndexTests.java50
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoTests.java25
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java4
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java7
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java18
6 files changed, 112 insertions, 3 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoIndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoIndexTests.java
new file mode 100644
index 0000000000..f3c8a7874e
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoIndexTests.java
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2018 Vlad Ivanov
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Vlad Ivanov (LabSystems) - Initial implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.parser.tests.ast2.cxx17;
+
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.IVariable;
+import org.eclipse.cdt.internal.index.tests.IndexBindingResolutionTestBase;
+
+public class TemplateAutoIndexTests extends IndexBindingResolutionTestBase {
+ public TemplateAutoIndexTests() {
+ setStrategy(new SinglePDOMTestStrategy(true));
+ }
+
+ // template<typename Type, Type v>
+ // struct helper {
+ // static Type call() {
+ // return nullptr;
+ // }
+ // };
+ //
+ // template<auto F>
+ // class call_helper {
+ // using functor_t = decltype(F);
+ //
+ // public:
+ // using type = helper<functor_t, F>;
+ // };
+
+ // struct Something {
+ // void foo() {}
+ // };
+ //
+ // using A = call_helper<&Something::foo>::type;
+ // auto waldo = A::call();
+ public void testTemplateAutoIndex() throws Exception {
+ BindingAssertionHelper helper = getAssertionHelper();
+ IVariable variable = helper.assertNonProblem("waldo");
+ IType variableType = variable.getType();
+
+ assertEquals("void (Something::*)()", variableType.toString());
+ }
+}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoTests.java
index 920fb2d90f..8675beca3c 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx17/TemplateAutoTests.java
@@ -47,4 +47,29 @@ public class TemplateAutoTests extends AST2CPPTestBase {
public void testTemplateNontypeParameterTypeDeductionParsing_519361_2() throws Exception {
parseAndCheckBindings();
}
+
+ // template<typename Type, Type v>
+ // struct helper {
+ // static void call() {}
+ // };
+ //
+ // template<auto F>
+ // class call_helper {
+ // using functor_t = decltype(F);
+ //
+ // public:
+ // using type = helper<functor_t, F>;
+ // };
+ //
+ // struct Something {
+ // void foo() {}
+ // };
+ //
+ // void test() {
+ // using A = call_helper<&Something::foo>::type;
+ // A::call();
+ // }
+ public void testTemplateNontypeParameterTypeDeductionParsing_519361_3() throws Exception {
+ parseAndCheckBindings();
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
index 48ba4c3deb..e9d21a51c2 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexTests.java
@@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.index.tests;
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.GenericLambdaIndexTests;
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.ReturnTypeDeductionIndexTests;
+import org.eclipse.cdt.core.parser.tests.ast2.cxx17.TemplateAutoIndexTests;
import junit.framework.Test;
import junit.framework.TestSuite;
@@ -42,6 +43,9 @@ public class IndexTests extends TestSuite {
suite.addTestSuite(ReturnTypeDeductionIndexTests.class);
suite.addTestSuite(GenericLambdaIndexTests.class);
+ // C++17 index test suites
+ suite.addTestSuite(TemplateAutoIndexTests.class);
+
IndexCPPBindingResolutionBugs.addTests(suite);
IndexCPPBindingResolutionTest.addTests(suite);
IndexGPPBindingResolutionTest.addTests(suite);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java
index f0877b906c..4af19edf56 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeParameter.java
@@ -28,7 +28,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ValueFactory;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPDependentEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression;
/**
* Binding for a non-type template parameter.
@@ -110,6 +113,14 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter
}
parent= parent.getParent();
}
+
+ // C++17 template<auto>
+ if (type instanceof CPPPlaceholderType) {
+ CPPDependentEvaluation eval = new EvalBinding(this, null, getPrimaryDeclaration());
+ TypeOfDependentExpression replacementType = new TypeOfDependentExpression(eval);
+ replacementType.setForTemplateAuto(true);
+ type = replacementType;
+ }
}
return type;
}
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 ed26f0a81d..d3df642946 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
@@ -2883,9 +2883,12 @@ public class CPPTemplates {
return null;
}
- if (paramType instanceof CPPPlaceholderType) {
+ if (paramType instanceof TypeOfDependentExpression) {
// Partial support for C++17 template <auto>
- return arg;
+ TypeOfDependentExpression type = (TypeOfDependentExpression) paramType;
+ if (type.isForTemplateAuto()) {
+ return arg;
+ }
}
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN,
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java
index c0d3c6f09e..1663cf1446 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java
@@ -29,6 +29,7 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
private final ICPPEvaluation fEvaluation;
// Whether this represents a decltype(expr), or a dependent type in another context.
private boolean fIsForDecltype;
+ private boolean fIsForTemplateAuto;
public TypeOfDependentExpression(ICPPEvaluation evaluation) {
this(evaluation, true);
@@ -38,6 +39,7 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
super(null);
fEvaluation = evaluation;
fIsForDecltype = isForDecltype;
+ fIsForTemplateAuto = false;
}
public ICPPEvaluation getEvaluation() {
@@ -52,6 +54,14 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
fIsForDecltype = isForDecltype;
}
+ public boolean isForTemplateAuto() {
+ return fIsForTemplateAuto;
+ }
+
+ public void setForTemplateAuto(boolean isForTemplateAuto) {
+ fIsForTemplateAuto = isForTemplateAuto;
+ }
+
@Override
public boolean isSameType(IType type) {
return type instanceof TypeOfDependentExpression
@@ -80,6 +90,9 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
if (fIsForDecltype) {
firstBytes |= ITypeMarshalBuffer.FLAG1;
}
+ if (fIsForTemplateAuto) {
+ firstBytes |= ITypeMarshalBuffer.FLAG2;
+ }
buffer.putShort(firstBytes);
buffer.marshalEvaluation(fEvaluation, false);
}
@@ -88,7 +101,10 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
ICPPEvaluation eval= buffer.unmarshalEvaluation();
if (eval != null) {
boolean isForDecltype = (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
- return new TypeOfDependentExpression(eval, isForDecltype);
+ boolean isForTemplateAuto = (firstBytes & ITypeMarshalBuffer.FLAG2) != 0;
+ TypeOfDependentExpression expression = new TypeOfDependentExpression(eval, isForDecltype);
+ expression.setForTemplateAuto(isForTemplateAuto);
+ return expression;
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}