summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/RunClang.cxx36
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/expect/cmd.cc-msvc-builtin-1900-E.stdout.txt3
-rw-r--r--test/input/make_integer_seq.cxx6
4 files changed, 45 insertions, 1 deletions
diff --git a/src/RunClang.cxx b/src/RunClang.cxx
index 0301388..e674ffc 100644
--- a/src/RunClang.cxx
+++ b/src/RunClang.cxx
@@ -240,6 +240,42 @@ protected:
;
}
+#if LLVM_VERSION_MAJOR < 3 \
+ || LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR < 8
+ // Clang 3.8 and above provide a __make_integer_seq builtin needed
+ // in C++14 mode. Provide it ourselves for older Clang versions.
+ if (CI.getLangOpts().CPlusPlus14) {
+ builtins += "\n"
+ "template <typename _T, _T> struct __castxml__integral_constant;\n"
+ "template <template<typename _U, _U...> class _S,\n"
+ " typename, typename, bool>\n"
+ " struct __castxml__make_integer_seq_impl;\n"
+ "template <template<typename _U, _U...> class _S,\n"
+ " class _T, _T... __v>\n"
+ " struct __castxml__make_integer_seq_impl<_S,\n"
+ " __castxml__integral_constant<_T, 0>,\n"
+ " _S<_T, __v...>, true> {\n"
+ " typedef _S<_T, __v...> type;\n"
+ " };\n"
+ "template <template<typename _U, _U...> class _S,\n"
+ " class _T, _T __i, _T... __v>\n"
+ " struct __castxml__make_integer_seq_impl<_S,\n"
+ " __castxml__integral_constant<_T, __i>,\n"
+ " _S<_T, __v...>, true>\n"
+ " : __castxml__make_integer_seq_impl<_S,\n"
+ " __castxml__integral_constant<_T, __i - 1>,\n"
+ " _S<_T, __i - 1, __v...>, __i >= 1 > {};\n"
+ "template <template<typename _U, _U...> class _S,\n"
+ " typename _T, _T _Sz>\n"
+ "using __castxml__make_integer_seq = typename\n"
+ " __castxml__make_integer_seq_impl<_S,\n"
+ " __castxml__integral_constant<_T, _Sz>,\n"
+ " _S<_T>, (_Sz>=0)>::type;\n"
+ "#define __make_integer_seq __castxml__make_integer_seq\n"
+ ;
+ }
+#endif
+
// Prevent glibc use of a GNU extension not implemented by Clang.
if (this->NeedNoMathInlines(this->Opts.Predefines)) {
builtins += "\n"
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 98a58bf..575ab81 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -268,6 +268,7 @@ castxml_test_cmd(cc-msvc-std-c++14 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc>
castxml_test_cmd(cc-msvc-std-explicit --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1500 ")" -std=gnu++14 ${empty_cxx} "-###")
castxml_test_cmd(cc-msvc-builtin-1800-E --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1800 ")" ${empty_cxx} -E -dM)
castxml_test_cmd(cc-msvc-builtin-1900-E --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 ")" ${empty_cxx} -E -dM)
+castxml_test_cmd(cc-msvc-builtin-1900 --castxml-cc-msvc "(" $<TARGET_FILE:cc-msvc> -msc=1900 ")" ${input}/make_integer_seq.cxx)
castxml_test_cmd(cc-msvc-c-bad-cmd --castxml-cc-msvc-c "(" cc-msvc-c-bad-cmd ")" ${empty_c})
castxml_test_cmd(cc-msvc-c-src-c-E --castxml-cc-msvc-c $<TARGET_FILE:cc-msvc> ${empty_c} -E -dM)
castxml_test_cmd(cc-msvc-c-src-c-cmd --castxml-cc-msvc-c $<TARGET_FILE:cc-msvc> ${empty_c} "-###")
diff --git a/test/expect/cmd.cc-msvc-builtin-1900-E.stdout.txt b/test/expect/cmd.cc-msvc-builtin-1900-E.stdout.txt
index d008453..3990d4c 100644
--- a/test/expect/cmd.cc-msvc-builtin-1900-E.stdout.txt
+++ b/test/expect/cmd.cc-msvc-builtin-1900-E.stdout.txt
@@ -5,4 +5,5 @@
#define __castxml_clang_minor__ [0-9]+
#define __castxml_clang_patchlevel__ [0-9]+
#define __cplusplus 199711L
-#define __is_assignable\(_To,_Fr\) \(sizeof\(__castxml__is_assignable_check<_To,_Fr>\(0\)\) == sizeof\(char\(&\)\[1\]\)\)$
+#define __is_assignable\(_To,_Fr\) \(sizeof\(__castxml__is_assignable_check<_To,_Fr>\(0\)\) == sizeof\(char\(&\)\[1\]\)\)(
+#define __make_integer_seq __castxml__make_integer_seq)?$
diff --git a/test/input/make_integer_seq.cxx b/test/input/make_integer_seq.cxx
new file mode 100644
index 0000000..44a89a8
--- /dev/null
+++ b/test/input/make_integer_seq.cxx
@@ -0,0 +1,6 @@
+template <typename _T, _T...> struct seq;
+typedef __make_integer_seq<seq, int, 3> seq_A;
+typedef seq<int,0,1,2> seq_B;
+template <typename A, typename B> struct assert_same;
+template <typename A> struct assert_same<A,A> {};
+assert_same<seq_A,seq_B> enforce;