From 276e2bbace4559f655f5adea8f58104abb21314f Mon Sep 17 00:00:00 2001 From: Frederich Munch Date: Mon, 26 Jun 2017 23:55:40 -0400 Subject: [PATCH 1/5] =?UTF-8?q?Don=E2=80=99t=20clear=20GNUMode=20when=20us?= =?UTF-8?q?er=20has=20specifically=20asked=20for=20it.=20There=20are=20use?= =?UTF-8?q?s=20that=20are=20valid=20even=20if=20the=20host=20compiled=20wi?= =?UTF-8?q?th=20=5FGLIBCXX=5FUSE=5FFLOAT128.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cling/Interpreter/InvocationOptions.h | 8 +++ .../cling/lib/Interpreter/CIFactory.cpp | 59 +++++++++++-------- interpreter/cling/test/Driver/Gnu.C | 27 +++++++++ 3 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 interpreter/cling/test/Driver/Gnu.C diff --git a/interpreter/cling/include/cling/Interpreter/InvocationOptions.h b/interpreter/cling/include/cling/Interpreter/InvocationOptions.h index e08a68b0044c2..4caeb586bcf22 100644 --- a/interpreter/cling/include/cling/Interpreter/InvocationOptions.h +++ b/interpreter/cling/include/cling/Interpreter/InvocationOptions.h @@ -36,6 +36,14 @@ namespace cling { void Parse(int argc, const char* const argv[], std::vector* Inputs = nullptr); + ///\brief By default clang will try to set up an Interpreter with features + /// that match how it was compiled. There are cases; however, where the + /// client is asking for something so specific (i.e './cling -std=gnu++11' + /// or './cling -x c') that this shouldn't be done. This will return false + /// in those cases. + /// + bool DefaultLanguage() const { return !Language && !StdVersion; } + unsigned Language : 1; unsigned ResourceDir : 1; unsigned SysRoot : 1; diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index a4d8ae4007404..7b95b9cbc48f5 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -360,7 +360,8 @@ namespace { } } - static void SetClingCustomLangOpts(LangOptions& Opts) { + static void SetClingCustomLangOpts(LangOptions& Opts, + const CompilerOptions& CompilerOpts) { Opts.EmitAllDecls = 0; // Otherwise if PCH attached will codegen all decls. #ifdef _MSC_VER #ifdef _DEBUG @@ -395,7 +396,6 @@ namespace { // Except -fexceptions -fcxx-exceptions. Opts.Deprecated = 1; - Opts.GNUKeywords = 0; #ifdef __APPLE__ Opts.Blocks = 1; @@ -417,18 +417,23 @@ namespace { #ifdef _REENTRANT Opts.POSIXThreads = 1; #endif -#ifdef __STRICT_ANSI__ - Opts.GNUMode = 0; -#else - Opts.GNUMode = 1; -#endif #ifdef __FAST_MATH__ Opts.FastMath = 1; #endif + + if (CompilerOpts.DefaultLanguage()) { +#ifdef __STRICT_ANSI__ + Opts.GNUMode = 0; +#else + Opts.GNUMode = 1; +#endif + Opts.GNUKeywords = 0; + } } static void SetClingTargetLangOpts(LangOptions& Opts, - const TargetInfo& Target) { + const TargetInfo& Target, + const CompilerOptions& CompilerOpts) { if (Target.getTriple().getOS() == llvm::Triple::Win32) { Opts.MicrosoftExt = 1; #ifdef _MSC_VER @@ -439,21 +444,24 @@ namespace { } else { Opts.MicrosoftExt = 0; } + + if (CompilerOpts.DefaultLanguage()) { #if _GLIBCXX_USE_FLOAT128 - // We are compiling with libstdc++ with __float128 enabled. - if (!Target.hasFloat128Type()) { - // clang currently supports native __float128 only on few targets, and - // this target does not have it. The most visible consequence of this is a - // specialization - // __is_floating_point_helper<__float128> - // in include/c++/6.3.0/type_traits:344 that clang then rejects. The - // specialization is protected by !if _GLIBCXX_USE_FLOAT128 (which is - // unconditionally set in c++config.h) and #if !__STRICT_ANSI__. Tweak the - // latter by disabling GNUMode: + // We are compiling with libstdc++ with __float128 enabled. + if (!Target.hasFloat128Type()) { + // clang currently supports native __float128 only on few targets, and + // this target does not have it. The most visible consequence of this is a + // specialization + // __is_floating_point_helper<__float128> + // in include/c++/6.3.0/type_traits:344 that clang then rejects. The + // specialization is protected by !if _GLIBCXX_USE_FLOAT128 (which is + // unconditionally set in c++config.h) and #if !__STRICT_ANSI__. Tweak the + // latter by disabling GNUMode: # warning "Disabling gnu++: clang has no __float128 support on this target!" - Opts.GNUMode = 0; + Opts.GNUMode = 0; + } +#endif //_GLIBCXX_USE_FLOAT128 } -#endif //__GLIBCXX__ } // This must be a copy of clang::getClangToolFullVersion(). Luckily @@ -628,11 +636,12 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, } static bool - SetupCompiler(CompilerInstance* CI, bool Lang = true, bool Targ = true) { + SetupCompiler(CompilerInstance* CI, const CompilerOptions& CompilerOpts, + bool Lang = true, bool Targ = true) { // Set the language options, which cling needs. // This may have already been done via a precompiled header if (Lang) - SetClingCustomLangOpts(CI->getLangOpts()); + SetClingCustomLangOpts(CI->getLangOpts(), CompilerOpts); PreprocessorOptions& PPOpts = CI->getInvocation().getPreprocessorOpts(); SetPreprocessorFromBinary(PPOpts); @@ -659,7 +668,7 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, // This may have already been done via a precompiled header if (Targ) - SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget()); + SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget(), CompilerOpts); SetPreprocessorFromTarget(PPOpts, CI->getTarget().getTriple()); return true; @@ -816,7 +825,7 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, "output is supported.\n"; return nullptr; } - if (!SetupCompiler(CI.get())) + if (!SetupCompiler(CI.get(), COpts)) return nullptr; ProcessWarningOptions(*Diags, DiagOpts); @@ -895,7 +904,7 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, Invocation.getFrontendOpts().DisableFree = true; // Set up compiler language and target - if (!SetupCompiler(CI.get(), InitLang, InitTarget)) + if (!SetupCompiler(CI.get(), COpts, InitLang, InitTarget)) return nullptr; // Set up source managers diff --git a/interpreter/cling/test/Driver/Gnu.C b/interpreter/cling/test/Driver/Gnu.C new file mode 100644 index 0000000000000..2f0b149f1ef83 --- /dev/null +++ b/interpreter/cling/test/Driver/Gnu.C @@ -0,0 +1,27 @@ +//------------------------------------------------------------------------------ +// CLING - the C++ LLVM-based InterpreterG :) +// +// This file is dual-licensed: you can choose to license it under the University +// of Illinois Open Source License or the GNU Lesser General Public License. See +// LICENSE.TXT for details. +//------------------------------------------------------------------------------ + +// RUN: cat %s | %cling -std=gnu99 -x c -Xclang -verify 2>&1 | FileCheck %s +// RUN: cat %s | %cling -D__STRICT_ANSI__ -std=gnu++11 -Xclang -verify 2>&1 | FileCheck %s +// RUN: cat %s | %cling -D__STRICT_ANSI__ -std=gnu++14 -Xclang -verify 2>&1 | FileCheck %s +// RUN: cat %s | %cling -D__STRICT_ANSI__ -std=gnu++1z -Xclang -verify 2>&1 | FileCheck %s + +#ifdef __cplusplus +extern "C" int printf(const char*, ...); +#else +int printf(const char*, ...); +#endif + +typeof (int) Val = 22; +typeof (const char*) This = "THIS"; + +printf("TEST: %d '%s'\n", Val, This); +// CHECK: TEST: 22 'THIS' + +// expected-no-diagnostics +.q From 6e68ec056b0482ab10f7d45839856c3862321c2d Mon Sep 17 00:00:00 2001 From: Frederich Munch Date: Wed, 28 Jun 2017 04:54:33 -0400 Subject: [PATCH 2/5] Make sure to setup the language defaults normally when outputting a PCH. --- .../include/cling/Interpreter/InvocationOptions.h | 6 +++++- interpreter/cling/lib/Interpreter/CIFactory.cpp | 4 ++-- .../cling/lib/Interpreter/InvocationOptions.cpp | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/interpreter/cling/include/cling/Interpreter/InvocationOptions.h b/interpreter/cling/include/cling/Interpreter/InvocationOptions.h index 4caeb586bcf22..8ace791e7413c 100644 --- a/interpreter/cling/include/cling/Interpreter/InvocationOptions.h +++ b/interpreter/cling/include/cling/Interpreter/InvocationOptions.h @@ -13,6 +13,10 @@ #include #include +namespace clang { + class LangOptions; +}; + namespace cling { ///\brief Class that stores options that are used by both cling and @@ -42,7 +46,7 @@ namespace cling { /// or './cling -x c') that this shouldn't be done. This will return false /// in those cases. /// - bool DefaultLanguage() const { return !Language && !StdVersion; } + bool DefaultLanguage(const clang::LangOptions&) const; unsigned Language : 1; unsigned ResourceDir : 1; diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index 7b95b9cbc48f5..c18f67cfbb97b 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -421,7 +421,7 @@ namespace { Opts.FastMath = 1; #endif - if (CompilerOpts.DefaultLanguage()) { + if (CompilerOpts.DefaultLanguage(Opts)) { #ifdef __STRICT_ANSI__ Opts.GNUMode = 0; #else @@ -445,7 +445,7 @@ namespace { Opts.MicrosoftExt = 0; } - if (CompilerOpts.DefaultLanguage()) { + if (CompilerOpts.DefaultLanguage(Opts)) { #if _GLIBCXX_USE_FLOAT128 // We are compiling with libstdc++ with __float128 enabled. if (!Target.hasFloat128Type()) { diff --git a/interpreter/cling/lib/Interpreter/InvocationOptions.cpp b/interpreter/cling/lib/Interpreter/InvocationOptions.cpp index c8cdfff3444f8..b40629911a5ed 100644 --- a/interpreter/cling/lib/Interpreter/InvocationOptions.cpp +++ b/interpreter/cling/lib/Interpreter/InvocationOptions.cpp @@ -11,6 +11,7 @@ #include "cling/Interpreter/ClingOptions.h" #include "cling/Utils/Output.h" +#include "clang/Basic/LangOptions.h" #include "clang/Driver/Options.h" #include "llvm/Option/Arg.h" @@ -144,6 +145,20 @@ void CompilerOptions::Parse(int argc, const char* const argv[], } } +bool CompilerOptions::DefaultLanguage(const LangOptions& LangOpts) const { + // When StdVersion is set (-std=c++11, -std=gnu++11, etc.) then definitely + // don't setup the defaults, as they may interfere with what the user is doing + if (StdVersion) + return false; + + // Also don't set up the defaults when language is explicitly set; unless + // the language was set to generate a PCH, in which case definitely do. + if (Language) + return LangOpts.CompilingPCH || HasOutput; + + return true; +} + InvocationOptions::InvocationOptions(int argc, const char* const* argv) : MetaString("."), ErrorOut(false), NoLogo(false), ShowVersion(false), Help(false), NoRuntime(false) { From 3586e0ba43a02dc3dc43a20677fd8c928e9215b3 Mon Sep 17 00:00:00 2001 From: Frederich Munch Date: Mon, 26 Jun 2017 23:20:03 -0400 Subject: [PATCH 3/5] Remove outdated comments. --- interpreter/cling/lib/Interpreter/CIFactory.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index c18f67cfbb97b..a659e265ad3f8 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -54,10 +54,6 @@ using namespace cling; namespace { static constexpr unsigned CxxStdCompiledWith() { - // Extracted from Boost/config/compiler. - // SunProCC has no C++11. - // VisualC's support is not obvious to extract from Boost... - // The value of __cplusplus in GCC < 5.0 (e.g. 4.9.3) when // either -std=c++1y or -std=c++14 is specified is 201300L, which fails // the test for C++14 or more (201402L) as previously specified. @@ -648,7 +644,6 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, PPOpts.addMacroDef("__CLING__"); if (CI->getLangOpts().CPlusPlus11 == 1) { - // http://llvm.org/bugs/show_bug.cgi?id=13530 PPOpts.addMacroDef("__CLING__CXX11"); } From e930f551780d0c0f82f3d7d23750f98aec9fbb93 Mon Sep 17 00:00:00 2001 From: Frederich Munch Date: Mon, 26 Jun 2017 23:23:28 -0400 Subject: [PATCH 4/5] Set __CLING__CXX14 for consitancy. --- interpreter/cling/lib/Interpreter/CIFactory.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index a659e265ad3f8..989cb2c96c739 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -643,9 +643,10 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts, SetPreprocessorFromBinary(PPOpts); PPOpts.addMacroDef("__CLING__"); - if (CI->getLangOpts().CPlusPlus11 == 1) { + if (CI->getLangOpts().CPlusPlus11 == 1) PPOpts.addMacroDef("__CLING__CXX11"); - } + if (CI->getLangOpts().CPlusPlus14 == 1) + PPOpts.addMacroDef("__CLING__CXX14"); if (CI->getDiagnostics().hasErrorOccurred()) { cling::errs() << "Compiler error to early in initialization.\n"; From 6b1bd71606d984b7507b46e9da044088f45aa4f1 Mon Sep 17 00:00:00 2001 From: Frederich Munch Date: Tue, 27 Jun 2017 20:44:46 -0400 Subject: [PATCH 5/5] Travis: Re-enable testing for issues with __float128 on OS X. --- interpreter/cling/.travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interpreter/cling/.travis.yml b/interpreter/cling/.travis.yml index 39c3090528c1e..b739dae5479ab 100644 --- a/interpreter/cling/.travis.yml +++ b/interpreter/cling/.travis.yml @@ -200,7 +200,11 @@ install: fi if [ "$COMPILER" == "g++-6" ]; then - export CLING_BUILD_FLAGS="-DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON -DCXX_EXTENSIONS=OFF" + export CLING_BUILD_FLAGS="-DCMAKE_CXX_STANDARD=17 -DCMAKE_CXX_STANDARD_REQUIRED=ON" + # On OS X force the test to reproduce __float128 issues with libstdc++. + if [ $TRAVIS_OS_NAME != 'osx' ]; then + export CLING_BUILD_FLAGS="$CLING_BUILD_FLAGS -DCXX_EXTENSIONS=OFF" + fi CMAKEREQ="3.8" else CMAKEREQ="3.6"