mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Add tests for c++17 deduction guides
This commit is contained in:
parent
f17675be16
commit
7d1ea08ae0
3 changed files with 347 additions and 1 deletions
|
@ -112,6 +112,12 @@ public abstract class AST2TestBase extends SemanticTestBase {
|
|||
return true;
|
||||
}
|
||||
},
|
||||
STDCPP17 {
|
||||
@Override
|
||||
public boolean isUseGNUExtensions() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
STDCPP20 {
|
||||
@Override
|
||||
public boolean isUseGNUExtensions() {
|
||||
|
@ -128,6 +134,7 @@ public abstract class AST2TestBase extends SemanticTestBase {
|
|||
|
||||
private static final ScannerInfo GNU_SCANNER_INFO = new ScannerInfo(getGnuMap());
|
||||
private static final ScannerInfo SCANNER_INFO = new ScannerInfo(getStdMap());
|
||||
private static final ScannerInfo STDCPP17_SCANNER_INFO = new ScannerInfo(getStdCpp17Map());
|
||||
private static final ScannerInfo STDCPP20_SCANNER_INFO = new ScannerInfo(getStdCpp20Map());
|
||||
|
||||
private static Map<String, String> getGnuMap() {
|
||||
|
@ -154,10 +161,18 @@ public abstract class AST2TestBase extends SemanticTestBase {
|
|||
return map;
|
||||
}
|
||||
|
||||
private static Map<String, String> getStdCpp20Map() {
|
||||
private static Map<String, String> getStdCpp17Map() {
|
||||
Map<String, String> map = getStdMap();
|
||||
map.put("__cpp_deduction_guides", "201703L");
|
||||
return map;
|
||||
}
|
||||
|
||||
private static Map<String, String> getStdCpp20Map() {
|
||||
Map<String, String> map = getStdCpp17Map();
|
||||
map.put("__cpp_impl_three_way_comparison", "201907L");
|
||||
map.put("__cpp_char8_t", "201811L");
|
||||
// TODO: C++20 features
|
||||
//map.put("__cpp_deduction_guides", "201907L");
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -241,6 +256,8 @@ public abstract class AST2TestBase extends SemanticTestBase {
|
|||
switch (scannerKind) {
|
||||
case GNU:
|
||||
return GNU_SCANNER_INFO;
|
||||
case STDCPP17:
|
||||
return STDCPP17_SCANNER_INFO;
|
||||
case STDCPP20:
|
||||
return STDCPP20_SCANNER_INFO;
|
||||
case STD:
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2.cxx17;
|
||||
|
||||
import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.char_;
|
||||
import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.double_;
|
||||
import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.int_;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemType;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||
import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTestBase;
|
||||
|
||||
/**
|
||||
* AST tests for C++17 deduction guides.
|
||||
*/
|
||||
public class DeductionGuideTest extends AST2CPPTestBase {
|
||||
|
||||
// template<typename T> struct S {
|
||||
// template<typename U> S(S<U> s) : value(s.value) {}
|
||||
// S(T v) : value(v) {}
|
||||
// T value;
|
||||
// };
|
||||
//
|
||||
// //template<typename T> S(T t) -> S<double>;
|
||||
// template<typename T> S(char) -> S<char>; // invalid candidate, T cannot be deduced
|
||||
// S(int) -> S<double>;
|
||||
//
|
||||
// void f() {
|
||||
// auto dchar = S('1').value;
|
||||
// auto dint = S(1).value;
|
||||
// double dv = S<double>(1).value;
|
||||
// int iv = S(1).value;
|
||||
//
|
||||
// auto sdouble = S<double>();
|
||||
// auto ddouble = S(1);
|
||||
//
|
||||
// S copy = ddouble;
|
||||
// S init{ddouble};
|
||||
// S convert(ddouble);
|
||||
// }
|
||||
public void testDeductionGuideBasic() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper(ParserLanguage.CPP, ScannerKind.STDCPP17);
|
||||
assertType(bh.assertNonProblem("dchar = S", 5), char_);
|
||||
assertType(bh.assertNonProblem("dint = S", 4), double_);
|
||||
assertType(bh.assertNonProblem("dv = S", 2), double_);
|
||||
assertType(bh.assertNonProblem("iv = S", 2), int_);
|
||||
|
||||
IVariable varDouble = bh.assertNonProblem("sdouble = S", 7);
|
||||
assertType(bh.assertNonProblem("ddouble = S", 7), varDouble.getType());
|
||||
|
||||
assertType(bh.assertNonProblem("copy = ddouble", 4), varDouble.getType());
|
||||
|
||||
assertType(bh.assertNonProblem("init{", 4), varDouble.getType());
|
||||
|
||||
assertType(bh.assertNonProblem("convert(", 7), varDouble.getType());
|
||||
}
|
||||
|
||||
// template<typename T, typename U = bool> struct S {
|
||||
// S(T v) : value(v) {}
|
||||
// T value;
|
||||
// };
|
||||
//
|
||||
// //template<typename T> S(T t) -> S<double>;
|
||||
// template<typename T> S(char) -> S<char>;
|
||||
// S(int) -> S<double>;
|
||||
//
|
||||
// void f() {
|
||||
// auto dchar = S('1').value;
|
||||
// auto dint = S(1).value;
|
||||
// double dv = S<double>(1).value;
|
||||
// int iv = S(1).value;
|
||||
// }
|
||||
public void testDeductionGuideWithDefaultTemplateArg() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper(ParserLanguage.CPP, ScannerKind.STDCPP17);
|
||||
assertType(bh.assertNonProblem("dchar = S", 5), char_);
|
||||
assertType(bh.assertNonProblem("dint = S", 4), double_);
|
||||
assertType(bh.assertNonProblem("dv = S", 2), double_);
|
||||
assertType(bh.assertNonProblem("iv = S", 2), int_);
|
||||
}
|
||||
|
||||
// template<typename T> struct S; // No definition
|
||||
//
|
||||
// S(char) -> S<char>;
|
||||
// S(int) -> S<double>;
|
||||
//
|
||||
// void f() {
|
||||
// auto schar = S<char>();
|
||||
// auto dchar = S('1');
|
||||
// auto sdouble = S<double>();
|
||||
// auto ddouble = S(1);
|
||||
// S copy = ddouble;
|
||||
// S init{ddouble};
|
||||
// S convert(ddouble);
|
||||
// }
|
||||
public void testDeductionGuideWithTemplateDeclaration() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper(ParserLanguage.CPP, ScannerKind.STDCPP17);
|
||||
|
||||
IVariable varChar = bh.assertNonProblem("schar = S", 5);
|
||||
assertType(bh.assertNonProblem("dchar = S", 5), varChar.getType());
|
||||
|
||||
IVariable varDouble = bh.assertNonProblem("sdouble = S", 7);
|
||||
assertType(bh.assertNonProblem("ddouble = S", 7), varDouble.getType());
|
||||
|
||||
assertType(bh.assertNonProblem("copy = ddouble", 4), varDouble.getType());
|
||||
|
||||
assertType(bh.assertNonProblem("init{", 4), varDouble.getType());
|
||||
|
||||
assertType(bh.assertNonProblem("convert(", 7), varDouble.getType());
|
||||
}
|
||||
|
||||
// template<class T>
|
||||
// struct UniquePtr
|
||||
// {
|
||||
// UniquePtr(T* t);
|
||||
// };
|
||||
//
|
||||
// UniquePtr dp{new auto(2.0)};
|
||||
// auto da = dp;
|
||||
public void testMinimal() throws Exception {
|
||||
parseAndCheckBindings(ScannerKind.STDCPP17);
|
||||
}
|
||||
|
||||
// template<class T> struct S {
|
||||
// S();
|
||||
// };
|
||||
//
|
||||
// S<int> sInt;
|
||||
//
|
||||
// S s1;
|
||||
//
|
||||
// S() -> S<int>;
|
||||
//
|
||||
// S s2;
|
||||
public void testDeduceFromEmptyInitializer() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper(ParserLanguage.CPP, ScannerKind.STDCPP17);
|
||||
IVariable varSInt = bh.assertNonProblem("sInt", 4);
|
||||
bh.assertProblem("S s1", 1);
|
||||
bh.assertNonProblem("S s2", 1);
|
||||
assertType(bh.assertNonProblem("s2", 2), varSInt.getType());
|
||||
}
|
||||
|
||||
// template<class T>
|
||||
// struct S
|
||||
// {
|
||||
// S(T t);
|
||||
// template <typename U> S(U u);
|
||||
// };
|
||||
//
|
||||
// S(char c) -> S<long>;
|
||||
// S(int i) -> S<double>;
|
||||
//
|
||||
// auto v = S(1);
|
||||
public void testViaFunctionSetFromConstructors() throws Exception {
|
||||
parseAndCheckBindings(ScannerKind.STDCPP17);
|
||||
}
|
||||
|
||||
// template<class T> struct S{};
|
||||
//
|
||||
// S* pointer;
|
||||
public void testNoDeductionForPointer() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper(ParserLanguage.CPP, ScannerKind.STDCPP17);
|
||||
IType pointedType = ((IPointerType) ((IVariable) bh.assertNonProblem("pointer")).getType()).getType();
|
||||
assertTrue(pointedType instanceof IProblemType);
|
||||
bh.assertProblem("S*", 1);
|
||||
}
|
||||
|
||||
// template<class T> struct S;
|
||||
//
|
||||
// S* pointer;
|
||||
public void testNoDeductionForPointerNoDefinition() throws Exception {
|
||||
BindingAssertionHelper bh = getAssertionHelper(ParserLanguage.CPP, ScannerKind.STDCPP17);
|
||||
IType pointedType = ((IPointerType) ((IVariable) bh.assertNonProblem("pointer")).getType()).getType();
|
||||
assertTrue(pointedType instanceof IProblemType);
|
||||
bh.assertProblem("S*", 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.index.tests;
|
||||
|
||||
import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.char_;
|
||||
import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.double_;
|
||||
import static org.eclipse.cdt.core.parser.tests.ast2.CommonCPPTypes.int_;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||
import org.eclipse.cdt.core.testplugin.TestScannerProvider;
|
||||
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
/**
|
||||
* AST tests for C++17 deduction guides via PDOM.
|
||||
*/
|
||||
public abstract class IndexDeductionGuideTest extends IndexBindingResolutionTestBase {
|
||||
private static void cxx17SetUp() {
|
||||
// Enable deduction guides via C++17 feature detection macro
|
||||
TestScannerProvider.sDefinedSymbols.put("__cpp_deduction_guides", "201703L");
|
||||
}
|
||||
|
||||
private static void cxx17TearDown() {
|
||||
TestScannerProvider.clear();
|
||||
}
|
||||
|
||||
public class Cxx17ReferencedProject extends ReferencedProject {
|
||||
public Cxx17ReferencedProject() {
|
||||
super(true /* cpp */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
cxx17SetUp();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
cxx17TearDown();
|
||||
}
|
||||
}
|
||||
|
||||
public class Cxx17SinglePDOMTestStrategy extends SinglePDOMTestStrategy {
|
||||
public Cxx17SinglePDOMTestStrategy() {
|
||||
super(true /* cpp */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
cxx17SetUp();
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
cxx17TearDown();
|
||||
}
|
||||
}
|
||||
|
||||
public static class IndexDeductionGuideTestSingleProject extends IndexDeductionGuideTest {
|
||||
public IndexDeductionGuideTestSingleProject() {
|
||||
setStrategy(new Cxx17SinglePDOMTestStrategy());
|
||||
}
|
||||
|
||||
public static TestSuite suite() {
|
||||
return suite(IndexDeductionGuideTestSingleProject.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IndexDeductionGuideTestProjectWithDepProj extends IndexDeductionGuideTest {
|
||||
public IndexDeductionGuideTestProjectWithDepProj() {
|
||||
setStrategy(new Cxx17ReferencedProject());
|
||||
}
|
||||
|
||||
public static TestSuite suite() {
|
||||
return suite(IndexDeductionGuideTestProjectWithDepProj.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static void addTests(TestSuite suite) {
|
||||
suite.addTest(IndexDeductionGuideTestSingleProject.suite());
|
||||
suite.addTest(IndexDeductionGuideTestProjectWithDepProj.suite());
|
||||
}
|
||||
|
||||
// template<typename T> struct S {
|
||||
// template<typename U> S(S<U> s) : value(s.value) {}
|
||||
// S(T v) : value(v) {}
|
||||
// T value;
|
||||
// };
|
||||
//
|
||||
// //template<typename T> S(T t) -> S<double>;
|
||||
// template<typename T> S(char) -> S<char>; // invalid candidate, T cannot be deduced
|
||||
// S(int) -> S<double>;
|
||||
|
||||
// void f() {
|
||||
// auto dchar = S('1').value;
|
||||
// auto dint = S(1).value;
|
||||
// double dv = S<double>(1).value;
|
||||
// int iv = S(1).value;
|
||||
//
|
||||
// auto sdouble = S<double>();
|
||||
// auto ddouble = S(1);
|
||||
//
|
||||
// S copy = ddouble;
|
||||
// S init{ddouble};
|
||||
// S convert(ddouble);
|
||||
// }
|
||||
//
|
||||
// constexpr size_t value = sizeof(ddouble.value);
|
||||
public void testDeductionGuideBasicHeader() throws Exception {
|
||||
assertType(getBindingFromASTName("dchar = S", 5), char_);
|
||||
assertType(getBindingFromASTName("dint = S", 4), double_);
|
||||
assertType(getBindingFromASTName("dv = S", 2), double_);
|
||||
assertType(getBindingFromASTName("iv = S", 2), int_);
|
||||
|
||||
IVariable varDouble = (IVariable) getBindingFromASTName("sdouble = S", 7);
|
||||
assertType(getBindingFromASTName("ddouble = S", 7), varDouble.getType());
|
||||
|
||||
assertType(getBindingFromASTName("copy = ddouble", 4), varDouble.getType());
|
||||
|
||||
assertType(getBindingFromASTName("init{", 4), varDouble.getType());
|
||||
|
||||
assertType(getBindingFromASTName("convert(", 7), varDouble.getType());
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue