diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
| commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
| tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /clang/lib/Tooling/Tooling.cpp | |
| parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'clang/lib/Tooling/Tooling.cpp')
| -rw-r--r-- | clang/lib/Tooling/Tooling.cpp | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index 79851ac723da..5242134097da 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -83,16 +83,20 @@ newDriver(DiagnosticsEngine *Diagnostics, const char *BinaryName, return CompilerDriver; } -/// Retrieves the clang CC1 specific flags out of the compilation's jobs. -/// -/// Returns nullptr on error. -static const llvm::opt::ArgStringList *getCC1Arguments( - DiagnosticsEngine *Diagnostics, driver::Compilation *Compilation) { - // We expect to get back exactly one Command job, if we didn't something - // failed. Extract that job from the Compilation. +/// Decide whether extra compiler frontend commands can be ignored. +static bool ignoreExtraCC1Commands(const driver::Compilation *Compilation) { const driver::JobList &Jobs = Compilation->getJobs(); const driver::ActionList &Actions = Compilation->getActions(); + bool OffloadCompilation = false; + + // Jobs and Actions look very different depending on whether the Clang tool + // injected -fsyntax-only or not. Try to handle both cases here. + + for (const auto &Job : Jobs) + if (StringRef(Job.getExecutable()) == "clang-offload-bundler") + OffloadCompilation = true; + if (Jobs.size() > 1) { for (auto A : Actions){ // On MacOSX real actions may end up being wrapped in BindArchAction @@ -117,8 +121,33 @@ static const llvm::opt::ArgStringList *getCC1Arguments( } } } - if (Jobs.size() == 0 || !isa<driver::Command>(*Jobs.begin()) || - (Jobs.size() > 1 && !OffloadCompilation)) { + + return OffloadCompilation; +} + +namespace clang { +namespace tooling { + +const llvm::opt::ArgStringList * +getCC1Arguments(DiagnosticsEngine *Diagnostics, + driver::Compilation *Compilation) { + const driver::JobList &Jobs = Compilation->getJobs(); + + auto IsCC1Command = [](const driver::Command &Cmd) { + return StringRef(Cmd.getCreator().getName()) == "clang"; + }; + + auto IsSrcFile = [](const driver::InputInfo &II) { + return isSrcFile(II.getType()); + }; + + llvm::SmallVector<const driver::Command *, 1> CC1Jobs; + for (const driver::Command &Job : Jobs) + if (IsCC1Command(Job) && llvm::all_of(Job.getInputInfos(), IsSrcFile)) + CC1Jobs.push_back(&Job); + + if (CC1Jobs.empty() || + (CC1Jobs.size() > 1 && !ignoreExtraCC1Commands(Compilation))) { SmallString<256> error_msg; llvm::raw_svector_ostream error_stream(error_msg); Jobs.Print(error_stream, "; ", true); @@ -127,19 +156,9 @@ static const llvm::opt::ArgStringList *getCC1Arguments( return nullptr; } - // The one job we find should be to invoke clang again. - const auto &Cmd = cast<driver::Command>(*Jobs.begin()); - if (StringRef(Cmd.getCreator().getName()) != "clang") { - Diagnostics->Report(diag::err_fe_expected_clang_command); - return nullptr; - } - - return &Cmd.getArguments(); + return &CC1Jobs[0]->getArguments(); } -namespace clang { -namespace tooling { - /// Returns a clang build invocation initialized from the CC1 flags. CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics, const llvm::opt::ArgStringList &CC1Args, @@ -334,6 +353,10 @@ bool ToolInvocation::run() { DiagnosticsEngine Diagnostics( IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), &*DiagOpts, DiagConsumer ? DiagConsumer : &DiagnosticPrinter, false); + // Although `Diagnostics` are used only for command-line parsing, the custom + // `DiagConsumer` might expect a `SourceManager` to be present. + SourceManager SrcMgr(Diagnostics, *Files); + Diagnostics.setSourceManager(&SrcMgr); const std::unique_ptr<driver::Driver> Driver( newDriver(&Diagnostics, BinaryName, &Files->getVirtualFileSystem())); @@ -440,8 +463,9 @@ static void injectResourceDir(CommandLineArguments &Args, const char *Argv0, return; // If there's no override in place add our resource dir. - Args.push_back("-resource-dir=" + - CompilerInvocation::GetResourcesPath(Argv0, MainAddr)); + Args = getInsertArgumentAdjuster( + ("-resource-dir=" + CompilerInvocation::GetResourcesPath(Argv0, MainAddr)) + .c_str())(Args, ""); } int ClangTool::run(ToolAction *Action) { |
