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

260 for (Decl *D : DGR)

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 (V) {

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.