Skip to content

Commit bfac216

Browse files
committed
Infer -target and --driver-mode from argv[0]
Fix #511
1 parent 3e04997 commit bfac216

File tree

1 file changed

+60
-11
lines changed

1 file changed

+60
-11
lines changed

src/clang_tu.cc

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
#include "platform.hh"
88

99
#include <clang/AST/Type.h>
10+
#include <clang/Driver/Action.h>
11+
#include <clang/Driver/Compilation.h>
12+
#include <clang/Driver/Driver.h>
13+
#include <clang/Driver/Tool.h>
1014
#include <clang/Lex/Lexer.h>
1115
#include <llvm/Support/Path.h>
1216

@@ -76,21 +80,66 @@ buildCompilerInvocation(const std::string &main, std::vector<const char *> args,
7680
IntrusiveRefCntPtr<llvm::vfs::FileSystem> vfs) {
7781
std::string save = "-resource-dir=" + g_config->clang.resourceDir;
7882
args.push_back(save.c_str());
83+
args.push_back("-fsyntax-only");
84+
85+
// Similar to clang/tools/driver/driver.cpp:insertTargetAndModeArgs but don't
86+
// require llvm::InitializeAllTargetInfos().
87+
auto target_and_mode =
88+
driver::ToolChain::getTargetAndModeFromProgramName(args[0]);
89+
if (target_and_mode.DriverMode)
90+
args.insert(args.begin() + 1, target_and_mode.DriverMode);
91+
if (!target_and_mode.TargetPrefix.empty()) {
92+
const char *arr[] = {"-target", target_and_mode.TargetPrefix.c_str()};
93+
args.insert(args.begin() + 1, std::begin(arr), std::end(arr));
94+
}
95+
7996
IntrusiveRefCntPtr<DiagnosticsEngine> diags(
8097
CompilerInstance::createDiagnostics(new DiagnosticOptions,
8198
new IgnoringDiagConsumer, true));
82-
std::unique_ptr<CompilerInvocation> ci =
83-
createInvocationFromCommandLine(args, diags, vfs);
84-
if (ci) {
85-
ci->getDiagnosticOpts().IgnoreWarnings = true;
86-
ci->getFrontendOpts().DisableFree = false;
87-
// Enable IndexFrontendAction::shouldSkipFunctionBody.
88-
ci->getFrontendOpts().SkipFunctionBodies = true;
89-
ci->getLangOpts()->SpellChecking = false;
90-
auto &isec = ci->getFrontendOpts().Inputs;
91-
if (isec.size())
92-
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem());
99+
driver::Driver d(args[0], llvm::sys::getDefaultTargetTriple(), *diags, vfs);
100+
d.setCheckInputsExist(false);
101+
std::unique_ptr<driver::Compilation> comp(d.BuildCompilation(args));
102+
if (!comp)
103+
return nullptr;
104+
const driver::JobList &jobs = comp->getJobs();
105+
bool offload_compilation = false;
106+
if (jobs.size() > 1) {
107+
for (auto &a : comp->getActions()){
108+
// On MacOSX real actions may end up being wrapped in BindArchAction
109+
if (isa<driver::BindArchAction>(a))
110+
a = *a->input_begin();
111+
if (isa<driver::OffloadAction>(a)) {
112+
offload_compilation = true;
113+
break;
114+
}
115+
}
116+
if (!offload_compilation)
117+
return nullptr;
93118
}
119+
if (jobs.size() == 0 || !isa<driver::Command>(*jobs.begin()))
120+
return nullptr;
121+
122+
const driver::Command &cmd = cast<driver::Command>(*jobs.begin());
123+
if (StringRef(cmd.getCreator().getName()) != "clang")
124+
return nullptr;
125+
const llvm::opt::ArgStringList &cc_args = cmd.getArguments();
126+
auto ci = std::make_unique<CompilerInvocation>();
127+
#if LLVM_VERSION_MAJOR >= 10 // rC370122
128+
if (!CompilerInvocation::CreateFromArgs(*ci, cc_args, *diags))
129+
#else
130+
if (!CompilerInvocation::CreateFromArgs(
131+
*ci, cc_args.data(), cc_args.data() + cc_args.size(), *diags))
132+
#endif
133+
return nullptr;
134+
135+
ci->getDiagnosticOpts().IgnoreWarnings = true;
136+
ci->getFrontendOpts().DisableFree = false;
137+
// Enable IndexFrontendAction::shouldSkipFunctionBody.
138+
ci->getFrontendOpts().SkipFunctionBodies = true;
139+
ci->getLangOpts()->SpellChecking = false;
140+
auto &isec = ci->getFrontendOpts().Inputs;
141+
if (isec.size())
142+
isec[0] = FrontendInputFile(main, isec[0].getKind(), isec[0].isSystem());
94143
return ci;
95144
}
96145

0 commit comments

Comments
 (0)