Browse Source

Infer -target and --driver-mode from argv[0]

Fix #511
pull/607/head
Fangrui Song 5 years ago
parent
commit
0fe8a16504
  1. 71
      src/clang_tu.cc

71
src/clang_tu.cc

@ -7,6 +7,10 @@
#include "platform.hh" #include "platform.hh"
#include <clang/AST/Type.h> #include <clang/AST/Type.h>
#include <clang/Driver/Action.h>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Driver/Tool.h>
#include <clang/Lex/Lexer.h> #include <clang/Lex/Lexer.h>
#include <llvm/Support/Host.h> #include <llvm/Support/Host.h>
#include <llvm/Support/Path.h> #include <llvm/Support/Path.h>
@ -77,21 +81,66 @@ buildCompilerInvocation(const std::string &main, std::vector<const char *> args,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs) { IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs) {
std::string save = "-resource-dir=" + g_config->clang.resourceDir; std::string save = "-resource-dir=" + g_config->clang.resourceDir;
args.push_back(save.c_str()); args.push_back(save.c_str());
args.push_back("-fsyntax-only");
// Similar to clang/tools/driver/driver.cpp:insertTargetAndModeArgs but don't
// require llvm::InitializeAllTargetInfos().
auto target_and_mode =
driver::ToolChain::getTargetAndModeFromProgramName(args[0]);
if (target_and_mode.DriverMode)
args.insert(args.begin() + 1, target_and_mode.DriverMode);
if (!target_and_mode.TargetPrefix.empty()) {
const char *arr[] = {"-target", target_and_mode.TargetPrefix.c_str()};
args.insert(args.begin() + 1, std::begin(arr), std::end(arr));
}
IntrusiveRefCntPtr<DiagnosticsEngine> diags( IntrusiveRefCntPtr<DiagnosticsEngine> diags(
CompilerInstance::createDiagnostics(new DiagnosticOptions, CompilerInstance::createDiagnostics(new DiagnosticOptions,
new IgnoringDiagConsumer, true)); new IgnoringDiagConsumer, true));
std::unique_ptr<CompilerInvocation> ci = driver::Driver d(args[0], llvm::sys::getDefaultTargetTriple(), *diags, vfs);
createInvocationFromCommandLine(args, diags, vfs); d.setCheckInputsExist(false);
if (ci) { std::unique_ptr<driver::Compilation> comp(d.BuildCompilation(args));
ci->getDiagnosticOpts().IgnoreWarnings = true; if (!comp)
ci->getFrontendOpts().DisableFree = false; return nullptr;
// Enable IndexFrontendAction::shouldSkipFunctionBody. const driver::JobList &jobs = comp->getJobs();
ci->getFrontendOpts().SkipFunctionBodies = true; bool offload_compilation = false;
ci->getLangOpts()->SpellChecking = false; if (jobs.size() > 1) {
auto &isec = ci->getFrontendOpts().Inputs; for (auto &a : comp->getActions()){
if (isec.size()) // On MacOSX real actions may end up being wrapped in BindArchAction
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem()); if (isa<driver::BindArchAction>(a))
a = *a->input_begin();
if (isa<driver::OffloadAction>(a)) {
offload_compilation = true;
break;
}
}
if (!offload_compilation)
return nullptr;
} }
if (jobs.size() == 0 || !isa<driver::Command>(*jobs.begin()))
return nullptr;
const driver::Command &cmd = cast<driver::Command>(*jobs.begin());
if (StringRef(cmd.getCreator().getName()) != "clang")
return nullptr;
const llvm::opt::ArgStringList &cc_args = cmd.getArguments();
auto ci = std::make_unique<CompilerInvocation>();
#if LLVM_VERSION_MAJOR >= 10 // rC370122
if (!CompilerInvocation::CreateFromArgs(*ci, cc_args, *diags))
#else
if (!CompilerInvocation::CreateFromArgs(
*ci, cc_args.data(), cc_args.data() + cc_args.size(), *diags))
#endif
return nullptr;
ci->getDiagnosticOpts().IgnoreWarnings = true;
ci->getFrontendOpts().DisableFree = false;
// Enable IndexFrontendAction::shouldSkipFunctionBody.
ci->getFrontendOpts().SkipFunctionBodies = true;
ci->getLangOpts()->SpellChecking = false;
auto &isec = ci->getFrontendOpts().Inputs;
if (isec.size())
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem());
return ci; return ci;
} }

Loading…
Cancel
Save