If called as *cpp or *cpp-[^-]*, run only the preprocessor. If no
input is specified, use stdin implicitly. Based on a patch from
Roman Divacky.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127137 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 03fa0ef..dd91ea7 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -102,6 +102,9 @@
/// Whether the driver should follow g++ like behavior.
unsigned CCCIsCXX : 1;
+ /// Whether the driver is just the preprocessor
+ unsigned CCCIsCPP : 1;
+
/// Echo commands while executing (in -v style).
unsigned CCCEcho : 1;
@@ -221,7 +224,7 @@
/// \param TC - The default host tool chain.
/// \param Args - The input arguments.
/// \param Actions - The list to store the resulting actions onto.
- void BuildActions(const ToolChain &TC, const ArgList &Args,
+ void BuildActions(const ToolChain &TC, const InputArgList &Args,
ActionList &Actions) const;
/// BuildUniversalActions - Construct the list of actions to perform
@@ -230,7 +233,7 @@
/// \param TC - The default host tool chain.
/// \param Args - The input arguments.
/// \param Actions - The list to store the resulting actions onto.
- void BuildUniversalActions(const ToolChain &TC, const ArgList &Args,
+ void BuildUniversalActions(const ToolChain &TC, const InputArgList &Args,
ActionList &Actions) const;
/// BuildJobs - Bind actions to concrete tools and translate
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index ee225f2..c8300d3 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -308,10 +308,10 @@
// Construct the list of abstract actions to perform for this compilation.
if (Host->useDriverDriver())
- BuildUniversalActions(C->getDefaultToolChain(), C->getArgs(),
+ BuildUniversalActions(C->getDefaultToolChain(), C->getInputArgs(),
C->getActions());
else
- BuildActions(C->getDefaultToolChain(), C->getArgs(), C->getActions());
+ BuildActions(C->getDefaultToolChain(), C->getInputArgs(), C->getActions());
if (CCCPrintActions) {
PrintActions(*C);
@@ -593,7 +593,7 @@
}
void Driver::BuildUniversalActions(const ToolChain &TC,
- const ArgList &Args,
+ const InputArgList &Args,
ActionList &Actions) const {
llvm::PrettyStackTraceString CrashInfo("Building universal build actions");
// Collect the list of architectures. Duplicates are allowed, but should only
@@ -688,7 +688,7 @@
}
}
-void Driver::BuildActions(const ToolChain &TC, const ArgList &Args,
+void Driver::BuildActions(const ToolChain &TC, const InputArgList &Args,
ActionList &Actions) const {
llvm::PrettyStackTraceString CrashInfo("Building compilation actions");
// Start by constructing the list of inputs and their types.
@@ -721,7 +721,7 @@
//
// Otherwise emit an error but still use a valid type to avoid
// spurious errors (e.g., no inputs).
- if (!Args.hasArgNoClaim(options::OPT_E))
+ if (!Args.hasArgNoClaim(options::OPT_E) && !CCCIsCPP)
Diag(clang::diag::err_drv_unknown_stdin_type);
Ty = types::TY_C;
} else {
@@ -799,6 +799,15 @@
}
}
+ if (CCCIsCPP && Inputs.empty()) {
+ // If called as standalone preprocessor, stdin is processed
+ // if no other input is present.
+ unsigned Index = Args.MakeIndex("-");
+ Arg *A = Opts->ParseOneArg(Args, Index);
+ A->claim();
+ Inputs.push_back(std::make_pair(types::TY_C, A));
+ }
+
if (!SuppressMissingInputWarning && Inputs.empty()) {
Diag(clang::diag::err_drv_no_input_files);
return;
@@ -811,7 +820,8 @@
phases::ID FinalPhase;
// -{E,M,MM} only run the preprocessor.
- if ((FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
+ if (CCCIsCPP ||
+ (FinalPhaseArg = Args.getLastArg(options::OPT_E)) ||
(FinalPhaseArg = Args.getLastArg(options::OPT_M, options::OPT_MM))) {
FinalPhase = phases::Preprocess;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 2f6a4cc..68439ce 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -41,7 +41,7 @@
/// arguments that is shared with gcc.
static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) {
if (Arg *A = Args.getLastArg(options::OPT_C, options::OPT_CC))
- if (!Args.hasArg(options::OPT_E))
+ if (!Args.hasArg(options::OPT_E) && !D.CCCIsCPP)
D.Diag(clang::diag::err_drv_argument_only_allowed_with)
<< A->getAsString(Args) << "-E";
}
@@ -2403,7 +2403,7 @@
OutputArgs.push_back("-o");
OutputArgs.push_back(Output.getFilename());
- if (Args.hasArg(options::OPT_E)) {
+ if (Args.hasArg(options::OPT_E) || getToolChain().getDriver().CCCIsCPP) {
AddCPPOptionsArgs(Args, CmdArgs, Inputs, OutputArgs);
} else {
AddCPPOptionsArgs(Args, CmdArgs, Inputs, ArgStringList());
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 0b5d2c9..71baf8d 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -342,6 +342,11 @@
TheDriver.CCCIsCXX = true;
}
+ if (llvm::StringRef(ProgName).endswith("cpp") ||
+ llvm::StringRef(ProgName).rsplit('-').first.endswith("cpp")) {
+ TheDriver.CCCIsCPP = true;
+ }
+
// Handle CC_PRINT_OPTIONS and CC_PRINT_OPTIONS_FILE.
TheDriver.CCPrintOptions = !!::getenv("CC_PRINT_OPTIONS");
if (TheDriver.CCPrintOptions)