summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Driver/Types.h5
-rw-r--r--clang/lib/Driver/Driver.cpp16
-rw-r--r--clang/lib/Driver/Types.cpp56
3 files changed, 67 insertions, 10 deletions
diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h
index b7041ba65a9..a605450e6e3 100644
--- a/clang/include/clang/Driver/Types.h
+++ b/clang/include/clang/Driver/Types.h
@@ -11,12 +11,14 @@
#include "clang/Driver/Phases.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Option/ArgList.h"
namespace llvm {
class StringRef;
}
namespace clang {
namespace driver {
+class Driver;
namespace types {
enum ID {
TY_INVALID,
@@ -100,6 +102,9 @@ namespace types {
void getCompilationPhases(
ID Id,
llvm::SmallVectorImpl<phases::ID> &Phases);
+ void getCompilationPhases(const clang::driver::Driver &Driver,
+ llvm::opt::DerivedArgList &DAL, ID Id,
+ llvm::SmallVectorImpl<phases::ID> &Phases);
/// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given
/// C type (used for clang++ emulation of g++ behaviour)
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 209cbc8ec95..6d673e75db3 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -3217,10 +3217,9 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
HeaderModulePrecompileJobAction *HeaderModuleAction = nullptr;
ActionList LinkerInputs;
- phases::ID FinalPhase;
{
Arg *FinalPhaseArg;
- FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
+ phases::ID FinalPhase = getFinalPhase(Args, &FinalPhaseArg);
if (FinalPhase == phases::Link) {
if (Args.hasArg(options::OPT_emit_llvm))
@@ -3323,10 +3322,13 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
const Arg *InputArg = I.second;
llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PL;
- types::getCompilationPhases(InputType, PL);
- if (PL[0] > FinalPhase)
+ types::getCompilationPhases(*this, Args, InputType, PL);
+ if (PL.empty())
continue;
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> FullPL;
+ types::getCompilationPhases(InputType, FullPL);
+
// Build the pipeline for this file.
Action *Current = C.MakeAction<InputAction>(*InputArg, InputType);
@@ -3337,13 +3339,9 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
for (phases::ID Phase : PL) {
- // We are done if this step is past what the user requested.
- if (Phase > FinalPhase)
- break;
-
// Add any offload action the host action depends on.
Current = OffloadBuilder.addDeviceDependencesToHostAction(
- Current, InputArg, Phase, FinalPhase, PL);
+ Current, InputArg, Phase, PL.back(), FullPL);
if (!Current)
break;
diff --git a/clang/lib/Driver/Types.cpp b/clang/lib/Driver/Types.cpp
index 8c3f23789c1..d83935cdaf9 100644
--- a/clang/lib/Driver/Types.cpp
+++ b/clang/lib/Driver/Types.cpp
@@ -7,9 +7,13 @@
//===----------------------------------------------------------------------===//
#include "clang/Driver/Types.h"
+#include "clang/Driver/Driver.h"
+#include "clang/Driver/DriverDiagnostic.h"
+#include "clang/Driver/Options.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Option/Arg.h"
#include <cassert>
#include <cstring>
@@ -293,6 +297,56 @@ void types::getCompilationPhases(ID Id, llvm::SmallVectorImpl<phases::ID> &P) {
assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list");
}
+void types::getCompilationPhases(const clang::driver::Driver &Driver,
+ llvm::opt::DerivedArgList &DAL, ID Id,
+ llvm::SmallVectorImpl<phases::ID> &P) {
+ llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> PhaseList;
+ types::getCompilationPhases(Id, PhaseList);
+
+ // Filter to compiler mode. When the compiler is run as a preprocessor then
+ // compilation is not an option.
+ // -S runs the compiler in Assembly listing mode.
+ if (Driver.CCCIsCPP() || DAL.getLastArg(options::OPT_E) ||
+ DAL.getLastArg(options::OPT__SLASH_EP) ||
+ DAL.getLastArg(options::OPT_M, options::OPT_MM) ||
+ DAL.getLastArg(options::OPT__SLASH_P))
+ llvm::copy_if(PhaseList, std::back_inserter(P),
+ [](phases::ID Phase) { return Phase <= phases::Preprocess; });
+
+ // --precompile only runs up to precompilation.
+ // This is a clang extension and is not compatible with GCC.
+ else if (DAL.getLastArg(options::OPT__precompile))
+ llvm::copy_if(PhaseList, std::back_inserter(P),
+ [](phases::ID Phase) { return Phase <= phases::Precompile; });
+
+ // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
+ else if (DAL.getLastArg(options::OPT_fsyntax_only) ||
+ DAL.getLastArg(options::OPT_print_supported_cpus) ||
+ DAL.getLastArg(options::OPT_module_file_info) ||
+ DAL.getLastArg(options::OPT_verify_pch) ||
+ DAL.getLastArg(options::OPT_rewrite_objc) ||
+ DAL.getLastArg(options::OPT_rewrite_legacy_objc) ||
+ DAL.getLastArg(options::OPT__migrate) ||
+ DAL.getLastArg(options::OPT_emit_iterface_stubs) ||
+ DAL.getLastArg(options::OPT__analyze, options::OPT__analyze_auto) ||
+ DAL.getLastArg(options::OPT_emit_ast))
+ llvm::copy_if(PhaseList, std::back_inserter(P),
+ [](phases::ID Phase) { return Phase <= phases::Compile; });
+
+ else if (DAL.getLastArg(options::OPT_S) ||
+ DAL.getLastArg(options::OPT_emit_llvm))
+ llvm::copy_if(PhaseList, std::back_inserter(P),
+ [](phases::ID Phase) { return Phase <= phases::Backend; });
+
+ else if (DAL.getLastArg(options::OPT_c))
+ llvm::copy_if(PhaseList, std::back_inserter(P),
+ [](phases::ID Phase) { return Phase <= phases::Assemble; });
+
+ // Generally means, do every phase until Link.
+ else
+ P = PhaseList;
+}
+
ID types::lookupCXXTypeForCType(ID Id) {
switch (Id) {
default:
OpenPOWER on IntegriCloud