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:
parent
c61e879532
commit
aff9a3332d
9 changed files with 114 additions and 4 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue