1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
13 //===----------------------------------------------------------------------===
15 // This file defines alternate interfaces to core functions that are more
16 // readily callable by Rust's FFI.
18 //===----------------------------------------------------------------------===
21 using namespace llvm::sys;
23 static const char *LLVMRustError;
25 extern cl::opt<bool> EnableARMEHABI;
27 extern "C" LLVMMemoryBufferRef
28 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
29 LLVMMemoryBufferRef MemBuf = NULL;
30 LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
31 const_cast<char **>(&LLVMRustError));
35 extern "C" const char *LLVMRustGetLastError(void) {
39 extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
41 extern "C" void LLVMRustAddPrintModulePass(LLVMPassManagerRef PMR,
44 PassManager *PM = unwrap<PassManager>(PMR);
45 std::string ErrorInfo;
46 raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
47 formatted_raw_ostream FOS(OS);
48 PM->add(createPrintModulePass(&FOS));
52 void LLVMInitializeX86TargetInfo();
53 void LLVMInitializeX86Target();
54 void LLVMInitializeX86TargetMC();
55 void LLVMInitializeX86AsmPrinter();
56 void LLVMInitializeX86AsmParser();
59 void LLVMInitializeARMTargetInfo();
60 void LLVMInitializeARMTarget();
61 void LLVMInitializeARMTargetMC();
62 void LLVMInitializeARMAsmPrinter();
63 void LLVMInitializeARMAsmParser();
65 void LLVMInitializeMipsTargetInfo();
66 void LLVMInitializeMipsTarget();
67 void LLVMInitializeMipsTargetMC();
68 void LLVMInitializeMipsAsmPrinter();
69 void LLVMInitializeMipsAsmParser();
70 // Only initialize the platforms supported by Rust here,
71 // because using --llvm-root will have multiple platforms
72 // that rustllvm doesn't actually link to and it's pointless to put target info
73 // into the registry that Rust can not generate machine code for.
75 void LLVMRustInitializeTargets() {
76 LLVMInitializeX86TargetInfo();
77 LLVMInitializeX86Target();
78 LLVMInitializeX86TargetMC();
79 LLVMInitializeX86AsmPrinter();
80 LLVMInitializeX86AsmParser();
82 LLVMInitializeARMTargetInfo();
83 LLVMInitializeARMTarget();
84 LLVMInitializeARMTargetMC();
85 LLVMInitializeARMAsmPrinter();
86 LLVMInitializeARMAsmParser();
88 LLVMInitializeMipsTargetInfo();
89 LLVMInitializeMipsTarget();
90 LLVMInitializeMipsTargetMC();
91 LLVMInitializeMipsAsmPrinter();
92 LLVMInitializeMipsAsmParser();
95 // Custom memory manager for MCJITting. It needs special features
96 // that the generic JIT memory manager doesn't entail. Based on
97 // code from LLI, change where needed for Rust.
98 class RustMCJITMemoryManager : public JITMemoryManager {
100 SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
101 SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
102 SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
104 DenseSet<DynamicLibrary*> crates;
106 RustMCJITMemoryManager(void* sym) : __morestack(sym) { }
107 ~RustMCJITMemoryManager();
109 bool loadCrate(const char*, std::string*);
111 virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
114 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
115 unsigned SectionID, bool isReadOnly);
116 bool finalizeMemory(std::string *ErrMsg) { return false; }
118 virtual bool applyPermissions(std::string *Str);
120 virtual void *getPointerToNamedFunction(const std::string &Name,
121 bool AbortOnFailure = true);
123 // Invalidate instruction cache for code sections. Some platforms with
124 // separate data cache and instruction cache require explicit cache flush,
125 // otherwise JIT code manipulations (like resolved relocations) will get to
126 // the data cache but not to the instruction cache.
127 virtual void invalidateInstructionCache();
129 // The MCJITMemoryManager doesn't use the following functions, so we don't
130 // need implement them.
131 virtual void setMemoryWritable() {
132 llvm_unreachable("Unimplemented call");
134 virtual void setMemoryExecutable() {
135 llvm_unreachable("Unimplemented call");
137 virtual void setPoisonMemory(bool poison) {
138 llvm_unreachable("Unimplemented call");
140 virtual void AllocateGOT() {
141 llvm_unreachable("Unimplemented call");
143 virtual uint8_t *getGOTBase() const {
144 llvm_unreachable("Unimplemented call");
147 virtual uint8_t *startFunctionBody(const Function *F,
148 uintptr_t &ActualSize){
149 llvm_unreachable("Unimplemented call");
152 virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
153 unsigned Alignment) {
154 llvm_unreachable("Unimplemented call");
157 virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
158 uint8_t *FunctionEnd) {
159 llvm_unreachable("Unimplemented call");
161 virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
162 llvm_unreachable("Unimplemented call");
165 virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
166 llvm_unreachable("Unimplemented call");
169 virtual void deallocateFunctionBody(void *Body) {
170 llvm_unreachable("Unimplemented call");
172 virtual uint8_t* startExceptionTable(const Function* F,
173 uintptr_t &ActualSize) {
174 llvm_unreachable("Unimplemented call");
177 virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
178 uint8_t *TableEnd, uint8_t* FrameRegister) {
179 llvm_unreachable("Unimplemented call");
181 virtual void deallocateExceptionTable(void *ET) {
182 llvm_unreachable("Unimplemented call");
186 bool RustMCJITMemoryManager::loadCrate(const char* file, std::string* err) {
187 DynamicLibrary crate = DynamicLibrary::getPermanentLibrary(file,
190 if(crate.isValid()) {
191 crates.insert(&crate);
199 uint8_t *RustMCJITMemoryManager::allocateDataSection(uintptr_t Size,
205 uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment);
206 AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size));
210 bool RustMCJITMemoryManager::applyPermissions(std::string *Str) {
215 uint8_t *RustMCJITMemoryManager::allocateCodeSection(uintptr_t Size,
217 unsigned SectionID) {
220 unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1);
222 // Look in the list of free code memory regions and use a block there if one
224 for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) {
225 sys::MemoryBlock &MB = FreeCodeMem[i];
226 if (MB.size() >= NeedAllocate) {
227 Addr = (uintptr_t)MB.base();
228 uintptr_t EndOfBlock = Addr + MB.size();
229 // Align the address.
230 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
231 // Store cutted free memory block.
232 FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size),
233 EndOfBlock - Addr - Size);
234 return (uint8_t*)Addr;
238 // No pre-allocated free block was large enough. Allocate a new memory region.
239 sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0);
241 AllocatedCodeMem.push_back(MB);
242 Addr = (uintptr_t)MB.base();
243 uintptr_t EndOfBlock = Addr + MB.size();
244 // Align the address.
245 Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
246 // The AllocateRWX may allocate much more memory than we need. In this case,
247 // we store the unused memory as a free memory block.
248 unsigned FreeSize = EndOfBlock-Addr-Size;
250 FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize));
252 // Return aligned address
253 return (uint8_t*)Addr;
256 void RustMCJITMemoryManager::invalidateInstructionCache() {
257 for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
258 sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(),
259 AllocatedCodeMem[i].size());
262 void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
263 bool AbortOnFailure) {
265 // Force the following functions to be linked in to anything that uses the
266 // JIT. This is a hack designed to work around the all-too-clever Glibc
267 // strategy of making these functions work differently when inlined vs. when
268 // not inlined, and hiding their real definitions in a separate archive file
269 // that the dynamic linker can't see. For more info, search for
270 // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
271 if (Name == "stat") return (void*)(intptr_t)&stat;
272 if (Name == "fstat") return (void*)(intptr_t)&fstat;
273 if (Name == "lstat") return (void*)(intptr_t)&lstat;
274 if (Name == "stat64") return (void*)(intptr_t)&stat64;
275 if (Name == "fstat64") return (void*)(intptr_t)&fstat64;
276 if (Name == "lstat64") return (void*)(intptr_t)&lstat64;
277 if (Name == "atexit") return (void*)(intptr_t)&atexit;
278 if (Name == "mknod") return (void*)(intptr_t)&mknod;
281 if (Name == "__morestack" || Name == "___morestack") return &__morestack;
283 const char *NameStr = Name.c_str();
285 // Look through loaded crates and main for symbols.
287 void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
290 // If it wasn't found and if it starts with an underscore ('_') character,
291 // try again without the underscore.
292 if (NameStr[0] == '_') {
293 Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1);
298 report_fatal_error("Program used external function '" + Name +
299 "' which could not be resolved!");
303 RustMCJITMemoryManager::~RustMCJITMemoryManager() {
304 for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
305 sys::Memory::ReleaseRWX(AllocatedCodeMem[i]);
306 for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i)
307 free(AllocatedDataMem[i].base());
311 LLVMRustPrepareJIT(void* __morestack) {
312 // An execution engine will take ownership of this later
313 // and clean it up for us.
315 return (void*) new RustMCJITMemoryManager(__morestack);
319 LLVMRustLoadCrate(void* mem, const char* crate) {
320 RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem;
325 if(!manager->loadCrate(crate, &Err)) {
326 LLVMRustError = Err.c_str();
333 extern "C" LLVMExecutionEngineRef
334 LLVMRustBuildJIT(void* mem,
336 bool EnableSegmentedStacks) {
338 InitializeNativeTarget();
339 InitializeNativeTargetAsmPrinter();
340 InitializeNativeTargetAsmParser();
343 TargetOptions Options;
344 Options.JITEmitDebugInfo = true;
345 Options.NoFramePointerElim = true;
346 Options.EnableSegmentedStacks = EnableSegmentedStacks;
347 RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem;
350 ExecutionEngine* EE = EngineBuilder(unwrap(M))
352 .setTargetOptions(Options)
353 .setJITMemoryManager(MM)
355 .setAllocateGVsWithCode(false)
358 if(!EE || Err != "") {
359 LLVMRustError = Err.c_str();
360 // The EngineBuilder only takes ownership of these two structures if the
361 // create() call is successful, but here it wasn't successful.
362 LLVMDisposeModule(M);
367 MM->invalidateInstructionCache();
372 LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
377 TargetMachine::CodeGenFileType FileType,
378 CodeGenOpt::Level OptLevel,
379 bool EnableSegmentedStacks) {
381 LLVMRustInitializeTargets();
383 // Initializing the command-line options more than once is not
384 // allowed. So, check if they've already been initialized.
385 // (This could happen if we're being called from rustpkg, for
387 if (!EnableARMEHABI) {
389 const char* argv[] = {"rustc", "-arm-enable-ehabi",
390 "-arm-enable-ehabi-descriptors"};
391 cl::ParseCommandLineOptions(argc, argv);
394 TargetOptions Options;
395 Options.NoFramePointerElim = true;
396 Options.EnableSegmentedStacks = EnableSegmentedStacks;
397 Options.FixedStackSegmentSize = 2 * 1024 * 1024; // XXX: This is too big.
399 PassManager *PM = unwrap<PassManager>(PMR);
402 std::string Trip(Triple::normalize(triple));
403 std::string FeaturesStr(feature);
404 std::string CPUStr("generic");
405 const Target *TheTarget = TargetRegistry::lookupTarget(Trip, Err);
406 TargetMachine *Target =
407 TheTarget->createTargetMachine(Trip, CPUStr, FeaturesStr,
408 Options, Reloc::PIC_,
409 CodeModel::Default, OptLevel);
410 Target->addAnalysisPasses(*PM);
412 bool NoVerify = false;
413 std::string ErrorInfo;
414 raw_fd_ostream OS(path, ErrorInfo,
415 raw_fd_ostream::F_Binary);
416 if (ErrorInfo != "") {
417 LLVMRustError = ErrorInfo.c_str();
420 formatted_raw_ostream FOS(OS);
422 bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, NoVerify);
430 extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(LLVMContextRef C,
431 const char *Filename) {
433 Module *m = ParseAssemblyFile(Filename, d, *unwrap(C));
437 LLVMRustError = d.getMessage().str().c_str();
442 extern "C" LLVMModuleRef LLVMRustParseBitcode(LLVMMemoryBufferRef MemBuf) {
444 return LLVMParseBitcode(MemBuf, &M, const_cast<char **>(&LLVMRustError))
448 extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
449 LLVMBool SignExtend) {
450 return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
453 extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
456 LLVMBool SignExtend) {
457 unsigned long long N = N_hi;
460 return LLVMConstInt(IntTy, N, SignExtend);
463 extern bool llvm::TimePassesIsEnabled;
464 extern "C" void LLVMRustEnableTimePasses() {
465 TimePassesIsEnabled = true;
468 extern "C" void LLVMRustPrintPassTimings() {
469 raw_fd_ostream OS (2, false); // stderr.
470 TimerGroup::printAll(OS);
473 extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
475 LLVMTypeRef FunctionTy) {
476 return wrap(unwrap(M)->getOrInsertFunction(Name,
477 unwrap<FunctionType>(FunctionTy)));
480 extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
481 return wrap(Type::getMetadataTy(*unwrap(C)));
484 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
487 AtomicOrdering order,
488 unsigned alignment) {
489 LoadInst* li = new LoadInst(unwrap(source),0);
490 li->setVolatile(true);
491 li->setAtomic(order);
492 li->setAlignment(alignment);
493 return wrap(unwrap(B)->Insert(li, Name));
496 extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
499 AtomicOrdering order,
500 unsigned alignment) {
501 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
502 si->setVolatile(true);
503 si->setAtomic(order);
504 si->setAlignment(alignment);
505 return wrap(unwrap(B)->Insert(si));
508 extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
512 AtomicOrdering order) {
513 return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
514 unwrap(source), order));
516 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
517 return wrap(unwrap(B)->CreateFence(order));
520 extern "C" void LLVMSetDebug(int Enabled) {
526 extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
529 LLVMBool HasSideEffects,
530 LLVMBool IsAlignStack,
532 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
533 Constraints, HasSideEffects,
534 IsAlignStack, (InlineAsm::AsmDialect) Dialect));
538 * This function is intended to be a threadsafe interface into enabling a
539 * multithreaded LLVM. This is invoked at the start of the translation phase of
540 * compilation to ensure that LLVM is ready.
542 * All of trans properly isolates LLVM with the use of a different
543 * LLVMContextRef per task, thus allowing parallel compilation of different
544 * crates in the same process. At the time of this writing, the use case for
545 * this is unit tests for rusti, but there are possible other applications.
547 extern "C" bool LLVMRustStartMultithreading() {
550 assert(lock.acquire());
551 if (!LLVMIsMultithreaded()) {
552 ret = LLVMStartMultithreaded();
554 assert(lock.release());
559 typedef DIBuilder* DIBuilderRef;
561 template<typename DIT>
562 DIT unwrapDI(LLVMValueRef ref) {
563 return DIT(ref ? unwrap<MDNode>(ref) : NULL);
566 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
567 return new DIBuilder(*unwrap(M));
570 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
574 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
578 extern "C" void LLVMDIBuilderCreateCompileUnit(
579 DIBuilderRef Builder,
583 const char* Producer,
587 const char* SplitName) {
588 Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
589 Flags, RuntimeVer, SplitName);
592 extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
593 DIBuilderRef Builder,
594 const char* Filename,
595 const char* Directory) {
596 return wrap(Builder->createFile(Filename, Directory));
599 extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
600 DIBuilderRef Builder,
602 LLVMValueRef ParameterTypes) {
603 return wrap(Builder->createSubroutineType(
604 unwrapDI<DIFile>(File),
605 unwrapDI<DIArray>(ParameterTypes)));
608 extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
609 DIBuilderRef Builder,
612 const char* LinkageName,
624 return wrap(Builder->createFunction(
625 unwrapDI<DIScope>(Scope), Name, LinkageName,
626 unwrapDI<DIFile>(File), LineNo,
627 unwrapDI<DIType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
629 unwrap<Function>(Fn),
630 unwrapDI<MDNode*>(TParam),
631 unwrapDI<MDNode*>(Decl)));
634 extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType(
635 DIBuilderRef Builder,
638 uint64_t AlignInBits,
640 return wrap(Builder->createBasicType(
642 AlignInBits, Encoding));
645 extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType(
646 DIBuilderRef Builder,
647 LLVMValueRef PointeeTy,
649 uint64_t AlignInBits,
651 return wrap(Builder->createPointerType(
652 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
655 extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
656 DIBuilderRef Builder,
662 uint64_t AlignInBits,
664 LLVMValueRef DerivedFrom,
665 LLVMValueRef Elements,
666 unsigned RunTimeLang,
667 LLVMValueRef VTableHolder) {
668 return wrap(Builder->createStructType(
669 unwrapDI<DIDescriptor>(Scope), Name,
670 unwrapDI<DIFile>(File), LineNumber,
671 SizeInBits, AlignInBits, Flags,
672 unwrapDI<DIType>(DerivedFrom),
673 unwrapDI<DIArray>(Elements), RunTimeLang,
674 unwrapDI<MDNode*>(VTableHolder)));
677 extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
678 DIBuilderRef Builder,
684 uint64_t AlignInBits,
685 uint64_t OffsetInBits,
688 return wrap(Builder->createMemberType(
689 unwrapDI<DIDescriptor>(Scope), Name,
690 unwrapDI<DIFile>(File), LineNo,
691 SizeInBits, AlignInBits, OffsetInBits, Flags,
692 unwrapDI<DIType>(Ty)));
695 extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
696 DIBuilderRef Builder,
701 return wrap(Builder->createLexicalBlock(
702 unwrapDI<DIDescriptor>(Scope),
703 unwrapDI<DIFile>(File), Line, Col));
706 extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
707 DIBuilderRef Builder,
717 return wrap(Builder->createLocalVariable(Tag,
718 unwrapDI<DIDescriptor>(Scope), Name,
719 unwrapDI<DIFile>(File),
721 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
724 extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType(
725 DIBuilderRef Builder,
727 uint64_t AlignInBits,
729 LLVMValueRef Subscripts) {
730 return wrap(Builder->createArrayType(Size, AlignInBits,
731 unwrapDI<DIType>(Ty),
732 unwrapDI<DIArray>(Subscripts)));
735 extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType(
736 DIBuilderRef Builder,
738 uint64_t AlignInBits,
740 LLVMValueRef Subscripts) {
741 return wrap(Builder->createVectorType(Size, AlignInBits,
742 unwrapDI<DIType>(Ty),
743 unwrapDI<DIArray>(Subscripts)));
746 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(
747 DIBuilderRef Builder,
750 return wrap(Builder->getOrCreateSubrange(Lo, Count));
753 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray(
754 DIBuilderRef Builder,
757 return wrap(Builder->getOrCreateArray(
758 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
761 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
762 DIBuilderRef Builder,
764 LLVMValueRef VarInfo,
765 LLVMBasicBlockRef InsertAtEnd) {
766 return wrap(Builder->insertDeclare(
768 unwrapDI<DIVariable>(VarInfo),
769 unwrap(InsertAtEnd)));
772 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
773 DIBuilderRef Builder,
775 LLVMValueRef VarInfo,
776 LLVMValueRef InsertBefore) {
777 return wrap(Builder->insertDeclare(
779 unwrapDI<DIVariable>(VarInfo),
780 unwrap<Instruction>(InsertBefore)));
783 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator(
784 DIBuilderRef Builder,
788 return wrap(Builder->createEnumerator(Name, Val));
791 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerationType(
792 DIBuilderRef Builder,
798 uint64_t AlignInBits,
799 LLVMValueRef Elements,
800 LLVMValueRef ClassType)
802 return wrap(Builder->createEnumerationType(
803 unwrapDI<DIDescriptor>(Scope),
805 unwrapDI<DIFile>(File),
809 unwrapDI<DIArray>(Elements),
810 unwrapDI<DIType>(ClassType)));
813 extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
814 DIBuilderRef Builder,
820 uint64_t AlignInBits,
822 LLVMValueRef Elements,
823 unsigned RunTimeLang)
825 return wrap(Builder->createUnionType(
826 unwrapDI<DIDescriptor>(Scope),
828 unwrapDI<DIFile>(File),
833 unwrapDI<DIArray>(Elements),