mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 02:06:01 +02:00
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>
This commit is contained in:
parent
c16a31325b
commit
809aa57076
6 changed files with 112 additions and 3 deletions
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
|
@ -47,4 +47,29 @@ public class TemplateAutoTests extends AST2CPPTestBase {
|
||||||
public void testTemplateNontypeParameterTypeDeductionParsing_519361_2() throws Exception {
|
public void testTemplateNontypeParameterTypeDeductionParsing_519361_2() throws Exception {
|
||||||
parseAndCheckBindings();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.GenericLambdaIndexTests;
|
||||||
import org.eclipse.cdt.core.parser.tests.ast2.cxx14.ReturnTypeDeductionIndexTests;
|
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.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
@ -42,6 +43,9 @@ public class IndexTests extends TestSuite {
|
||||||
suite.addTestSuite(ReturnTypeDeductionIndexTests.class);
|
suite.addTestSuite(ReturnTypeDeductionIndexTests.class);
|
||||||
suite.addTestSuite(GenericLambdaIndexTests.class);
|
suite.addTestSuite(GenericLambdaIndexTests.class);
|
||||||
|
|
||||||
|
// C++17 index test suites
|
||||||
|
suite.addTestSuite(TemplateAutoIndexTests.class);
|
||||||
|
|
||||||
IndexCPPBindingResolutionBugs.addTests(suite);
|
IndexCPPBindingResolutionBugs.addTests(suite);
|
||||||
IndexCPPBindingResolutionTest.addTests(suite);
|
IndexCPPBindingResolutionTest.addTests(suite);
|
||||||
IndexGPPBindingResolutionTest.addTests(suite);
|
IndexGPPBindingResolutionTest.addTests(suite);
|
||||||
|
|
|
@ -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.ASTQueries;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
|
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.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.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.
|
* Binding for a non-type template parameter.
|
||||||
|
@ -110,6 +113,14 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter
|
||||||
}
|
}
|
||||||
parent= parent.getParent();
|
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;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2883,9 +2883,12 @@ public class CPPTemplates {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paramType instanceof CPPPlaceholderType) {
|
if (paramType instanceof TypeOfDependentExpression) {
|
||||||
// Partial support for C++17 template <auto>
|
// 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,
|
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN,
|
||||||
|
|
|
@ -29,6 +29,7 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
|
||||||
private final ICPPEvaluation fEvaluation;
|
private final ICPPEvaluation fEvaluation;
|
||||||
// Whether this represents a decltype(expr), or a dependent type in another context.
|
// Whether this represents a decltype(expr), or a dependent type in another context.
|
||||||
private boolean fIsForDecltype;
|
private boolean fIsForDecltype;
|
||||||
|
private boolean fIsForTemplateAuto;
|
||||||
|
|
||||||
public TypeOfDependentExpression(ICPPEvaluation evaluation) {
|
public TypeOfDependentExpression(ICPPEvaluation evaluation) {
|
||||||
this(evaluation, true);
|
this(evaluation, true);
|
||||||
|
@ -38,6 +39,7 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
|
||||||
super(null);
|
super(null);
|
||||||
fEvaluation = evaluation;
|
fEvaluation = evaluation;
|
||||||
fIsForDecltype = isForDecltype;
|
fIsForDecltype = isForDecltype;
|
||||||
|
fIsForTemplateAuto = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ICPPEvaluation getEvaluation() {
|
public ICPPEvaluation getEvaluation() {
|
||||||
|
@ -52,6 +54,14 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
|
||||||
fIsForDecltype = isForDecltype;
|
fIsForDecltype = isForDecltype;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isForTemplateAuto() {
|
||||||
|
return fIsForTemplateAuto;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForTemplateAuto(boolean isForTemplateAuto) {
|
||||||
|
fIsForTemplateAuto = isForTemplateAuto;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isSameType(IType type) {
|
public boolean isSameType(IType type) {
|
||||||
return type instanceof TypeOfDependentExpression
|
return type instanceof TypeOfDependentExpression
|
||||||
|
@ -80,6 +90,9 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
|
||||||
if (fIsForDecltype) {
|
if (fIsForDecltype) {
|
||||||
firstBytes |= ITypeMarshalBuffer.FLAG1;
|
firstBytes |= ITypeMarshalBuffer.FLAG1;
|
||||||
}
|
}
|
||||||
|
if (fIsForTemplateAuto) {
|
||||||
|
firstBytes |= ITypeMarshalBuffer.FLAG2;
|
||||||
|
}
|
||||||
buffer.putShort(firstBytes);
|
buffer.putShort(firstBytes);
|
||||||
buffer.marshalEvaluation(fEvaluation, false);
|
buffer.marshalEvaluation(fEvaluation, false);
|
||||||
}
|
}
|
||||||
|
@ -88,7 +101,10 @@ public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPP
|
||||||
ICPPEvaluation eval= buffer.unmarshalEvaluation();
|
ICPPEvaluation eval= buffer.unmarshalEvaluation();
|
||||||
if (eval != null) {
|
if (eval != null) {
|
||||||
boolean isForDecltype = (firstBytes & ITypeMarshalBuffer.FLAG1) != 0;
|
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;
|
return ProblemType.UNKNOWN_FOR_EXPRESSION;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue