summaryrefslogtreecommitdiffstats
path: root/clang/lib/Driver/ToolChains/Clang.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-10-10 21:04:25 +0000
committerReid Kleckner <rnk@google.com>2019-10-10 21:04:25 +0000
commit5e866e411caad4c4e17e7e0c67b06d28451e1bf2 (patch)
tree1ae51b6ec80724b28ad4c849dde12661289f3917 /clang/lib/Driver/ToolChains/Clang.cpp
parent53a53e63c85e53e70ea208a38d4efa9b90fb5f42 (diff)
downloadbcm5719-llvm-5e866e411caad4c4e17e7e0c67b06d28451e1bf2.tar.gz
bcm5719-llvm-5e866e411caad4c4e17e7e0c67b06d28451e1bf2.zip
Add -fgnuc-version= to control __GNUC__ and other GCC macros
I noticed that compiling on Windows with -fno-ms-compatibility had the side effect of defining __GNUC__, along with __GNUG__, __GXX_RTTI__, and a number of other macros for GCC compatibility. This is undesirable and causes Chromium to do things like mix __attribute__ and __declspec, which doesn't work. We should have a positive language option to enable GCC compatibility features so that we can experiment with -fno-ms-compatibility on Windows. This change adds -fgnuc-version= to be that option. My issue aside, users have, for a long time, reported that __GNUC__ doesn't match their expectations in one way or another. We have encouraged users to migrate code away from this macro, but new code continues to be written assuming a GCC-only environment. There's really nothing we can do to stop that. By adding this flag, we can allow them to choose their own adventure with __GNUC__. This overlaps a bit with the "GNUMode" language option from -std=gnu*. The gnu language mode tends to enable non-conforming behaviors that we'd rather not enable by default, but the we want to set things like __GXX_RTTI__ by default, so I've kept these separate. Helps address PR42817 Reviewed By: hans, nickdesaulniers, MaskRay Differential Revision: https://reviews.llvm.org/D68055 llvm-svn: 374449
Diffstat (limited to 'clang/lib/Driver/ToolChains/Clang.cpp')
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp33
1 files changed, 28 insertions, 5 deletions
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 22b830ee838..154e3a86429 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4875,13 +4875,36 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fuse-line-directives");
// -fms-compatibility=0 is default.
- if (Args.hasFlag(options::OPT_fms_compatibility,
- options::OPT_fno_ms_compatibility,
- (IsWindowsMSVC &&
- Args.hasFlag(options::OPT_fms_extensions,
- options::OPT_fno_ms_extensions, true))))
+ bool IsMSVCCompat = Args.hasFlag(
+ options::OPT_fms_compatibility, options::OPT_fno_ms_compatibility,
+ (IsWindowsMSVC && Args.hasFlag(options::OPT_fms_extensions,
+ options::OPT_fno_ms_extensions, true)));
+ if (IsMSVCCompat)
CmdArgs.push_back("-fms-compatibility");
+ // Handle -fgcc-version, if present.
+ VersionTuple GNUCVer;
+ if (Arg *A = Args.getLastArg(options::OPT_fgnuc_version_EQ)) {
+ // Check that the version has 1 to 3 components and the minor and patch
+ // versions fit in two decimal digits.
+ StringRef Val = A->getValue();
+ Val = Val.empty() ? "0" : Val; // Treat "" as 0 or disable.
+ bool Invalid = GNUCVer.tryParse(Val);
+ unsigned Minor = GNUCVer.getMinor().getValueOr(0);
+ unsigned Patch = GNUCVer.getSubminor().getValueOr(0);
+ if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
+ D.Diag(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ } else if (!IsMSVCCompat) {
+ // Imitate GCC 4.2.1 by default if -fms-compatibility is not in effect.
+ GNUCVer = VersionTuple(4, 2, 1);
+ }
+ if (!GNUCVer.empty()) {
+ CmdArgs.push_back(
+ Args.MakeArgString("-fgnuc-version=" + GNUCVer.getAsString()));
+ }
+
VersionTuple MSVT = TC.computeMSVCVersion(&D, Args);
if (!MSVT.empty())
CmdArgs.push_back(
OpenPOWER on IntegriCloud