summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend
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/Frontend
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/Frontend')
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp16
-rw-r--r--clang/lib/Frontend/InitPreprocessor.cpp34
2 files changed, 36 insertions, 14 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index d55f969e0f4..3ea421c4992 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2250,6 +2250,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.Digraphs = Std.hasDigraphs();
Opts.GNUMode = Std.isGNUMode();
Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus;
+ Opts.GNUCVersion = 0;
Opts.HexFloats = Std.hasHexFloats();
Opts.ImplicitInt = Std.hasImplicitInt();
@@ -2574,6 +2575,21 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
(Opts.ObjCRuntime.getKind() == ObjCRuntime::FragileMacOSX);
}
+ 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.
+ VersionTuple GNUCVer;
+ bool Invalid = GNUCVer.tryParse(A->getValue());
+ unsigned Major = GNUCVer.getMajor();
+ unsigned Minor = GNUCVer.getMinor().getValueOr(0);
+ unsigned Patch = GNUCVer.getSubminor().getValueOr(0);
+ if (Invalid || GNUCVer.getBuild() || Minor >= 100 || Patch >= 100) {
+ Diags.Report(diag::err_drv_invalid_value)
+ << A->getAsString(Args) << A->getValue();
+ }
+ Opts.GNUCVersion = Major * 100 * 100 + Minor * 100 + Patch;
+ }
+
if (Args.hasArg(OPT_fgnu89_inline)) {
if (Opts.CPlusPlus)
Diags.Report(diag::err_drv_argument_not_allowed_with)
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 6a3c898d8c3..6810379c6ff 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -574,13 +574,22 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__clang_version__",
"\"" CLANG_VERSION_STRING " "
+ getClangFullRepositoryVersion() + "\"");
- if (!LangOpts.MSVCCompat) {
- // Currently claim to be compatible with GCC 4.2.1-5621, but only if we're
- // not compiling for MSVC compatibility
- Builder.defineMacro("__GNUC_MINOR__", "2");
- Builder.defineMacro("__GNUC_PATCHLEVEL__", "1");
- Builder.defineMacro("__GNUC__", "4");
+
+ if (LangOpts.GNUCVersion != 0) {
+ // Major, minor, patch, are given two decimal places each, so 4.2.1 becomes
+ // 40201.
+ unsigned GNUCMajor = LangOpts.GNUCVersion / 100 / 100;
+ unsigned GNUCMinor = LangOpts.GNUCVersion / 100 % 100;
+ unsigned GNUCPatch = LangOpts.GNUCVersion % 100;
+ Builder.defineMacro("__GNUC__", Twine(GNUCMajor));
+ Builder.defineMacro("__GNUC_MINOR__", Twine(GNUCMinor));
+ Builder.defineMacro("__GNUC_PATCHLEVEL__", Twine(GNUCPatch));
Builder.defineMacro("__GXX_ABI_VERSION", "1002");
+
+ if (LangOpts.CPlusPlus) {
+ Builder.defineMacro("__GNUG__", Twine(GNUCMajor));
+ Builder.defineMacro("__GXX_WEAK__");
+ }
}
// Define macros for the C11 / C++11 memory orderings
@@ -619,7 +628,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (!LangOpts.GNUMode && !LangOpts.MSVCCompat)
Builder.defineMacro("__STRICT_ANSI__");
- if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus11)
+ if (LangOpts.GNUCVersion && LangOpts.CPlusPlus11)
Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__");
if (LangOpts.ObjC) {
@@ -699,7 +708,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (!LangOpts.MSVCCompat && LangOpts.Exceptions)
Builder.defineMacro("__EXCEPTIONS");
- if (!LangOpts.MSVCCompat && LangOpts.RTTI)
+ if (LangOpts.GNUCVersion && LangOpts.RTTI)
Builder.defineMacro("__GXX_RTTI");
if (LangOpts.SjLjExceptions)
@@ -713,11 +722,8 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
if (LangOpts.Deprecated)
Builder.defineMacro("__DEPRECATED");
- if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus) {
- Builder.defineMacro("__GNUG__", "4");
- Builder.defineMacro("__GXX_WEAK__");
+ if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus)
Builder.defineMacro("__private_extern__", "extern");
- }
if (LangOpts.MicrosoftExt) {
if (LangOpts.WChar) {
@@ -927,7 +933,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
else
Builder.defineMacro("__FINITE_MATH_ONLY__", "0");
- if (!LangOpts.MSVCCompat) {
+ if (LangOpts.GNUCVersion) {
if (LangOpts.GNUInline || LangOpts.CPlusPlus)
Builder.defineMacro("__GNUC_GNU_INLINE__");
else
@@ -964,7 +970,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
#undef DEFINE_LOCK_FREE_MACRO
};
addLockFreeMacros("__CLANG_ATOMIC_");
- if (!LangOpts.MSVCCompat)
+ if (LangOpts.GNUCVersion)
addLockFreeMacros("__GCC_ATOMIC_");
if (LangOpts.NoInlineDefine)
OpenPOWER on IntegriCloud