1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 568616 - Support for __is_same and __is_same_as (built-in equivalent to std::is_same)

IType.isSameType was doing pretty much already what was needed. Added
GCC 6.0 and 10.0 parser configs to enable these built-ins for the proper
versions.

Change-Id: Ifd2908e726c098fb07c9420b29e2cb26014419bf
Signed-off-by: Marc-Andre Laperle <malaperle@gmail.com>
This commit is contained in:
Marc-Andre Laperle 2020-11-08 02:21:24 -05:00 committed by Marc-André Laperle
parent c61e879532
commit aff9a3332d
9 changed files with 114 additions and 4 deletions

View file

@ -13574,4 +13574,74 @@ public class AST2CPPTests extends AST2CPPTestBase {
public void testExplicitSpecPointerType_562697() throws Exception {
parseAndCheckBindings();
}
// using MyBool = bool;
//
// class Foo {
// };
//
// template<typename T = void>
// class Templated {
// };
//
// template<bool>
// class Test {
// public:
// constexpr static int false_val = 0;
// };
//
// template<>
// class Test<true> {
// public:
// constexpr static int true_val = 0;
// };
//
// enum Enum {
// };
//
// enum EnumChar : char {
// };
//
// template<typename T, typename U>
// class TemplateArgs {
// public:
// constexpr static bool Value = __is_same(T, U);
// };
//
// int main() {
// Test<__is_same(bool, bool)>::true_val;
// Test<__is_same_as(bool, bool)>::true_val;
// Test<__is_same(bool, bool&)>::false_val;
// Test<__is_same(bool, bool*)>::false_val;
// Test<__is_same(bool*, bool*)>::true_val;
// Test<__is_same(bool&, bool&)>::true_val;
// Test<__is_same(bool[], bool[])>::true_val;
// Test<__is_same(bool[], bool*)>::false_val;
// Test<__is_same(bool, const volatile MyBool)>::false_val;
// Test<__is_same(bool, MyBool)>::true_val;
// Test<__is_same(bool, Foo)>::false_val;
// Test<__is_same(Templated<bool>, Templated<Foo>)>::false_val;
// Test<__is_same(Templated<>, Templated<void>)>::true_val;
//
// auto func = []() {
// };
// auto func2 = []() {
// };
// Test<__is_same(decltype(func), decltype(func))>::true_val;
// Test<__is_same(decltype(func), decltype(func2))>::false_val;
//
// Test<__is_same(void (*)(int), void (*)(int))>::true_val;
// Test<__is_same(void (*)(bool), void (*)(MyBool))>::true_val;
//
// Test<__is_same(Enum, Enum)>::true_val;
// Test<__is_same(Enum, int)>::false_val;
// Test<__is_same(EnumChar, char)>::false_val;
//
// Test<TemplateArgs<int, bool>::Value>::false_val;
// Test<TemplateArgs<int, int>::Value>::true_val;
// }
public void testIsSame() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true);
}
}

View file

