clang: lib/Interpreter/Interpreter.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
18#include "llvm/Support/VirtualFileSystem.h"
19#ifdef __EMSCRIPTEN__
21#endif
22
47#include "llvm/ExecutionEngine/JITSymbol.h"
48#include "llvm/ExecutionEngine/Orc/LLJIT.h"
49#include "llvm/IR/Module.h"
50#include "llvm/Support/Errc.h"
51#include "llvm/Support/ErrorHandling.h"
52#include "llvm/Support/raw_ostream.h"
53#include "llvm/TargetParser/Host.h"
54#include "llvm/Transforms/Utils/Cloning.h"
55
56#define DEBUG_TYPE "clang-repl"
57
58using namespace clang;
59
60
61namespace {
62
63
67
68
70 if (!Jobs.size() || !isadriver::Command(*Jobs.begin()))
71 return llvm::createStringError(llvm::errc::not_supported,
72 "Driver initialization failed. "
73 "Unable to create a driver job");
74
75
77 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
78 return llvm::createStringError(llvm::errc::not_supported,
79 "Driver initialization failed");
80
81 return &Cmd->getArguments();
82}
83
85CreateCI(const llvm::opt::ArgStringList &Argv) {
86 std::unique_ptr Clang(new CompilerInstance());
88
89
90
91 auto PCHOps = Clang->getPCHContainerOperations();
92 PCHOps->registerWriter(std::make_unique());
93 PCHOps->registerReader(std::make_unique());
94
95
96
101 Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
102
103
104 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
105 Clang->getHeaderSearchOpts().ResourceDir.empty())
106 Clang->getHeaderSearchOpts().ResourceDir =
108
109
110 Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
111 if (!Clang->hasDiagnostics())
112 return llvm::createStringError(llvm::errc::not_supported,
113 "Initialization failed. "
114 "Unable to create diagnostics engine");
115
118 return llvm::createStringError(llvm::errc::not_supported,
119 "Initialization failed. "
120 "Unable to flush diagnostics");
121
122
123 llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release();
124 Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
125
127 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
128 if (!Clang->hasTarget())
129 return llvm::createStringError(llvm::errc::not_supported,
130 "Initialization failed. "
131 "Target is missing");
132
133 Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts());
134
135
136
137 Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
138
139 Clang->getFrontendOpts().DisableFree = false;
140 Clang->getCodeGenOpts().DisableFree = false;
141 return std::move(Clang);
142}
143
144}
145
147
149IncrementalCompilerBuilder::create(std::string TT,
150 std::vector<const char *> &ClangArgv) {
151
152
153
154 std::string MainExecutableName =
155 llvm::sys::fs::getMainExecutable(nullptr, nullptr);
156
157 ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
158
159
160
161
162
163
164 ClangArgv.insert(ClangArgv.end(), "-Xclang");
165 ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions");
166 ClangArgv.insert(ClangArgv.end(), "-c");
167
168
169
170 ClangArgv.push_back("<<< inputs >>>");
171
172
173
179
181 Driver.setCheckInputsExist(false);
183 std::unique_ptrdriver::Compilation Compilation(Driver.BuildCompilation(RF));
184
185 if (Compilation->getArgs().hasArg(driver::options::OPT_v))
186 Compilation->getJobs().Print(llvm::errs(), "\n", false);
187
188 auto ErrOrCC1Args = GetCC1Arguments(&Diags, Compilation.get());
189 if (auto Err = ErrOrCC1Args.takeError())
190 return std::move(Err);
191
192 return CreateCI(**ErrOrCC1Args);
193}
194
197 std::vector<const char *> Argv;
198 Argv.reserve(5 + 1 + UserArgs.size());
199 Argv.push_back("-xc++");
200#ifdef __EMSCRIPTEN__
201 Argv.push_back("-target");
202 Argv.push_back("wasm32-unknown-emscripten");
203 Argv.push_back("-fvisibility=default");
204#endif
205 Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
206
207 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
208 return IncrementalCompilerBuilder::create(TT, Argv);
209}
210
212IncrementalCompilerBuilder::createCuda(bool device) {
213 std::vector<const char *> Argv;
214 Argv.reserve(5 + 4 + UserArgs.size());
215
216 Argv.push_back("-xcuda");
217 if (device)
218 Argv.push_back("--cuda-device-only");
219 else
220 Argv.push_back("--cuda-host-only");
221
222 std::string SDKPathArg = "--cuda-path=";
223 if (!CudaSDKPath.empty()) {
224 SDKPathArg += CudaSDKPath;
225 Argv.push_back(SDKPathArg.c_str());
226 }
227
228 std::string ArchArg = "--offload-arch=";
231 Argv.push_back(ArchArg.c_str());
232 }
233
234 Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end());
235
236 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
237 return IncrementalCompilerBuilder::create(TT, Argv);
238}
239
242 return IncrementalCompilerBuilder::createCuda(true);
243}
244
247 return IncrementalCompilerBuilder::createCuda(false);
248}
249
252
253public:
257 if (DGR.isNull())
258 return true;
259
261 if (auto *TLSD = llvm::dyn_cast(D))
262 if (TLSD && TLSD->isSemiMissing()) {
263 auto ExprOrErr =
264 Interp.ExtractValueFromExpr(cast(TLSD->getStmt()));
265 if (llvm::Error E = ExprOrErr.takeError()) {
266 llvm::logAllUnhandledErrors(std::move(E), llvm::errs(),
267 "Value printing failed: ");
268 return false;
269 }
270 TLSD->setStmt(*ExprOrErr);
271 }
272
274 }
275};
276
277
278
279
280
281
282
283
284
285
287private:
288 bool IsTerminating = false;
290 std::unique_ptr Consumer;
291
292public:
295 std::unique_ptr Consumer = nullptr)
297 llvm::ErrorAsOutParameter EAO(&Err);
298 std::unique_ptr Act;
300 default:
301 Err = llvm::createStringError(
302 std::errc::state_not_recoverable,
303 "Driver initialization failed. "
304 "Incremental mode for action %d is not supported",
306 return Act;
311 break;
319 break;
320 }
321 return Act;
322 }()),
323 Interp(I), Consumer(std::move(Consumer)) {}
327 }
328
330 StringRef InFile) override {
331 std::unique_ptr C =
333
334 if (Consumer) {
335 std::vector<std::unique_ptr> Cs;
336 Cs.push_back(std::move(Consumer));
337 Cs.push_back(std::move(C));
338 return std::make_unique(std::move(Cs));
339 }
340
341 return std::make_unique(std::move(C), Interp);
342 }
343
347 }
348
349
350
352
355 }
356
358 assert(!IsTerminating && "Already finalized!");
359 IsTerminating = true;
361 }
362};
363
365 llvm::Error &ErrOut,
366 std::unique_ptrllvm::orc::LLJITBuilder JITBuilder,
367 std::unique_ptrclang::ASTConsumer Consumer)
368 : JITBuilder(std::move(JITBuilder)) {
369 CI = std::move(Instance);
370 llvm::ErrorAsOutParameter EAO(&ErrOut);
371 auto LLVMCtx = std::make_uniquellvm::LLVMContext();
372 TSCtx = std::make_uniquellvm::orc::ThreadSafeContext(std::move(LLVMCtx));
373
374 Act = std::make_unique(*CI, *TSCtx->getContext(), ErrOut,
375 *this, std::move(Consumer));
376 if (ErrOut)
377 return;
378 CI->ExecuteAction(*Act);
379
380 IncrParser = std::make_unique(*CI, ErrOut);
381
382 if (ErrOut)
383 return;
384
385 if (getCodeGen()) {
386 CachedInCodeGenModule = GenModule();
387
388
389 if (!CI->getPreprocessorOpts().Includes.empty()) {
390
391
392
393 auto M = llvm::CloneModule(*CachedInCodeGenModule);
395 RegisterPTU(C.getTranslationUnitDecl(), std::move(M));
396 }
398 ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
399 return;
400 }
401 }
402
403
404 if (getCodeGen()) {
405
406
408 if (llvm::Error Err = Execute(PTU)) {
409 ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
410 return;
411 }
412 }
413}
414
416 IncrParser.reset();
417 Act->FinalizeAction();
418 if (IncrExecutor) {
419 if (llvm::Error Err = IncrExecutor->cleanUp())
420 llvm::report_fatal_error(
421 llvm::Twine("Failed to clean up IncrementalExecutor: ") +
423 }
424}
425
426
427
428
430 #define __CLANG_REPL__ 1
431#ifdef __cplusplus
432 #define EXTERN_C extern "C"
433 void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
434 struct __clang_Interpreter_NewTag{} __ci_newtag;
435 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
436 template <class T, class = T (*)() /*disable for arrays*/>
437 void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
438 for (auto Idx = 0; Idx < Size; ++Idx)
439 new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
440 }
441 template <class T, unsigned long N>
442 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
443 __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
444 }
445#else
446 #define EXTERN_C extern
447#endif // __cplusplus
448
449 EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
451
454 llvm::Error Err = llvm::Error::success();
455 auto Interp =
456 std::unique_ptr(new Interpreter(std::move(CI), Err));
457 if (Err)
458 return std::move(Err);
459
460
461
462 auto PTU = Interp->Parse(Runtimes);
463 if (!PTU)
464 return PTU.takeError();
465 Interp->markUserCodeStart();
466
467 Interp->ValuePrintingInfo.resize(4);
468 return std::move(Interp);
470
473 std::unique_ptr DCI) {
474
476 std::make_uniquellvm::vfs::InMemoryFileSystem();
478 std::make_uniquellvm::vfs::OverlayFileSystem(
479 llvm::vfs::getRealFileSystem());
480 OverlayVFS->pushOverlay(IMVFS);
481 CI->createFileManager(OverlayVFS);
482
484 if (auto E = Interp.takeError())
485 return std::move(E);
486
487 llvm::Error Err = llvm::Error::success();
488 auto DeviceParser = std::make_unique(
489 std::move(DCI), *(*Interp)->getCompilerInstance(), IMVFS, Err,
490 (*Interp)->PTUs);
491 if (Err)
492 return std::move(Err);
493
494 (*Interp)->DeviceParser = std::move(DeviceParser);
495
496 return Interp;
497}
498
500 return CI.get();
501}
504
506 if (!IncrExecutor) {
508 return std::move(Err);
509 }
510
511 return IncrExecutor->GetExecutionEngine();
512}
513
516}
517
520}
521
522void Interpreter::markUserCodeStart() {
523 assert(!InitPTUSize && "We only do this once");
524 InitPTUSize = PTUs.size();
525}
526
527size_t Interpreter::getEffectivePTUSize() const {
528 assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
529 return PTUs.size() - InitPTUSize;
530}
531
534 std::unique_ptrllvm::Module M ) {
538
539 if (!M)
540 M = GenModule();
541
542 assert((!getCodeGen() || M) && "Must have a llvm::Module at this point");
543
544 LastPTU.TheModule = std::move(M);
545 LLVM_DEBUG(llvm::dbgs() << "compile-ptu " << PTUs.size() - 1
546 << ": [TU=" << LastPTU.TUPart);
548 LLVM_DEBUG(llvm::dbgs() << ", M=" << LastPTU.TheModule.get() << " ("
549 << LastPTU.TheModule->getName() << ")");
550 LLVM_DEBUG(llvm::dbgs() << "]\n");
551 return LastPTU;
553
556
557
558 if (DeviceParser) {
560 if (auto E = DeviceTU.takeError())
561 return std::move(E);
562 }
563
564
565
568
570 if (!TuOrErr)
571 return TuOrErr.takeError();
572
573 return RegisterPTU(*TuOrErr);
575
578 if (TT == llvm::sys::getProcessTriple())
579
580 return llvm::orc::JITTargetMachineBuilder::detectHost();
581
582
583 return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
584}
585
587 if (IncrExecutor)
588 return llvm::make_errorllvm::StringError("Operation failed. "
589 "Execution engine exists",
590 std::error_code());
591 if (!getCodeGen())
592 return llvm::make_errorllvm::StringError("Operation failed. "
593 "No code generator available",
594 std::error_code());
595 if (!JITBuilder) {
598 if (!JTMB)
599 return JTMB.takeError();
601 if (!JB)
602 return JB.takeError();
603 JITBuilder = std::move(*JB);
604 }
605
606 llvm::Error Err = llvm::Error::success();
607#ifdef __EMSCRIPTEN__
608 auto Executor = std::make_unique(*TSCtx);
609#else
610 auto Executor =
611 std::make_unique(*TSCtx, *JITBuilder, Err);
612#endif
613 if (!Err)
614 IncrExecutor = std::move(Executor);
615
616 return Err;
617}
620
622 assert(T.TheModule);
623 LLVM_DEBUG(llvm::dbgs()
624 << "execute-ptu "
625 << ((std::find(PTUs.begin(), PTUs.end(), T) != PTUs.end())
626 ? std::distance(PTUs.begin(),
627 std::find(PTUs.begin(), PTUs.end(), T))
628 : -1)
629 << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get() << " ("
630 << T.TheModule->getName() << ")]\n");
631 if (!IncrExecutor) {
633 if (Err)
634 return Err;
635 }
636
637 if (auto Err = IncrExecutor->addModule(T))
638 return Err;
639
640 if (auto Err = IncrExecutor->runCtors())
641 return Err;
642
643 return llvm::Error::success();
644}
645
647
648 auto PTU = Parse(Code);
649 if (!PTU)
650 return PTU.takeError();
651 if (PTU->TheModule)
652 if (llvm::Error Err = Execute(*PTU))
653 return Err;
654
655 if (LastValue.isValid()) {
656 if () {
657 LastValue.dump();
658 LastValue.clear();
659 } else
660 *V = std::move(LastValue);
661 }
662 return llvm::Error::success();
664
667 if (!IncrExecutor)
668 return llvm::make_errorllvm::StringError("Operation failed. "
669 "No execution engine",
670 std::error_code());
671 llvm::StringRef MangledName = getCodeGen()->GetMangledName(GD);
674
677 if (!IncrExecutor)
678 return llvm::make_errorllvm::StringError("Operation failed. "
679 "No execution engine",
680 std::error_code());
681
684
687 if (!IncrExecutor)
688 return llvm::make_errorllvm::StringError("Operation failed. "
689 "No execution engine",
690 std::error_code());
691
693}
694
696
697 if (N > getEffectivePTUSize())
698 return llvm::make_errorllvm::StringError("Operation failed. "
699 "Too many undos",
700 std::error_code());
701 for (unsigned I = 0; I < N; I++) {
702 if (IncrExecutor) {
703 if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back()))
704 return Err;
705 }
706
707 IncrParser->CleanUpPTU(PTUs.back().TUPart);
708 PTUs.pop_back();
709 }
710 return llvm::Error::success();
711}
712
715 if (!EE)
716 return EE.takeError();
717
718 auto &DL = EE->getDataLayout();
719
720 if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load(
721 name, DL.getGlobalPrefix()))
722 EE->getMainJITDylib().addGenerator(std::move(*DLSG));
723 else
724 return DLSG.takeError();
725
726 return llvm::Error::success();
727}
728
729std::unique_ptrllvm::Module Interpreter::GenModule() {
730 static unsigned ID = 0;
732
733
734
735
736
737
738
739 assert(((!CachedInCodeGenModule ||
741 (CachedInCodeGenModule->empty() &&
742 CachedInCodeGenModule->global_empty() &&
743 CachedInCodeGenModule->alias_empty() &&
744 CachedInCodeGenModule->ifunc_empty())) &&
745 "CodeGen wrote to a readonly module");
746 std::unique_ptrllvm::Module M(CG->ReleaseModule());
747 CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
748 return M;
749 }
750 return nullptr;
751}
752
756 return nullptr;
757 return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
758}
759}
Defines the clang::ASTContext interface.
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
The primary public interface to the Clang code generator.
llvm::StringRef GetMangledName(GlobalDecl GD)
Given a global declaration, return a mangled name for this declaration which has been added to this c...
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
ASTContext & getASTContext() const
TargetOptions & getTargetOpts()
FrontendOptions & getFrontendOpts()
static std::string GetResourcesPath(const char *Argv0, void *MainAddr)
Get the directory where the compiler headers reside, relative to the compiler binary (found by the pa...
static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Create a compiler invocation from a list of input options.
Decl - This represents one declaration (or definition), e.g.
Used for handling and querying diagnostic IDs.
Options for controlling the compiler diagnostics engine.
Concrete class used by the front-end to report problems and issues.
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Abstract base class for actions which can be performed by the frontend.
virtual bool hasIRSupport() const
Does this action support use with IR files?
CompilerInstance & getCompilerInstance() const
frontend::ActionKind ProgramAction
The frontend action to perform.
GlobalDecl - represents a global declaration.
bool HandleTopLevelDecl(DeclGroupRef DGR) override final
HandleTopLevelDecl - Handle the specified top-level declaration.
InProcessPrintingASTConsumer(std::unique_ptr< ASTConsumer > C, Interpreter &I)
A custom action enabling the incremental processing functionality.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx, llvm::Error &Err, Interpreter &I, std::unique_ptr< ASTConsumer > Consumer=nullptr)
TranslationUnitKind getTranslationUnitKind() override
For AST-based actions, the kind of translation unit we're handling.
FrontendAction * getWrapped() const
void EndSourceFile() override
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
llvm::Expected< std::unique_ptr< CompilerInstance > > CreateCudaHost()
llvm::Expected< std::unique_ptr< CompilerInstance > > CreateCudaDevice()
llvm::Expected< std::unique_ptr< CompilerInstance > > CreateCpp()
static llvm::Expected< std::unique_ptr< llvm::orc::LLJITBuilder > > createDefaultJITBuilder(llvm::orc::JITTargetMachineBuilder JTMB)
Provides top-level interfaces for incremental compilation and execution.
llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V=nullptr)
llvm::Error CreateExecutor()
Interpreter(std::unique_ptr< CompilerInstance > Instance, llvm::Error &Err, std::unique_ptr< llvm::orc::LLJITBuilder > JITBuilder=nullptr, std::unique_ptr< clang::ASTConsumer > Consumer=nullptr)
static llvm::Expected< std::unique_ptr< Interpreter > > create(std::unique_ptr< CompilerInstance > CI)
llvm::Expected< llvm::orc::ExecutorAddr > getSymbolAddress(GlobalDecl GD) const
llvm::Error LoadDynamicLibrary(const char *name)
Link a dynamic library.
static llvm::Expected< std::unique_ptr< Interpreter > > createWithCUDA(std::unique_ptr< CompilerInstance > CI, std::unique_ptr< CompilerInstance > DCI)
llvm::Expected< PartialTranslationUnit & > Parse(llvm::StringRef Code)
llvm::Expected< llvm::orc::ExecutorAddr > getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const
llvm::Error Undo(unsigned N=1)
Undo N previous incremental inputs.
const CompilerInstance * getCompilerInstance() const
const ASTContext & getASTContext() const
llvm::Expected< llvm::orc::LLJIT & > getExecutionEngine()
llvm::Error Execute(PartialTranslationUnit &T)
bool HandleTopLevelDecl(DeclGroupRef D) override
HandleTopLevelDecl - Handle the specified top-level declaration.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Encodes a location in the source.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)
Construct a target for the given options.
std::string Triple
The name of the target triple to compile for.
void FlushDiagnostics(DiagnosticsEngine &Diags) const
FlushDiagnostics - Flush the buffered diagnostics to an given diagnostic engine.
The top declaration context.
A frontend action which simply wraps some other runtime-specified frontend action.
void ExecuteAction() override
Callback to run the program action, using the initialized compiler instance.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
std::unique_ptr< FrontendAction > WrappedAction
void EndSourceFile() override
Perform any per-file post processing, deallocate per-file objects, and run statistics and output file...
Command - An executable path/name and argument vector to execute.
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
JobList - A sequence of jobs to perform.
Defines the clang::TargetInfo interface.
@ Ignored
Do not present this diagnostic, ignore it.
@ PrintPreprocessedInput
-E mode.
@ ParseSyntaxOnly
Parse and perform semantic analysis.
@ PluginAction
Run a plugin action,.
@ ASTPrint
Parse ASTs and print them.
@ ASTDump
Parse ASTs and dump them.
@ EmitAssembly
Emit a .s file.
@ EmitLLVMOnly
Generate LLVM IR, but do not emit anything.
The JSON file list parser is used to communicate input to InstallAPI.
static llvm::Expected< llvm::orc::JITTargetMachineBuilder > createJITTargetMachineBuilder(const std::string &TT)
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
std::unique_ptr< FrontendAction > CreateFrontendAction(CompilerInstance &CI)
Construct the FrontendAction of a compiler invocation based on the options specified for the compiler...
const char *const Runtimes
TranslationUnitKind
Describes the kind of translation unit being processed.
@ TU_Incremental
The translation unit is a is a complete translation unit that we might incrementally extend later.
const FunctionProtoType * T
@ Success
Template argument deduction was successful.
bool(*)(llvm::ArrayRef< const char * >, llvm::raw_ostream &, llvm::raw_ostream &, bool, bool) Driver
The class keeps track of various objects created as part of processing incremental inputs.
TranslationUnitDecl * TUPart
std::unique_ptr< llvm::Module > TheModule
The llvm IR produced for the input.