clang 22.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 "IncrementalExecutor.h"
17#include "IncrementalParser.h"
18#include "InterpreterUtils.h"
19#include "llvm/Support/VirtualFileSystem.h"
20#ifdef __EMSCRIPTEN__
21#include "Wasm.h"
22#include <dlfcn.h>
23#endif // __EMSCRIPTEN__
24
27#include "clang/AST/Mangle.h"
34#include "clang/Driver/Driver.h"
35#include "clang/Driver/Job.h"
37#include "clang/Driver/Tool.h"
46#include "clang/Sema/Lookup.h"
48#include "llvm/ExecutionEngine/JITSymbol.h"
49#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h"
50#include "llvm/ExecutionEngine/Orc/LLJIT.h"
51#include "llvm/IR/Module.h"
52#include "llvm/Support/Errc.h"
53#include "llvm/Support/ErrorHandling.h"
54#include "llvm/Support/raw_ostream.h"
55#include "llvm/TargetParser/Host.h"
56#include "llvm/Transforms/Utils/Cloning.h" // for CloneModule
57
58#define DEBUG_TYPE "clang-repl"
59
60using namespace clang;
61// FIXME: Figure out how to unify with namespace init_convenience from
62// tools/clang-import-test/clang-import-test.cpp
63namespace {
64/// Retrieves the clang CC1 specific flags out of the compilation's jobs.
65/// \returns NULL on error.
67GetCC1Arguments(DiagnosticsEngine *Diagnostics,
68 driver::Compilation *Compilation) {
69 // We expect to get back exactly one Command job, if we didn't something
70 // failed. Extract that job from the Compilation.
71 const driver::JobList &Jobs = Compilation->getJobs();
72 if (!Jobs.size() || !isa<driver::Command>(*Jobs.begin()))
73 return llvm::createStringError(llvm::errc::not_supported,
74 "Driver initialization failed. "
75 "Unable to create a driver job");
76
77 // The one job we find should be to invoke clang again.
78 const driver::Command *Cmd = cast<driver::Command>(&(*Jobs.begin()));
79 if (llvm::StringRef(Cmd->getCreator().getName()) != "clang")
80 return llvm::createStringError(llvm::errc::not_supported,
81 "Driver initialization failed");
82
83 return &Cmd->getArguments();
84}
85
87CreateCI(const llvm::opt::ArgStringList &Argv) {
88 std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
89
90 // Register the support for object-file-wrapped Clang modules.
91 // FIXME: Clang should register these container operations automatically.
92 auto PCHOps = Clang->getPCHContainerOperations();
93 PCHOps->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
94 PCHOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
95
96 // Buffer diagnostics from argument parsing so that we can output them using
97 // a well formed diagnostic object.
98 DiagnosticOptions DiagOpts;
100 DiagnosticsEngine Diags(DiagnosticIDs::create(), DiagOpts, DiagsBuffer);
102 Clang->getInvocation(), llvm::ArrayRef(Argv.begin(), Argv.size()), Diags);
103
104 // Infer the builtin include path if unspecified.
105 if (Clang->getHeaderSearchOpts().UseBuiltinIncludes &&
106 Clang->getHeaderSearchOpts().ResourceDir.empty())
107 Clang->getHeaderSearchOpts().ResourceDir =
108 CompilerInvocation::GetResourcesPath(Argv[0], nullptr);
109
110 // Create the actual diagnostics engine.
111 Clang->createDiagnostics(*llvm::vfs::getRealFileSystem());
112 if (!Clang->hasDiagnostics())
113 return llvm::createStringError(llvm::errc::not_supported,
114 "Initialization failed. "
115 "Unable to create diagnostics engine");
116
117 DiagsBuffer->FlushDiagnostics(Clang->getDiagnostics());
118 if (!Success)
119 return llvm::createStringError(llvm::errc::not_supported,
120 "Initialization failed. "
121 "Unable to flush diagnostics");
122
123 // FIXME: Merge with CompilerInstance::ExecuteAction.
124 llvm::MemoryBuffer *MB = llvm::MemoryBuffer::getMemBuffer("").release();
125 Clang->getPreprocessorOpts().addRemappedFile("<<< inputs >>>", MB);
126
127 Clang->setTarget(TargetInfo::CreateTargetInfo(
128 Clang->getDiagnostics(), Clang->getInvocation().getTargetOpts()));
129 if (!Clang->hasTarget())
130 return llvm::createStringError(llvm::errc::not_supported,
131 "Initialization failed. "
132 "Target is missing");
133
134 Clang->getTarget().adjust(Clang->getDiagnostics(), Clang->getLangOpts(),
135 Clang->getAuxTarget());
136
137 // Don't clear the AST before backend codegen since we do codegen multiple
138 // times, reusing the same AST.
139 Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
140
141 Clang->getFrontendOpts().DisableFree = false;
142 Clang->getCodeGenOpts().DisableFree = false;
143 return std::move(Clang);
144}
145
146} // anonymous namespace
147
148namespace clang {
149
151IncrementalCompilerBuilder::create(std::string TT,
152 std::vector<const char *> &ClangArgv) {
153
154 // If we don't know ClangArgv0 or the address of main() at this point, try
155 // to guess it anyway (it's possible on some platforms).
156 std::string MainExecutableName =
157 llvm::sys::fs::getMainExecutable(nullptr, nullptr);
158
159 ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
160
161 // Prepending -c to force the driver to do something if no action was
162 // specified. By prepending we allow users to override the default
163 // action and use other actions in incremental mode.
164 // FIXME: Print proper driver diagnostics if the driver flags are wrong.
165 // We do C++ by default; append right after argv[0] if no "-x" given
166 ClangArgv.insert(ClangArgv.end(), "-Xclang");
167 ClangArgv.insert(ClangArgv.end(), "-fincremental-extensions");
168 ClangArgv.insert(ClangArgv.end(), "-c");
169
170 // Put a dummy C++ file on to ensure there's at least one compile job for the
171 // driver to construct.
172 ClangArgv.push_back("<<< inputs >>>");
173
174 // Buffer diagnostics from argument parsing so that we can output them using a
175 // well formed diagnostic object.
176 std::unique_ptr<DiagnosticOptions> DiagOpts =
177 CreateAndPopulateDiagOpts(ClangArgv);
179 DiagnosticsEngine Diags(DiagnosticIDs::create(), *DiagOpts, DiagsBuffer);
180
181 driver::Driver Driver(/*MainBinaryName=*/ClangArgv[0], TT, Diags);
182 Driver.setCheckInputsExist(false); // the input comes from mem buffers
184 std::unique_ptr<driver::Compilation> Compilation(Driver.BuildCompilation(RF));
185
186 if (Compilation->getArgs().hasArg(driver::options::OPT_v))
187 Compilation->getJobs().Print(llvm::errs(), "\n", /*Quote=*/false);
188
189 auto ErrOrCC1Args = GetCC1Arguments(&Diags, Compilation.get());
190 if (auto Err = ErrOrCC1Args.takeError())
191 return std::move(Err);
192
193 return CreateCI(**ErrOrCC1Args);
194}
195
198 std::vector<const char *> Argv;
199 Argv.reserve(5 + 1 + UserArgs.size());
200 Argv.push_back("-xc++");
201#ifdef __EMSCRIPTEN__
202 Argv.push_back("-target");
203 Argv.push_back("wasm32-unknown-emscripten");
204 Argv.push_back("-fvisibility=default");
205#endif
206 llvm::append_range(Argv, UserArgs);
207
208 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
209 return IncrementalCompilerBuilder::create(TT, Argv);
210}
211
213IncrementalCompilerBuilder::createCuda(bool device) {
214 std::vector<const char *> Argv;
215 Argv.reserve(5 + 4 + UserArgs.size());
216
217 Argv.push_back("-xcuda");
218 if (device)
219 Argv.push_back("--cuda-device-only");
220 else
221 Argv.push_back("--cuda-host-only");
222
223 std::string SDKPathArg = "--cuda-path=";
224 if (!CudaSDKPath.empty()) {
225 SDKPathArg += CudaSDKPath;
226 Argv.push_back(SDKPathArg.c_str());
227 }
228
229 std::string ArchArg = "--offload-arch=";
230 if (!OffloadArch.empty()) {
231 ArchArg += OffloadArch;
232 Argv.push_back(ArchArg.c_str());
233 }
234
235 llvm::append_range(Argv, UserArgs);
236
237 std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple();
238 return IncrementalCompilerBuilder::create(TT, Argv);
239}
240
243 return IncrementalCompilerBuilder::createCuda(true);
244}
245
248 return IncrementalCompilerBuilder::createCuda(false);
249}
250
251Interpreter::Interpreter(std::unique_ptr<CompilerInstance> Instance,
252 llvm::Error &ErrOut,
253 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder,
254 std::unique_ptr<clang::ASTConsumer> Consumer)
255 : JITBuilder(std::move(JITBuilder)) {
256 CI = std::move(Instance);
257 llvm::ErrorAsOutParameter EAO(&ErrOut);
258 auto LLVMCtx = std::make_unique<llvm::LLVMContext>();
259 TSCtx = std::make_unique<llvm::orc::ThreadSafeContext>(std::move(LLVMCtx));
260
261 Act = TSCtx->withContextDo([&](llvm::LLVMContext *Ctx) {
262 return std::make_unique<IncrementalAction>(*CI, *Ctx, ErrOut, *this,
263 std::move(Consumer));
264 });
265
266 if (ErrOut)
267 return;
268 CI->ExecuteAction(*Act);
269
270 IncrParser =
271 std::make_unique<IncrementalParser>(*CI, Act.get(), ErrOut, PTUs);
272
273 if (ErrOut)
274 return;
275
276 if (Act->getCodeGen()) {
277 Act->CacheCodeGenModule();
278 // The initial PTU is filled by `-include` or by CUDA includes
279 // automatically.
280 if (!CI->getPreprocessorOpts().Includes.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 (auto 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
351Interpreter::create(std::unique_ptr<CompilerInstance> CI,
352 std::unique_ptr<llvm::orc::LLJITBuilder> JB) {
353 llvm::Error Err = llvm::Error::success();
354 auto Interp = std::unique_ptr<Interpreter>(
355 new Interpreter(std::move(CI), Err, JB ? std::move(JB) : nullptr));
356 if (Err)
357 return std::move(Err);
358
359 // Add runtime code and set a marker to hide it from user code. Undo will not
360 // go through that.
361 Err = Interp->ParseAndExecute(Runtimes);
362 if (Err)
363 return std::move(Err);
364
365 Interp->markUserCodeStart();
366
367 return std::move(Interp);
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->createFileManager(OverlayVFS);
381
383 Interpreter::create(std::move(CI));
384 if (!InterpOrErr)
385 return InterpOrErr;
386
387 std::unique_ptr<Interpreter> Interp = std::move(*InterpOrErr);
388
389 llvm::Error Err = llvm::Error::success();
390
391 auto DeviceAct = Interp->TSCtx->withContextDo([&](llvm::LLVMContext *Ctx) {
392 return std::make_unique<IncrementalAction>(*DCI, *Ctx, Err, *Interp);
393 });
394
395 if (Err)
396 return std::move(Err);
397
398 Interp->DeviceAct = std::move(DeviceAct);
399
400 DCI->ExecuteAction(*Interp->DeviceAct);
401
402 Interp->DeviceCI = std::move(DCI);
403
404 auto DeviceParser = std::make_unique<IncrementalCUDADeviceParser>(
405 *Interp->DeviceCI, *Interp->getCompilerInstance(),
406 Interp->DeviceAct.get(), IMVFS, Err, Interp->PTUs);
407
408 if (Err)
409 return std::move(Err);
410
411 Interp->DeviceParser = std::move(DeviceParser);
412 return std::move(Interp);
414
417 return const_cast<Interpreter *>(this)->getCompilerInstance();
418}
419
421 if (!IncrExecutor) {
422 if (auto Err = CreateExecutor())
423 return std::move(Err);
424 }
425
426 return IncrExecutor->GetExecutionEngine();
427}
428
431}
432
435}
436
437void Interpreter::markUserCodeStart() {
438 assert(!InitPTUSize && "We only do this once");
439 InitPTUSize = PTUs.size();
440}
441
442size_t Interpreter::getEffectivePTUSize() const {
443 assert(PTUs.size() >= InitPTUSize && "empty PTU list?");
444 return PTUs.size() - InitPTUSize;
446
448Interpreter::Parse(llvm::StringRef Code) {
449 // If we have a device parser, parse it first. The generated code will be
450 // included in the host compilation
451 if (DeviceParser) {
452 llvm::Expected<TranslationUnitDecl *> DeviceTU = DeviceParser->Parse(Code);
453 if (auto E = DeviceTU.takeError())
454 return std::move(E);
455
456 DeviceParser->RegisterPTU(*DeviceTU);
457
458 llvm::Expected<llvm::StringRef> PTX = DeviceParser->GeneratePTX();
459 if (!PTX)
460 return PTX.takeError();
461
462 llvm::Error Err = DeviceParser->GenerateFatbinary();
463 if (Err)
464 return std::move(Err);
465 }
466
467 // Tell the interpreter sliently ignore unused expressions since value
468 // printing could cause it.
470 clang::diag::warn_unused_expr, diag::Severity::Ignored, SourceLocation());
471
472 llvm::Expected<TranslationUnitDecl *> TuOrErr = IncrParser->Parse(Code);
473 if (!TuOrErr)
474 return TuOrErr.takeError();
475
476 PTUs.emplace_back(PartialTranslationUnit());
477 PartialTranslationUnit &LastPTU = PTUs.back();
478 LastPTU.TUPart = *TuOrErr;
479
480 if (std::unique_ptr<llvm::Module> M = Act->GenModule())
481 LastPTU.TheModule = std::move(M);
482
483 return LastPTU;
485
487createJITTargetMachineBuilder(const std::string &TT) {
488 if (TT == llvm::sys::getProcessTriple())
489 // This fails immediately if the target backend is not registered
490 return llvm::orc::JITTargetMachineBuilder::detectHost();
491
492 // If the target backend is not registered, LLJITBuilder::create() will fail
493 return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
495
498 std::unique_ptr<llvm::orc::ExecutorProcessControl> EPC,
499 llvm::StringRef OrcRuntimePath) {
500 const std::string &TT = EPC->getTargetTriple().getTriple();
501 auto JTMB = createJITTargetMachineBuilder(TT);
502 if (!JTMB)
503 return JTMB.takeError();
504 auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
505 if (!JB)
506 return JB.takeError();
507
508 (*JB)->setExecutorProcessControl(std::move(EPC));
509 (*JB)->setPlatformSetUp(
510 llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str()));
511
512 return std::move(*JB);
513}
514
515llvm::Error Interpreter::CreateExecutor() {
516 if (IncrExecutor)
517 return llvm::make_error<llvm::StringError>("Operation failed. "
518 "Execution engine exists",
519 std::error_code());
520 if (!Act->getCodeGen())
521 return llvm::make_error<llvm::StringError>("Operation failed. "
522 "No code generator available",
523 std::error_code());
524 if (!JITBuilder) {
525 const std::string &TT = getCompilerInstance()->getTargetOpts().Triple;
526 auto JTMB = createJITTargetMachineBuilder(TT);
527 if (!JTMB)
528 return JTMB.takeError();
529 auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
530 if (!JB)
531 return JB.takeError();
532 JITBuilder = std::move(*JB);
533 }
534
535 llvm::Error Err = llvm::Error::success();
536#ifdef __EMSCRIPTEN__
537 auto Executor = std::make_unique<WasmIncrementalExecutor>(*TSCtx);
538#else
539 auto Executor =
540 std::make_unique<IncrementalExecutor>(*TSCtx, *JITBuilder, Err);
541#endif
542 if (!Err)
543 IncrExecutor = std::move(Executor);
544
545 return Err;
546}
548void Interpreter::ResetExecutor() { IncrExecutor.reset(); }
549
551 assert(T.TheModule);
552 LLVM_DEBUG(
553 llvm::dbgs() << "execute-ptu "
554 << (llvm::is_contained(PTUs, T)
555 ? std::distance(PTUs.begin(), llvm::find(PTUs, T))
556 : -1)
557 << ": [TU=" << T.TUPart << ", M=" << T.TheModule.get()
558 << " (" << T.TheModule->getName() << ")]\n");
559 if (!IncrExecutor) {
560 auto Err = CreateExecutor();
561 if (Err)
562 return Err;
563 }
564 // FIXME: Add a callback to retain the llvm::Module once the JIT is done.
565 if (auto Err = IncrExecutor->addModule(T))
566 return Err;
567
568 if (auto Err = IncrExecutor->runCtors())
569 return Err;
570
571 return llvm::Error::success();
572}
573
574llvm::Error Interpreter::ParseAndExecute(llvm::StringRef Code, Value *V) {
575
576 auto PTU = Parse(Code);
577 if (!PTU)
578 return PTU.takeError();
579 if (PTU->TheModule)
580 if (llvm::Error Err = Execute(*PTU))
581 return Err;
582
583 if (LastValue.isValid()) {
584 if (!V) {
585 LastValue.dump();
586 LastValue.clear();
587 } else
588 *V = std::move(LastValue);
589 }
590 return llvm::Error::success();
592
595 if (!IncrExecutor)
596 return llvm::make_error<llvm::StringError>("Operation failed. "
597 "No execution engine",
598 std::error_code());
599 llvm::StringRef MangledName = Act->getCodeGen()->GetMangledName(GD);
600 return getSymbolAddress(MangledName);
602
604Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
605 if (!IncrExecutor)
606 return llvm::make_error<llvm::StringError>("Operation failed. "
607 "No execution engine",
608 std::error_code());
609
610 return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName);
612
614Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
615 if (!IncrExecutor)
616 return llvm::make_error<llvm::StringError>("Operation failed. "
617 "No execution engine",
618 std::error_code());
619
620 return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName);
621}
622
623llvm::Error Interpreter::Undo(unsigned N) {
624
625 if (getEffectivePTUSize() == 0) {
626 return llvm::make_error<llvm::StringError>("Operation failed. "
627 "No input left to undo",
628 std::error_code());
629 } else if (N > getEffectivePTUSize()) {
630 return llvm::make_error<llvm::StringError>(
631 llvm::formatv(
632 "Operation failed. Wanted to undo {0} inputs, only have {1}.", N,
633 getEffectivePTUSize()),
634 std::error_code());
635 }
636
637 for (unsigned I = 0; I < N; I++) {
638 if (IncrExecutor) {
639 if (llvm::Error Err = IncrExecutor->removeModule(PTUs.back()))
640 return Err;
641 }
642
643 IncrParser->CleanUpPTU(PTUs.back().TUPart);
644 PTUs.pop_back();
645 }
646 return llvm::Error::success();
647}
648
649llvm::Error Interpreter::LoadDynamicLibrary(const char *name) {
650#ifdef __EMSCRIPTEN__
651 void *handle = dlopen(name, RTLD_NOW | RTLD_GLOBAL);
652 if (!handle) {
653 llvm::errs() << dlerror() << '\n';
654 return llvm::make_error<llvm::StringError>("Failed to load dynamic library",
655 llvm::inconvertibleErrorCode());
656 }
657#else
658 auto EE = getExecutionEngine();
659 if (!EE)
660 return EE.takeError();
661
662 if (llvm::Expected<
663 std::unique_ptr<llvm::orc::EPCDynamicLibrarySearchGenerator>>
664 DLSG = llvm::orc::EPCDynamicLibrarySearchGenerator::Load(
665 EE->getExecutionSession(), name))
666 // FIXME: Eventually we should put each library in its own JITDylib and
667 // turn off process symbols by default.
668 EE->getProcessSymbolsJITDylib()->addGenerator(std::move(*DLSG));
669 else
670 return DLSG.takeError();
671#endif
672
673 return llvm::Error::success();
674}
675} // end namespace clang
Defines the clang::ASTContext interface.
#define V(N, I)
Definition: ASTContext.h:3597
Expr * E
Defines the clang::FrontendAction interface and various convenience abstract classes (clang::ASTFront...
CompileCommand Cmd
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:188
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()
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.
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:231
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:355
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()
static llvm::Expected< std::unique_ptr< llvm::orc::LLJITBuilder > > createDefaultJITBuilder(llvm::orc::JITTargetMachineBuilder JTMB)
Provides top-level interfaces for incremental compilation and execution.
Definition: Interpreter.h:86
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)
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)
virtual ~Interpreter()
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
static llvm::Expected< std::unique_ptr< llvm::orc::LLJITBuilder > > createLLJITBuilder(std::unique_ptr< llvm::orc::ExecutorProcessControl > EPC, llvm::StringRef OrcRuntimePath)
static llvm::Expected< std::unique_ptr< Interpreter > > create(std::unique_ptr< CompilerInstance > CI, std::unique_ptr< llvm::orc::LLJITBuilder > JITBuilder=nullptr)
const ASTContext & getASTContext() const
llvm::Expected< llvm::orc::LLJIT & > getExecutionEngine()
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:777
std::string Triple
The name of the target triple to compile for.
Definition: TargetOptions.h:29
void FlushDiagnostics(DiagnosticsEngine &Diags) const
FlushDiagnostics - Flush the buffered diagnostics to an given diagnostic engine.
void dump() const
Definition: Value.cpp:251
void clear()
Definition: Value.cpp:216
bool isValid() const
Definition: Value.h:133
Command - An executable path/name and argument vector to execute.
Definition: Job.h:106
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:99
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
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.
static llvm::Expected< llvm::orc::JITTargetMachineBuilder > createJITTargetMachineBuilder(const std::string &TT)
std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)
@ Success
Annotation was successful.
OffloadArch
Definition: OffloadArch.h:18
@ Parse
Parse the block; this code is always used.
const char *const Runtimes
const FunctionProtoType * T
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.
std::unique_ptr< llvm::Module > TheModule
The llvm IR produced for the input.