summaryrefslogtreecommitdiffstats
path: root/clang/include
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2016-03-01 23:16:44 +0000
committerNico Weber <nicolasweber@gmx.de>2016-03-01 23:16:44 +0000
commit2ca4be97de0f8ff3fe51a4bf48a7d26922818482 (patch)
tree8bb195a267010aa38407fa370a5d2f03b1cf8b4d /clang/include
parent1012be120a17ca7693624e9ec63e7399d6d5e330 (diff)
downloadbcm5719-llvm-2ca4be97de0f8ff3fe51a4bf48a7d26922818482.tar.gz
bcm5719-llvm-2ca4be97de0f8ff3fe51a4bf48a7d26922818482.zip
clang-cl: Implement initial limited support for precompiled headers.
In the gcc precompiled header model, one explicitly runs clang with `-x c++-header` on a .h file to produce a gch file, and then includes the header with `-include foo.h` and if a .gch file exists for that header it gets used. This is documented at http://clang.llvm.org/docs/UsersManual.html#precompiled-headers cl.exe's model is fairly different, and controlled by the two flags /Yc and /Yu. A pch file is generated as a side effect of a regular compilation when /Ycheader.h is passed. While the compilation is running, the compiler keeps track of #include lines in the main translation unit and writes everything up to an `#include "header.h"` line into a pch file. Conversely, /Yuheader.h tells the compiler to skip all code in the main TU up to and including `#include "header.h"` and instead load header.pch. (It's also possible to use /Yc and /Yu without an argument, in that case a `#pragma hrdstop` takes the role of controlling the point where pch ends and real code begins.) This patch implements limited support for this in that it requires the pch header to be passed as a /FI force include flag – with this restriction, it can be implemented almost completely in the driver with fairly small amounts of code. For /Yu, this is trivial, and for /Yc a separate pch action is added that runs before the actual compilation. After r261774, the first failing command makes a compilation stop – this means if the pch fails to build the main compilation won't run, which is what we want. However, in /fallback builds we need to run the main compilation even if the pch build fails so that the main compilation's fallback can run. To achieve this, add a ForceSuccessCommand that pretends that the pch build always succeeded in /fallback builds (the main compilation will then fail to open the pch and run the fallback cl.exe invocation). If /Yc /Yu are used in a setup that clang-cl doesn't implement yet, clang-cl will now emit a "not implemented yet; flag ignored" warning that can be disabled using -Wno-clang-cl-pch. Since clang-cl doesn't yet serialize some important things (most notably `pragma comment(lib, ...)`, this feature is disabled by default and only enabled by an internal driver flag. Once it's more stable, this internal flag will disappear. (The default stdafx.h setup passes stdafx.h as explicit argument to /Yc but not as /FI – instead every single TU has to `#include <stdafx.h>` as first thing it does. Implementing support for this should be possible with the approach in this patch with minimal frontend changes by passing a --stop-at / --start-at flag from the driver to the frontend. This is left for a follow-up. I don't think we ever want to support `#pragma hdrstop`, and supporting it with this approach isn't easy: This approach relies on the driver knowing the pch filename in advance, and `#pragma hdrstop(out.pch)` can set the output filename, so the driver can't know about it in advance.) clang-cl now also honors /Fp and puts pch files in the same spot that cl.exe would put them, but the pch file format is of course incompatible. This has ramifications on /fallback, so /Yc /Yu aren't passed through to cl.exe in /fallback builds. http://reviews.llvm.org/D17695 llvm-svn: 262420
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/Basic/DiagnosticDriverKinds.td14
-rw-r--r--clang/include/clang/Basic/DiagnosticGroups.td2
-rw-r--r--clang/include/clang/Driver/CC1Options.td4
-rw-r--r--clang/include/clang/Driver/CLCompatOptions.td27
-rw-r--r--clang/include/clang/Driver/Driver.h3
-rw-r--r--clang/include/clang/Driver/Job.h14
-rw-r--r--clang/include/clang/Frontend/CompilerInstance.h9
-rw-r--r--clang/include/clang/Frontend/FrontendOptions.h4
8 files changed, 69 insertions, 8 deletions
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index c6e6eaf47cc..ce455ae9768 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -98,6 +98,20 @@ def err_drv_unknown_argument : Error<"unknown argument: '%0'">;
def warn_drv_unknown_argument_clang_cl : Warning<
"unknown argument ignored in clang-cl: '%0'">,
InGroup<UnknownArgument>;
+
+def warn_drv_ycyu_no_arg_clang_cl : Warning<
+ "support for '%0' without a filename not implemented yet; flag ignored">,
+ InGroup<ClangClPch>;
+def warn_drv_ycyu_different_arg_clang_cl : Warning<
+ "support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored">,
+ InGroup<ClangClPch>;
+def warn_drv_ycyu_no_fi_arg_clang_cl : Warning<
+ "support for '%0' without a corresponding /FI flag not implemented yet; flag ignored">,
+ InGroup<ClangClPch>;
+def warn_drv_yc_multiple_inputs_clang_cl : Warning<
+ "support for '/Yc' with more than one source file not implemented yet; flag ignored">,
+ InGroup<ClangClPch>;
+
def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">;
def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">;
def err_drv_invalid_remap_file : Error<
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 969050df596..e5d8794b555 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -785,6 +785,8 @@ def Microsoft : DiagGroup<"microsoft",
MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag,
MicrosoftCommentPaste, MicrosoftEndOfFile]>;
+def ClangClPch : DiagGroup<"clang-cl-pch">;
+
def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">;
def ObjCProtocolMethodImpl : DiagGroup<"objc-protocol-method-implementation">;
diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td
index d6905db9625..66a8acf2c68 100644
--- a/clang/include/clang/Driver/CC1Options.td
+++ b/clang/include/clang/Driver/CC1Options.td
@@ -495,6 +495,10 @@ def fixit_to_temp : Flag<["-"], "fixit-to-temporary">,
def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">,
HelpText<"Override record layouts with those in the given file">;
+def find_pch_source_EQ : Joined<["-"], "find-pch-source=">,
+ HelpText<"When building a pch, try to find the input file in include "
+ "directories, as if it had been included by the argument passed "
+ "to this flag.">;
//===----------------------------------------------------------------------===//
// Language Options
diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td
index dbd25f57233..d7c84134e24 100644
--- a/clang/include/clang/Driver/CLCompatOptions.td
+++ b/clang/include/clang/Driver/CLCompatOptions.td
@@ -20,6 +20,9 @@ def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">,
def cl_ignored_Group : OptionGroup<"<clang-cl ignored options>">,
Group<cl_Group>;
+def cl_internal_Group : OptionGroup<"<clang-cl internal options>">,
+ Group<cl_Group>;
+
class CLFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
Group<cl_Group>, Flags<[CLOption, DriverOption]>;
@@ -29,6 +32,9 @@ class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>,
Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>;
+class CLInternalFlag<string name> : Option<["-"], name, KIND_FLAG>,
+ Group<cl_internal_Group>, Flags<[CLOption, DriverOption, HelpHidden]>;
+
class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>,
Group<cl_Group>, Flags<[CLOption, DriverOption]>;
@@ -252,6 +258,23 @@ def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>,
def _SLASH_Zl : CLFlag<"Zl">,
HelpText<"Don't mention any default libraries in the object file">;
+def _SLASH_Yc : CLJoined<"Yc">,
+ HelpText<"Generate a pch file for all code up to and including <filename>">,
+ MetaVarName<"<filename>">;
+def _SLASH_Yu : CLJoined<"Yu">,
+ HelpText<"Load a pch file and use it instead of all code up to "
+ "and including <filename>">,
+ MetaVarName<"<filename>">;
+def _SLASH_Y_ : CLFlag<"Y-">,
+ HelpText<"Disable precompiled headers, overrides /Yc and /Yu">;
+def _SLASH_Fp : CLJoined<"Fp">,
+ HelpText<"Set pch filename (with /Yc and /Yu)">, MetaVarName<"<filename>">;
+
+// Internal:
+// FIXME: Once /Yc support is stable enough, turn it on by default (when /Yc
+// is passed) and remove this flag.
+def _SLASH_internal_enable_pch : CLInternalFlag<"internal-enable-pch">;
+
// Ignored:
def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">;
@@ -294,7 +317,6 @@ def _SLASH_favor : CLJoined<"favor">;
def _SLASH_FC : CLFlag<"FC">;
def _SLASH_F : CLFlag<"F">;
def _SLASH_Fm : CLJoined<"Fm">;
-def _SLASH_Fp : CLJoined<"Fp">;
def _SLASH_Fr : CLJoined<"Fr">;
def _SLASH_FR : CLJoined<"FR">;
def _SLASH_FU : CLJoinedOrSeparate<"FU">;
@@ -332,11 +354,8 @@ def _SLASH_V : CLFlag<"V">;
def _SLASH_WL : CLFlag<"WL">;
def _SLASH_Wp64 : CLFlag<"Wp64">;
def _SLASH_X : CLFlag<"X">;
-def _SLASH_Yc : CLJoined<"Yc">;
-def _SLASH_Y_ : CLFlag<"Y-">;
def _SLASH_Yd : CLFlag<"Yd">;
def _SLASH_Yl : CLJoined<"Yl">;
-def _SLASH_Yu : CLJoined<"Yu">;
def _SLASH_Za : CLFlag<"Za">;
def _SLASH_Zc : CLJoined<"Zc:">;
def _SLASH_Ze : CLFlag<"Ze">;
diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h
index ccf23e04696..f0924946e84 100644
--- a/clang/include/clang/Driver/Driver.h
+++ b/clang/include/clang/Driver/Driver.h
@@ -423,6 +423,9 @@ public:
/// GCC goes to extra lengths here to be a bit more robust.
std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const;
+ /// Return the pathname of the pch file in clang-cl mode.
+ std::string GetClPchPath(Compilation &C, StringRef BaseName) const;
+
/// ShouldUseClangCompiler - Should the clang compiler be used to
/// handle this action.
bool ShouldUseClangCompiler(const JobAction &JA) const;
diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h
index 263356f396f..3366fc48d71 100644
--- a/clang/include/clang/Driver/Job.h
+++ b/clang/include/clang/Driver/Job.h
@@ -138,6 +138,20 @@ private:
std::unique_ptr<Command> Fallback;
};
+/// Like Command, but always pretends that the wrapped command succeeded.
+class ForceSuccessCommand : public Command {
+public:
+ ForceSuccessCommand(const Action &Source_, const Tool &Creator_,
+ const char *Executable_, const ArgStringList &Arguments_,
+ ArrayRef<InputInfo> Inputs);
+
+ void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote,
+ CrashReportInfo *CrashInfo = nullptr) const override;
+
+ int Execute(const StringRef **Redirects, std::string *ErrMsg,
+ bool *ExecutionFailed) const override;
+};
+
/// JobList - A sequence of jobs to perform.
class JobList {
public:
diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h
index 83eed2cdc59..fe36eeee2e6 100644
--- a/clang/include/clang/Frontend/CompilerInstance.h
+++ b/clang/include/clang/Frontend/CompilerInstance.h
@@ -748,10 +748,11 @@ public:
///
/// \return True on success.
static bool InitializeSourceManager(const FrontendInputFile &Input,
- DiagnosticsEngine &Diags,
- FileManager &FileMgr,
- SourceManager &SourceMgr,
- const FrontendOptions &Opts);
+ DiagnosticsEngine &Diags,
+ FileManager &FileMgr,
+ SourceManager &SourceMgr,
+ HeaderSearch *HS,
+ const FrontendOptions &Opts);
/// }
diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h
index c800a5148e4..71c08ec9c63 100644
--- a/clang/include/clang/Frontend/FrontendOptions.h
+++ b/clang/include/clang/Frontend/FrontendOptions.h
@@ -266,6 +266,10 @@ public:
/// \brief Auxiliary triple for CUDA compilation.
std::string AuxTriple;
+ /// \brief If non-empty, search the pch input file as it was a header
+ // included by this file.
+ std::string FindPchSource;
+
public:
FrontendOptions() :
DisableFree(false), RelocatablePCH(false), ShowHelp(false),
OpenPOWER on IntegriCloud