From f1bb3c2ac4ff530b38ce0cc627f04d47b21d76f2 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 21 Apr 2016 13:38:06 -0400 Subject: RunClang: Provide `__make_integer_seq` builtin when Clang does not Visual Studio 2015 Update 2 (cl 19.00.23918) adds a `__make_integer_seq` builtin. It also started using the builtin in the `` header. Clang version 3.8 and above provide this builtin but older versions do not, so CastXML fails when built against Clang 3.6 or 3.7. Work around this problem by adding our own implementation of the builtin when Clang does not provide it. --- src/RunClang.cxx | 36 +++++++++++++++++++++++ test/CMakeLists.txt | 1 + test/expect/cmd.cc-msvc-builtin-1900-E.stdout.txt | 3 +- test/input/make_integer_seq.cxx | 6 ++++ 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 test/input/make_integer_seq.cxx 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 struct __castxml__integral_constant;\n" + "template class _S,\n" + " typename, typename, bool>\n" + " struct __castxml__make_integer_seq_impl;\n" + "template 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 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 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 "(" $ castxml_test_cmd(cc-msvc-std-explicit --castxml-cc-msvc "(" $ -msc=1500 ")" -std=gnu++14 ${empty_cxx} "-###") castxml_test_cmd(cc-msvc-builtin-1800-E --castxml-cc-msvc "(" $ -msc=1800 ")" ${empty_cxx} -E -dM) castxml_test_cmd(cc-msvc-builtin-1900-E --castxml-cc-msvc "(" $ -msc=1900 ")" ${empty_cxx} -E -dM) +castxml_test_cmd(cc-msvc-builtin-1900 --castxml-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 $ ${empty_c} -E -dM) castxml_test_cmd(cc-msvc-c-src-c-cmd --castxml-cc-msvc-c $ ${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 struct seq; +typedef __make_integer_seq seq_A; +typedef seq seq_B; +template struct assert_same; +template struct assert_same {}; +assert_same enforce; -- cgit v0.12