clang 23.0.0git
Interpreter.cpp
Go to the documentation of this file.
1//===------ Interpreter.cpp - Incremental Compilation and Execution -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the component which performs incremental code
10// compilation and execution.
11//
12//===----------------------------------------------------------------------===//
13
14#include "DeviceOffload.h"
15#include "IncrementalAction.h"
16#include "IncrementalParser.h"
17#include "InterpreterUtils.h"
18
21#include "clang/AST/Mangle.h"
28#include "clang/Driver/Driver.h"
29#include "clang/Driver/Job.h"
30#include "clang/Driver/Tool.h"
42#include "clang/Sema/Lookup.h"
44#include "llvm/ExecutionEngine/JITSymbol.h"
45#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
46#include "llvm/ExecutionEngine/Orc/LLJIT.h"
47#include "llvm/IR/Module.h"
48#include "llvm/Support/Errc.h"
49#include "llvm/Support/ErrorHandling.h"
50#include "llvm/Support/VirtualFileSystem.h"
51#include "llvm/Support/raw_ostream.h"
52#include "llvm/TargetParser/Host.h"
53#include "llvm/Transforms/Utils/Cloning.h" // for CloneModule
54
55#define DEBUG_TYPE "clang-repl"
56
57using namespace clang;
58// FIXME: Figure out how to unify with namespace init_convenience from
59// tools/clang-import-test/clang-import-test.cpp
60namespace {
61/// Retrieves the clang CC1 specific flags out of the compilation's jobs.
62/// \returns NULL on error.
64GetCC1Arguments(DiagnosticsEngine *Diagnostics,
65 driver::Compilation *Compilation) {
66 // We expect to get back exactly one Command job, if we didn't something
67 // failed. Extract that job from the Compilation.
68 const driver::JobList &Jobs = Compilation->getJobs();
69 if (!Jobs.size() || !isa<driver::Command>(*Jobs.begin()))
70 return llvm::createStringError(llvm::errc::not_supported,
71 "Driver initialization failed. "
72 "Unable to create a driver job");
73
74 // The one job we find should be to invoke clang again.
75 const driver::Command *Cmd = cast<driver::Command>(&(*Jobs.begin()));
76 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
77 return llvm::createStringError(llvm::errc::not_supported,
78 "Driver initialization failed");
79
80 return &Cmd->getArguments();
81}
82
84CreateCI(const llvm::opt::ArgStringList &Argv) {
85 std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
86
87 // Register the support for object-file-wrapped Clang modules.
88 // FIXME: Clang should register these container operations automatically.
89 auto PCHOps = Clang->getPCHContainerOperations();
90 PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
91 PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
92
93 // Buffer diagnostics from argument parsing so that we can output them using
94 // a well formed diagnostic object.
95 DiagnosticOptions DiagOpts;
97 DiagnosticsEngine Diags(DiagnosticIDs::create(), DiagOpts, DiagsBuffer);
99 Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
100
101 // Infer the builtin include path if unspecified.
102 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
103 Clang->getHeaderSearchOpts().ResourceDir.empty())
104 Clang->getHeaderSearchOpts().ResourceDir =
105 GetResourcesPath(Argv[0], nullptr);
106
107 Clang->createVirtualFileSystem();
108
109 // Create the actual diagnostics engine.
110 Clang->createDiagnostics();
111
112 DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
113 if (!Success)
114 return llvm::createStringError(llvm::errc::not_supported,
115 "Initialization failed. "
116 "Unable to flush diagnostics");
117
118 // FIXME: Merge with CompilerInstance::ExecuteAction.
119 llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release();
120 Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
121
122 Clang->setTarget(TargetInfo::CreateTargetInfo(
123 Clang->getDiagnostics(), Clang->getInvocation().getTargetOpts()));
124 if (!Clang->hasTarget())
125 return llvm::createStringError(llvm::errc::not_supported,
126 "Initialization failed. "
127 "Target is missing");
128
129 Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts(),
130 Clang->getAuxTarget());
131
132 // Don't clear the AST before backend codegen since we do codegen multiple
133 // times, reusing the same AST.
134 Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
135
136 Clang->getFrontendOpts().DisableFree = false;
137 Clang->getCodeGenOpts().DisableFree = false;
138 return std::move(Clang);
139}
140
141} // anonymous namespace
142
143namespace clang {
144
146IncrementalCompilerBuilder::create(std::string TT,
147 std::vector<const char *> &ClangArgv) {
148
149 // If we don't know ClangArgv0 or the address of main() at this point, try
150 // to guess it anyway (it's possible on some platforms).
151 std::string MainExecutableName =
152 llvm::sys::fs::getMainExecutable(nullptr, nullptr);
153
154 ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
155
156 // Prepending -c to force the driver to do something if no action was
157 // specified. By prepending we allow users to override the default
158 // action and use other actions in incremental mode.
159 // FIXME: Print proper driver diagnostics if the driver flags are wrong.
160 // We do C++ by default; append right after argv[0] if no "-x" given
161 ClangArgv.insert(ClangArgv.end(), "-Xclang");
162 ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions");
163 ClangArgv.insert(ClangArgv.end(), "-c");
164
165 // Put a dummy C++ file on to ensure there's at least one compile job for the
166 // driver to construct.
167 ClangArgv.push_back("<<< inputs >>>");
168
169 // Buffer diagnostics from argument parsing so that we can output them using a
170 // well formed diagnostic object.
171 std::unique_ptr<DiagnosticOptions> DiagOpts =
172 CreateAndPopulateDiagOpts(ClangArgv);
173 TextDiagnosticBuffer *DiagsBuffer = new TextDiagnosticBuffer;
174 DiagnosticsEngine Diags(DiagnosticIDs::create(), *DiagOpts, DiagsBuffer);
175
176 driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
177 Driver.setCheckInputsExist(false); // the input comes from mem buffers
178 llvm::ArrayRef<const char *> RF = llvm::ArrayRef(ClangArgv);
179 std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(RF));
180
181 if (CompilationCB)
182 if (auto Err = (*CompilationCB)(*Compilation.get()))
183 return std::move(Err);
184
185 if (Compilation->getArgs().hasArg(options::OPT_v))
186 Compilation->getJobs().Print(llvm::errs(), "\n", /*Quote=*/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 llvm::append_range(Argv, UserArgs);
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=";
229 if (!OffloadArch.empty()) {
230 ArchArg += OffloadArch;
231 Argv.push_back(ArchArg.c_str());
232 }
233
234 llvm::append_range(Argv, UserArgs);
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
250Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
251 llvm::Error &ErrOut,
252 std::unique_ptr<IncrementalExecutorBuilder> IEB,
253 std::unique_ptr<clang::ASTConsumer> Consumer)
254 : IncrExecutorBuilder(std::move(IEB)) {
255 CI = std::move(Instance);
256 llvm::ErrorAsOutParameter EAO(&ErrOut);
257 auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
258 TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(std::move(LLVMCtx));
259
260 Act = TSCtx->withContextDo([&](llvm::LLVMContext *Ctx) {
261 return std::make_unique<IncrementalAction>(*CI, *Ctx, ErrOut, *this,
262 std::move(Consumer));
263 });
264
265 if (ErrOut)
266 return;
267 CI->ExecuteAction(*Act);
268
269 IncrParser =
270 std::make_unique<IncrementalParser>(*CI, Act.get(), ErrOut, PTUs);
271
272 if (ErrOut)
273 return;
274
275 if (Act->getCodeGen()) {
276 Act->CacheCodeGenModule();
277 // The initial PTU is filled by `-include`/`-include-pch` or by CUDA
278 // includes automatically.
279 if (!CI->getPreprocessorOpts().Includes.empty() ||
280 !CI->getPreprocessorOpts().ImplicitPCHInclude.empty()) {
281 // We can't really directly pass the CachedInCodeGenModule to the Jit
282 // because it will steal it, causing dangling references as explained in
283 // Interpreter::Execute
284 auto M = llvm::CloneModule(*Act->getCachedCodeGenModule());
285 ASTContext &C = CI->getASTContext();
286 IncrParser->RegisterPTU(C.getTranslationUnitDecl(), std::move(M));
287 }
288 if (llvm::Error Err = CreateExecutor()) {
289 ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
290 return;
291 }
292 }
293
294 // Not all frontends support code-generation, e.g. ast-dump actions don't
295 if (Act->getCodeGen()) {
296 // Process the PTUs that came from initialization. For example -include will
297 // give us a header that's processed at initialization of the preprocessor.
298 for (PartialTranslationUnit &PTU : PTUs)
299 if (llvm::Error Err = Execute(PTU)) {
300 ErrOut = joinErrors(std::move(ErrOut), std::move(Err));
301 return;
302 }
303 }
304}
305
307 IncrParser.reset();
308 Act->FinalizeAction();
309 if (DeviceParser)
310 DeviceParser.reset();
311 if (DeviceAct)
312 DeviceAct->FinalizeAction();
313 if (IncrExecutor) {
314 if (llvm::Error Err = IncrExecutor->cleanUp())
315 llvm::report_fatal_error(
316 llvm::Twine("Failed to clean up IncrementalExecutor: ") +
317 toString(std::move(Err)));
318 }
319}
320
321// These better to put in a runtime header but we can't. This is because we
322// can't find the precise resource directory in unittests so we have to hard
323// code them.
324const char *const Runtimes = R"(
325 #define __CLANG_REPL__ 1
326#ifdef __cplusplus
327 #define EXTERN_C extern "C"
328 struct __clang_Interpreter_NewTag{} __ci_newtag;
329 void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
330 template <class T, class = T (*)() /*disable for arrays*/>
331 void __clang_Interpreter_SetValueCopyArr(const T* Src, void* Placement, unsigned long Size) {
332 for (unsigned long Idx = 0; Idx < Size; ++Idx)
333 new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
334 }
335 template <class T, unsigned long N>
336 void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) {
337 __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size);
338 }
339#else
340 #define EXTERN_C extern
341 EXTERN_C void *memcpy(void *restrict dst, const void *restrict src, __SIZE_TYPE__ n);
342 EXTERN_C inline void __clang_Interpreter_SetValueCopyArr(const void* Src, void* Placement, unsigned long Size) {
343 memcpy(Placement, Src, Size);
344 }
345#endif // __cplusplus
346 EXTERN_C void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
347 EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
348)";
349
351 std::unique_ptr<CompilerInstance> CI,
352 std::unique_ptr<IncrementalExecutorBuilder> IEB /*=nullptr*/) {
353 llvm::Error Err = llvm::Error::success();
354
355 auto Interp = std::unique_ptr<Interpreter>(new Interpreter(
356 std::move(CI), Err, std::move(IEB), /*Consumer=*/nullptr));
357 if (auto E = std::move(Err))
358 return std::move(E);
359
360 // Add runtime code and set a marker to hide it from user code. Undo will not
361 // go through that.
362 if (auto E = Interp->ParseAndExecute(Runtimes))
363 return std::move(E);
364
365 Interp->markUserCodeStart();
366
367 return std::move(Interp);
368}
369
371Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
372 std::unique_ptr<CompilerInstance> DCI) {
373 // avoid writing fat binary to disk using an in-memory virtual file system
375 std::make_unique<llvm::vfs::InMemoryFileSystem>();
377 std::make_unique<llvm::vfs::OverlayFileSystem>(
378 llvm::vfs::getRealFileSystem());
379 OverlayVFS->pushOverlay(IMVFS);
380 CI->createVirtualFileSystem(OverlayVFS);
381 CI->createFileManager();
382
384 Interpreter::create(std::move(CI));
385 if (!InterpOrErr)
386 return InterpOrErr;
387
388 std::unique_ptr<Interpreter> Interp = std::move(*InterpOrErr);
389
390 llvm::Error Err = llvm::Error::success();
391
392 auto DeviceAct = Interp->TSCtx->withContextDo([&](llvm::LLVMContext *Ctx) {
393 return std::make_unique<IncrementalAction>(*DCI, *Ctx, Err, *Interp);
394 });
395
396 if (Err)
397 return std::move(Err);
398
399 Interp->DeviceAct = std::move(DeviceAct);
400
401 DCI->ExecuteAction(*Interp->DeviceAct);
402
403 Interp->DeviceCI = std::move(DCI);
404
405 auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
406 *Interp->DeviceCI, *Interp->getCompilerInstance(),
407 Interp->DeviceAct.get(), IMVFS, Err, Interp->PTUs);
408
409 if (Err)
410 return std::move(Err);
411
412 Interp->DeviceParser = std::move(DeviceParser);
413 return std::move(Interp);
414}
415
418 return const_cast<Interpreter *>(this)->getCompilerInstance();
419}
420
422 if (!IncrExecutor) {
423 if (auto Err = CreateExecutor())
424 return std::move(Err);
425 }
426
427 return *IncrExecutor.get();
428}
429
433
437
438void Interpreter::markUserCodeStart() {
439 assert(!InitPTUSize && "We only do this once");
440 InitPTUSize = PTUs.size();
441}
442
443size_t Interpreter::getEffectivePTUSize() const {
444 assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
445 return PTUs.size() - InitPTUSize;
446}
447
449Interpreter::Parse(llvm::StringRef Code) {
450 // If we have a device parser, parse it first. The generated code will be
451 // included in the host compilation
452 if (DeviceParser) {
453 llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Code);
454 if (auto E = DeviceTU.takeError())
455 return std::move(E);
456
457 DeviceParser->RegisterPTU(*DeviceTU);
458
459 llvm::Expected<llvm::StringRef> PTX = DeviceParser->GeneratePTX();
460 if (!PTX)
461 return PTX.takeError();
462
463 llvm::Error Err = DeviceParser->GenerateFatbinary();
464 if (Err)
465 return std::move(Err);
466 }
467
468 // Tell the interpreter sliently ignore unused expressions since value
469 // printing could cause it.
471 clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation());
472
473 llvm::Expected<TranslationUnitDecl *> TuOrErr = IncrParser->Parse(Code);
474 if (!TuOrErr)
475 return TuOrErr.takeError();
476
477 PartialTranslationUnit &LastPTU = IncrParser->RegisterPTU(*TuOrErr);
478
479 return LastPTU;
480}
481
483 if (IncrExecutor)
484 return llvm::make_error<llvm::StringError>("Operation failed. "
485 "Execution engine exists",
486 std::error_code());
487 if (!Act->getCodeGen())
488 return llvm::make_error<llvm::StringError>("Operation failed. "
489 "No code generator available",
490 std::error_code());
491
492 if (!IncrExecutorBuilder)
493 IncrExecutorBuilder = std::make_unique<IncrementalExecutorBuilder>();
494
495 auto ExecutorOrErr = IncrExecutorBuilder->create(*TSCtx, CI->getTarget());
496 if (ExecutorOrErr)
497 IncrExecutor = std::move(*ExecutorOrErr);
498
499 return ExecutorOrErr.takeError();
500}
501
503 assert(T.TheModule);
504 LLVM_DEBUG(
505 llvm::dbgs() << "execute-ptu "
506 << (llvm::is_contained(PTUs, T)
507 ? std::distance(PTUs.begin(), llvm::find(PTUs, T))
508 : -1)
509 << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get()
510 << " (" << T.TheModule->getName() << ")]\n");
511 if (!IncrExecutor) {
512 auto Err = CreateExecutor();
513 if (Err)
514 return Err;
515 }
516 // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
517 if (auto Err = IncrExecutor->addModule(T))
518 return Err;
519
520 if (auto Err = IncrExecutor->runCtors())
521 return Err;
522
523 return llvm::Error::success();
524}
525
526llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
527
528 auto PTU = Parse(Code);
529 if (!PTU)
530 return PTU.takeError();
531 if (PTU->TheModule)
532 if (llvm::Error Err = Execute(*PTU))
533 return Err;
534
535 if (LastValue.isValid()) {
536 if (!V) {
537 LastValue.dump();
538 LastValue.clear();
539 } else
540 *V = std::move(LastValue);
541 }
542 return llvm::Error::success();
543}
544
547 if (!IncrExecutor)
548 return llvm::make_error<llvm::StringError>("Operation failed. "
549 "No execution engine",
550 std::error_code());
551 llvm::StringRef MangledName = Act->getCodeGen()->GetMangledName(GD);
552 return getSymbolAddress(MangledName);
553}
554
556Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
557 if (!IncrExecutor)
558 return llvm::make_error<llvm::StringError>("Operation failed. "
559 "No execution engine",
560 std::error_code());
561
562 return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName);
563}
564
567 if (!IncrExecutor)
568 return llvm::make_error<llvm::StringError>("Operation failed. "
569 "No execution engine",
570 std::error_code());
571
572 return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName);
573}
574
575llvm::Error Interpreter::Undo(unsigned N) {
576
577 if (getEffectivePTUSize() == 0) {
578 return llvm::make_error<llvm::StringError>("Operation failed. "
579 "No input left to undo",
580 std::error_code());
581 } else if (N > getEffectivePTUSize()) {
582 return llvm::make_error<llvm::StringError>(
583 llvm::formatv(
584 "Operation failed. Wanted to undo {0} inputs, only have {1}.", N,
585 getEffectivePTUSize()),
586 std::error_code());
587 }
588
589 for (unsigned I = 0; I < N; I++) {
590 if (IncrExecutor) {
591 if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back()))
592 return Err;
593 }
594
595 IncrParser->CleanUpPTU(PTUs.back().TUPart);
596 PTUs.pop_back();
597 }
598 return llvm::Error::success();
599}
600
601llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
602 auto EEOrErr = getExecutionEngine();
603 if (!EEOrErr)
604 return EEOrErr.takeError();
605
606 return EEOrErr->LoadDynamicLibrary(name);
607}
608} // end namespace clang
Defines the clang::ASTContext interface.
#define V(N, I)
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 ...
Definition ASTContext.h:220
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
ASTContext & getASTContext() const
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.
static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()
Options for controlling the compiler diagnostics engine.
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
llvm::Expected< std::unique_ptr< CompilerInstance > > CreateCudaHost()
llvm::Expected< std::unique_ptr< CompilerInstance > > CreateCudaDevice()
llvm::Expected< std::unique_ptr< CompilerInstance > > CreateCpp()
llvm::Expected< IncrementalExecutor & > getExecutionEngine()
llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V=nullptr)
static llvm::Expected< std::unique_ptr< Interpreter > > create(std::unique_ptr< CompilerInstance > CI, std::unique_ptr< IncrementalExecutorBuilder > IEB=nullptr)
llvm::Error CreateExecutor()
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
Interpreter(std::unique_ptr< CompilerInstance > Instance, llvm::Error &Err, std::unique_ptr< IncrementalExecutorBuilder > IEB=nullptr, std::unique_ptr< clang::ASTConsumer > Consumer=nullptr)
llvm::Error Undo(unsigned N=1)
Undo N previous incremental inputs.
const CompilerInstance * getCompilerInstance() const
const ASTContext & getASTContext() const
friend class Value
Definition Interpreter.h:99
llvm::Error Execute(PartialTranslationUnit &T)
Encodes a location in the source.
static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts)
Construct a target for the given options.
Definition Targets.cpp:806
void FlushDiagnostics(DiagnosticsEngine &Diags) const
FlushDiagnostics - Flush the buffered diagnostics to an given diagnostic engine.
Command - An executable path/name and argument vector to execute.
Definition Job.h:106
const Tool & getCreator() const
getCreator - Return the Tool which caused the creation of this job.
Definition Job.h:191
const llvm::opt::ArgStringList & getArguments() const
Definition Job.h:224
Compilation - A set of tasks to perform for a single driver invocation.
Definition Compilation.h:45
JobList - A sequence of jobs to perform.
Definition Job.h:260
size_type size() const
Definition Job.h:283
iterator begin()
Definition Job.h:284
const char * getName() const
Definition Tool.h:48
Defines the clang::TargetInfo interface.
@ Ignored
Do not present this diagnostic, ignore it.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
@ Success
Annotation was successful.
Definition Parser.h:65
@ Parse
Parse the block; this code is always used.
Definition Parser.h:137
const char *const Runtimes
const FunctionProtoType * T
std::string GetResourcesPath(StringRef BinaryPath)
Get the directory where the compiler headers reside, relative to the compiler binary path BinaryPath.
U cast(CodeGen::Address addr)
Definition Address.h:327
bool(*)(llvm::ArrayRef< const char * >, llvm::raw_ostream &, llvm::raw_ostream &, bool, bool) Driver
Definition Wasm.cpp:36
The class keeps track of various objects created as part of processing incremental inputs.