@ -73,7 +73,7 @@ public abstract class BaseTestCase extends TestCase {
* The GCC version to emulate when running tests.
* We emulate the latest version whose extensions we support.
*/
protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 8;
protected static final int GCC_MAJOR_VERSION_FOR_TESTS = 10;
protected static final int GCC_MINOR_VERSION_FOR_TESTS = 1;
/**

View file

@ -30,7 +30,11 @@ public interface IASTBinaryTypeIdExpression extends IASTExpression {
public static enum Operator {
__is_base_of,
/** @since 6.0 */
__is_trivially_assignable
__is_trivially_assignable,
/**
* @since 7.1
*/
__is_same,
}
/**

View file

@ -40,14 +40,18 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
private static final int VERSION_4_6 = version(4, 6);
private static final int VERSION_4_7 = version(4, 7);
private static final int VERSION_5_0 = version(5, 0);
private static final int VERSION_6_0 = version(6, 0);
private static final int VERSION_8_0 = version(8, 0);
private static final int VERSION_10_0 = version(10, 0);
private static GPPScannerExtensionConfiguration CONFIG = new GPPScannerExtensionConfiguration();
private static GPPScannerExtensionConfiguration CONFIG_4_2 = new GPPScannerExtensionConfiguration(VERSION_4_2);
private static GPPScannerExtensionConfiguration CONFIG_4_3 = new GPPScannerExtensionConfiguration(VERSION_4_3);
private static GPPScannerExtensionConfiguration CONFIG_4_6 = new GPPScannerExtensionConfiguration(VERSION_4_6);
private static GPPScannerExtensionConfiguration CONFIG_4_7 = new GPPScannerExtensionConfiguration(VERSION_4_7);
private static GPPScannerExtensionConfiguration CONFIG_5_0 = new GPPScannerExtensionConfiguration(VERSION_5_0);
private static GPPScannerExtensionConfiguration CONFIG_6_0 = new GPPScannerExtensionConfiguration(VERSION_6_0);
private static GPPScannerExtensionConfiguration CONFIG_8_0 = new GPPScannerExtensionConfiguration(VERSION_8_0);
private static GPPScannerExtensionConfiguration CONFIG_10_0 = new GPPScannerExtensionConfiguration(VERSION_10_0);
private static GPPScannerExtensionConfiguration CONFIG_CLANG = new GPPScannerExtensionConfiguration(
CompilerType.Clang, 0 /* version is ignored for now */);
private static GPPScannerExtensionConfiguration CONFIG_MSVC = new GPPScannerExtensionConfiguration(
@ -80,9 +84,15 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
int major = Integer.valueOf(definedSymbols.get("__GNUC__")); //$NON-NLS-1$
int minor = Integer.valueOf(definedSymbols.get("__GNUC_MINOR__")); //$NON-NLS-1$
int version = version(major, minor);
if (version >= VERSION_10_0) {
return CONFIG_10_0;
}
if (version >= VERSION_8_0) {
return CONFIG_8_0;
}
if (version >= VERSION_6_0) {
return CONFIG_6_0;
}
if (version >= VERSION_5_0) {
return CONFIG_5_0;
}
@ -173,10 +183,16 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
addKeyword(GCCKeywords.cp__is_trivially_constructible, IGCCToken.tTT_is_trivially_constructible);
addKeyword(GCCKeywords.cp__is_trivially_assignable, IGCCToken.tTT_is_trivially_assignable);
}
if (version >= VERSION_6_0) {
addKeyword(GCCKeywords.cp__is_same_as, IGCCToken.tTT_is_same);
}
if (version >= VERSION_8_0) {
addKeyword(GCCKeywords.cp__is_constructible, IGCCToken.tTT_is_constructible);
addKeyword(GCCKeywords.cp__integer_pack, IGCCToken.tTT_integer_pack);
}
if (version >= VERSION_10_0) {
addKeyword(GCCKeywords.cp__is_same, IGCCToken.tTT_is_same);
}
} else if (compiler == CompilerType.Clang) {
// As documented at
// http://clang.llvm.org/docs/LanguageExtensions.html#checks-for-type-trait-primitives.
@ -230,8 +246,8 @@ public class GPPScannerExtensionConfiguration extends GNUScannerExtensionConfigu
addKeyword(GCCKeywords.cp__is_polymorphic, IGCCToken.tTT_is_polymorphic);
// __is_reference
// __is_rvalue_reference
// __is_same
// __is_same_as
addKeyword(GCCKeywords.cp__is_same, IGCCToken.tTT_is_same);
addKeyword(GCCKeywords.cp__is_same_as, IGCCToken.tTT_is_same);
// __is_scalar
// __is_sealed
// __is_signed

View file

@ -99,4 +99,9 @@ public class GCCKeywords {
* @since 7.1
*/
public static final char[] cp__is_literal = "__is_literal".toCharArray();
/**
* @since 7.1
*/
public static final char[] cp__is_same = "__is_same".toCharArray(), cp__is_same_as = "__is_same_as".toCharArray();
}

View file

@ -96,4 +96,9 @@ public interface IGCCToken extends IToken {
/** @since 6.11*/
int tTT_integer_pack = FIRST_RESERVED_IGCCToken + 36;
/**
* @since 7.1
*/
int tTT_is_same = FIRST_RESERVED_IGCCToken + 37;
}

View file

@ -603,6 +603,11 @@ public class ValueFactory {
return IntegralValue.create(1);
}
return IntegralValue.create(0);
case __is_same:
if (type1.isSameType(type2)) {
return IntegralValue.create(1);
}
return IntegralValue.create(0);
case __is_trivially_assignable:
return IntegralValue.UNKNOWN; // TODO: Implement.
}

View file

@ -1566,6 +1566,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
case IGCCToken.tTT_is_trivially_constructible:
case IGCCToken.tTT_is_trivially_assignable:
case IGCCToken.tTT_is_constructible:
case IGCCToken.tTT_is_same:
return parseTypeTrait();
default:
@ -1617,6 +1618,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
switch (first.getType()) {
case IGCCToken.tTT_is_base_of:
case IGCCToken.tTT_is_trivially_assignable:
case IGCCToken.tTT_is_same:
return true;
}
return false;
@ -1637,6 +1639,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return IASTBinaryTypeIdExpression.Operator.__is_base_of;
case IGCCToken.tTT_is_trivially_assignable:
return IASTBinaryTypeIdExpression.Operator.__is_trivially_assignable;
case IGCCToken.tTT_is_same:
return IASTBinaryTypeIdExpression.Operator.__is_same;
}
assert false;

View file

@ -80,6 +80,7 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
switch (fOperator) {
case __is_base_of:
case __is_trivially_assignable:
case __is_same:
return CPPBasicType.BOOLEAN;
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;