1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "clang/Frontend/Utils.h" |
14 | #include "clang/Basic/DiagnosticOptions.h" |
15 | #include "clang/Driver/Compilation.h" |
16 | #include "clang/Driver/Driver.h" |
17 | #include "clang/Driver/Action.h" |
18 | #include "clang/Driver/Options.h" |
19 | #include "clang/Driver/Tool.h" |
20 | #include "clang/Frontend/CompilerInstance.h" |
21 | #include "clang/Frontend/FrontendDiagnostic.h" |
22 | #include "llvm/Option/ArgList.h" |
23 | #include "llvm/Support/Host.h" |
24 | using namespace clang; |
25 | using namespace llvm::opt; |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | std::unique_ptr<CompilerInvocation> clang::createInvocationFromCommandLine( |
33 | ArrayRef<const char *> ArgList, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, |
34 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS) { |
35 | if (!Diags.get()) { |
36 | |
37 | |
38 | Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions); |
39 | } |
40 | |
41 | SmallVector<const char *, 16> Args(ArgList.begin(), ArgList.end()); |
42 | |
43 | |
44 | Args.push_back("-fsyntax-only"); |
45 | |
46 | |
47 | driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), |
48 | *Diags, VFS); |
49 | |
50 | |
51 | TheDriver.setCheckInputsExist(false); |
52 | |
53 | std::unique_ptr<driver::Compilation> C(TheDriver.BuildCompilation(Args)); |
54 | if (!C) |
55 | return nullptr; |
56 | |
57 | |
58 | if (C->getArgs().hasArg(driver::options::OPT__HASH_HASH_HASH)) { |
59 | C->getJobs().Print(llvm::errs(), "\n", true); |
60 | return nullptr; |
61 | } |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | const driver::JobList &Jobs = C->getJobs(); |
69 | bool OffloadCompilation = false; |
70 | if (Jobs.size() > 1) { |
71 | for (auto &A : C->getActions()){ |
72 | |
73 | if (isa<driver::BindArchAction>(A)) |
74 | A = *A->input_begin(); |
75 | if (isa<driver::OffloadAction>(A)) { |
76 | OffloadCompilation = true; |
77 | break; |
78 | } |
79 | } |
80 | } |
81 | if (Jobs.size() == 0 || !isa<driver::Command>(*Jobs.begin()) || |
82 | (Jobs.size() > 1 && !OffloadCompilation)) { |
83 | SmallString<256> Msg; |
84 | llvm::raw_svector_ostream OS(Msg); |
85 | Jobs.Print(OS, "; ", true); |
86 | Diags->Report(diag::err_fe_expected_compiler_job) << OS.str(); |
87 | return nullptr; |
88 | } |
89 | |
90 | const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin()); |
91 | if (StringRef(Cmd.getCreator().getName()) != "clang") { |
92 | Diags->Report(diag::err_fe_expected_clang_command); |
93 | return nullptr; |
94 | } |
95 | |
96 | const ArgStringList &CCArgs = Cmd.getArguments(); |
97 | auto CI = llvm::make_unique<CompilerInvocation>(); |
98 | if (!CompilerInvocation::CreateFromArgs(*CI, |
99 | const_cast<const char **>(CCArgs.data()), |
100 | const_cast<const char **>(CCArgs.data()) + |
101 | CCArgs.size(), |
102 | *Diags)) |
103 | return nullptr; |
104 | return CI; |
105 | } |
106 | |