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>
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index 96b72dc..fe3fce6 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -13574,4 +13574,74 @@
 	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);
+	}
+
 }
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java
index 749a8e4..172d940 100644
--- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/testplugin/util/BaseTestCase.java
@@ -73,7 +73,7 @@
 	 * 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;
 
 	/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryTypeIdExpression.java
index abcd5de..3a98ede 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryTypeIdExpression.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTBinaryTypeIdExpression.java
@@ -30,7 +30,11 @@
 	public static enum Operator {
 		__is_base_of,
 		/** @since 6.0 */
-		__is_trivially_assignable
+		__is_trivially_assignable,
+		/**
+		* @since 7.1
+		*/
+		__is_same,
 	}
 
 	/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java
index aa659a7..99dcd0a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/parser/cpp/GPPScannerExtensionConfiguration.java
@@ -40,14 +40,18 @@
 	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 @@
 				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 @@
 				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 @@
 			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
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java
index 2062b2e..b737494 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/GCCKeywords.java
@@ -99,4 +99,9 @@
 	 * @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();
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java
index 62033d7..61dd350 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IGCCToken.java
@@ -96,4 +96,9 @@
 
 	/** @since 6.11*/
 	int tTT_integer_pack = FIRST_RESERVED_IGCCToken + 36;
+
+	/**
+	 * @since 7.1
+	 */
+	int tTT_is_same = FIRST_RESERVED_IGCCToken + 37;
 }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java
index 9d104b0..68651b8 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java
@@ -603,6 +603,11 @@
 				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.
 		}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index 85c3b2d..5ad8188 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -1566,6 +1566,7 @@
 		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 @@
 		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 @@
 			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;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java
index 21aff04..dc0d236 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java
@@ -80,6 +80,7 @@
 		switch (fOperator) {
 		case __is_base_of:
 		case __is_trivially_assignable:
+		case __is_same:
 			return CPPBasicType.BOOLEAN;
 		}
 		return ProblemType.UNKNOWN_FOR_EXPRESSION;