diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Driver/Job.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Linux.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Linux.h | 2 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 16 |
5 files changed, 35 insertions, 1 deletions
diff --git a/clang/lib/Driver/Job.cpp b/clang/lib/Driver/Job.cpp index 765c05752d8..b494bc75282 100644 --- a/clang/lib/Driver/Job.cpp +++ b/clang/lib/Driver/Job.cpp @@ -64,7 +64,7 @@ static bool skipArgs(const char *Flag, bool HaveCrashVFS, int &SkipNum, .Cases("-internal-externc-isystem", "-iprefix", true) .Cases("-iwithprefixbefore", "-isystem", "-iquote", true) .Cases("-isysroot", "-I", "-F", "-resource-dir", true) - .Cases("-iframework", "-include-pch", true) + .Cases("-iframework", "-include-pch", "-fsystem-include-if-exists", true) .Default(false); if (IsInclude) return HaveCrashVFS ? false : true; diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp index 1301cdf114a..5c3697391d5 100644 --- a/clang/lib/Driver/ToolChains/Linux.cpp +++ b/clang/lib/Driver/ToolChains/Linux.cpp @@ -710,6 +710,8 @@ void Linux::AddClangSystemIncludeArgs(const ArgList &DriverArgs, addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/include"); addExternCSystemInclude(DriverArgs, CC1Args, SysRoot + "/usr/include"); + + AddGnuIncludeArgs(DriverArgs, CC1Args); } static std::string DetectLibcxxIncludePath(StringRef base) { @@ -748,6 +750,16 @@ std::string Linux::findLibCxxIncludePath() const { return ""; } +void Linux::AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + if (!DriverArgs.hasArg(options::OPT_ffreestanding)) { + // For gcc compatibility, clang will preinclude <stdc-predef.h> + // -ffreestanding suppresses this behavior. + CC1Args.push_back("-fsystem-include-if-exists"); + CC1Args.push_back("stdc-predef.h"); + } +} + void Linux::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { // We need a detected GCC installation on Linux to provide libstdc++'s diff --git a/clang/lib/Driver/ToolChains/Linux.h b/clang/lib/Driver/ToolChains/Linux.h index 9778c1832cc..8b7e2e2ad53 100644 --- a/clang/lib/Driver/ToolChains/Linux.h +++ b/clang/lib/Driver/ToolChains/Linux.h @@ -31,6 +31,8 @@ public: void addLibStdCxxIncludePaths( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; + void AddGnuIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 2ebdc2a62aa..60802da921b 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -2611,6 +2611,10 @@ static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args, for (const Arg *A : Args.filtered(OPT_chain_include)) Opts.ChainedIncludes.emplace_back(A->getValue()); + // Add the ordered list of -fsystem-include-if-exists. + for (const Arg *A : Args.filtered(OPT_fsystem_include_if_exists)) + Opts.FSystemIncludeIfExists.emplace_back(A->getValue()); + for (const Arg *A : Args.filtered(OPT_remap_file)) { std::pair<StringRef, StringRef> Split = StringRef(A->getValue()).split(';'); diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index d3989049432..45760ae15e4 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -70,6 +70,15 @@ static void AddImplicitInclude(MacroBuilder &Builder, StringRef File) { Builder.append(Twine("#include \"") + File + "\""); } +/// AddImplicitSystemIncludeIfExists - Add an implicit system \#include of the +/// specified file to the predefines buffer: precheck with __has_include. +static void AddImplicitSystemIncludeIfExists(MacroBuilder &Builder, + StringRef File) { + Builder.append(Twine("#if __has_include( <") + File + ">)"); + Builder.append(Twine("#include <") + File + ">"); + Builder.append(Twine("#endif")); +} + static void AddImplicitIncludeMacros(MacroBuilder &Builder, StringRef File) { Builder.append(Twine("#__include_macros \"") + File + "\""); // Marker token to stop the __include_macros fetch loop. @@ -1133,6 +1142,13 @@ void clang::InitializePreprocessor( if (!PP.getLangOpts().AsmPreprocessor) Builder.append("# 1 \"<built-in>\" 2"); + // Process -fsystem-include-if-exists directives. + for (unsigned i = 0, + e = InitOpts.FSystemIncludeIfExists.size(); i != e; ++i) { + const std::string &Path = InitOpts.FSystemIncludeIfExists[i]; + AddImplicitSystemIncludeIfExists(Builder, Path); + } + // If -imacros are specified, include them now. These are processed before // any -include directives. for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i) |