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 {
|
||||
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.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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -2883,10 +2883,13 @@ public class CPPTemplates {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (paramType instanceof CPPPlaceholderType) {
|
||||
if (paramType instanceof TypeOfDependentExpression) {
|
||||
// Partial support for C++17 template <auto>
|
||||
TypeOfDependentExpression type = (TypeOfDependentExpression) paramType;
|
||||
if (type.isForTemplateAuto()) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN,
|
||||
Context.ORDINARY);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue