mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-21 23:25:07 +00:00
parent
5935db10fd
commit
0fe8a16504
@ -7,6 +7,10 @@
|
||||
#include "platform.hh"
|
||||
|
||||
#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 <llvm/Support/Host.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) {
|
||||
std::string save = "-resource-dir=" + g_config->clang.resourceDir;
|
||||
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(
|
||||
CompilerInstance::createDiagnostics(new DiagnosticOptions,
|
||||
new IgnoringDiagConsumer, true));
|
||||
std::unique_ptr<CompilerInvocation> ci =
|
||||
createInvocationFromCommandLine(args, diags, vfs);
|
||||
if (ci) {
|
||||
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());
|
||||
driver::Driver d(args[0], llvm::sys::getDefaultTargetTriple(), *diags, vfs);
|
||||
d.setCheckInputsExist(false);
|
||||
std::unique_ptr<driver::Compilation> comp(d.BuildCompilation(args));
|
||||
if (!comp)
|
||||
return nullptr;
|
||||
const driver::JobList &jobs = comp->getJobs();
|
||||
bool offload_compilation = false;
|
||||
if (jobs.size() > 1) {
|
||||
for (auto &a : comp->getActions()){
|
||||
// On MacOSX real actions may end up being wrapped in BindArchAction
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user