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 00000000000..f3c8a7874ed --- /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 + // struct helper { + // static Type call() { + // return nullptr; + // } + // }; + // + // template + // class call_helper { + // using functor_t = decltype(F); + // + // public: + // using type = helper; + // }; + + // 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 920fb2d90f6..8675beca3c4 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 + // struct helper { + // static void call() {} + // }; + // + // template + // class call_helper { + // using functor_t = decltype(F); + // + // public: + // using type = helper; + // }; + // + // 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 48ba4c3debe..e9d21a51c2f 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 f0877b906cb..4af19edf56e 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 + 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 ed26f0a81d4..d3df642946e 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 - 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 c0d3c6f09ea..1663cf1446c 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; }