1
0
Fork 0
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:
Igor V. Kovalenko 2023-03-04 12:55:49 +03:00 committed by Jonah Graham
parent f17675be16
commit 7d1ea08ae0
3 changed files with 347 additions and 1 deletions

View file

@ -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:

View file

@ -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);
}
}

View file

@ -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());
}
}