]> git.lizzy.rs Git - rust.git/blob - src/rustllvm/RustWrapper.cpp
04c062072d6cb4d8fd9dc4152f0af3f028f95f25
[rust.git] / src / rustllvm / RustWrapper.cpp
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.
4 //
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.
10
11 #include "rustllvm.h"
12
13 //===----------------------------------------------------------------------===
14 //
15 // This file defines alternate interfaces to core functions that are more
16 // readily callable by Rust's FFI.
17 //
18 //===----------------------------------------------------------------------===
19
20 using namespace llvm;
21 using namespace llvm::sys;
22
23 static const char *LLVMRustError;
24
25 extern cl::opt<bool> EnableARMEHABI;
26
27 extern "C" LLVMMemoryBufferRef
28 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
29   LLVMMemoryBufferRef MemBuf = NULL;
30   LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
31     const_cast<char **>(&LLVMRustError));
32   return MemBuf;
33 }
34
35 extern "C" const char *LLVMRustGetLastError(void) {
36   return LLVMRustError;
37 }
38
39 extern "C" void LLVMAddBasicAliasAnalysisPass(LLVMPassManagerRef PM);
40
41 extern "C" void LLVMRustAddPrintModulePass(LLVMPassManagerRef PMR,
42                                            LLVMModuleRef M,
43                                            const char* path) {
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));
49   PM->run(*unwrap(M));
50 }
51
52 void LLVMInitializeX86TargetInfo();
53 void LLVMInitializeX86Target();
54 void LLVMInitializeX86TargetMC();
55 void LLVMInitializeX86AsmPrinter();
56 void LLVMInitializeX86AsmParser();
57
58
59 void LLVMInitializeARMTargetInfo();
60 void LLVMInitializeARMTarget();
61 void LLVMInitializeARMTargetMC();
62 void LLVMInitializeARMAsmPrinter();
63 void LLVMInitializeARMAsmParser();
64
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.
74
75 void LLVMRustInitializeTargets() {
76   LLVMInitializeX86TargetInfo();
77   LLVMInitializeX86Target();
78   LLVMInitializeX86TargetMC();
79   LLVMInitializeX86AsmPrinter();
80   LLVMInitializeX86AsmParser();
81
82   LLVMInitializeARMTargetInfo();
83   LLVMInitializeARMTarget();
84   LLVMInitializeARMTargetMC();
85   LLVMInitializeARMAsmPrinter();
86   LLVMInitializeARMAsmParser();
87
88   LLVMInitializeMipsTargetInfo();
89   LLVMInitializeMipsTarget();
90   LLVMInitializeMipsTargetMC();
91   LLVMInitializeMipsAsmPrinter();
92   LLVMInitializeMipsAsmParser();
93 }
94
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 {
99 public:
100   SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
101   SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
102   SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
103   void* __morestack;
104   DenseSet<DynamicLibrary*> crates;
105
106   RustMCJITMemoryManager(void* sym) : __morestack(sym) { }
107   ~RustMCJITMemoryManager();
108
109   bool loadCrate(const char*, std::string*);
110
111   virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
112                                        unsigned SectionID);
113
114   virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
115                                        unsigned SectionID, bool isReadOnly);
116   bool finalizeMemory(std::string *ErrMsg) { return false; }
117
118   virtual bool applyPermissions(std::string *Str);
119
120   virtual void *getPointerToNamedFunction(const std::string &Name,
121                                           bool AbortOnFailure = true);
122
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();
128
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");
133   }
134   virtual void setMemoryExecutable() {
135     llvm_unreachable("Unimplemented call");
136   }
137   virtual void setPoisonMemory(bool poison) {
138     llvm_unreachable("Unimplemented call");
139   }
140   virtual void AllocateGOT() {
141     llvm_unreachable("Unimplemented call");
142   }
143   virtual uint8_t *getGOTBase() const {
144     llvm_unreachable("Unimplemented call");
145     return 0;
146   }
147   virtual uint8_t *startFunctionBody(const Function *F,
148                                      uintptr_t &ActualSize){
149     llvm_unreachable("Unimplemented call");
150     return 0;
151   }
152   virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
153                                 unsigned Alignment) {
154     llvm_unreachable("Unimplemented call");
155     return 0;
156   }
157   virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
158                                uint8_t *FunctionEnd) {
159     llvm_unreachable("Unimplemented call");
160   }
161   virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
162     llvm_unreachable("Unimplemented call");
163     return 0;
164   }
165   virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
166     llvm_unreachable("Unimplemented call");
167     return 0;
168   }
169   virtual void deallocateFunctionBody(void *Body) {
170     llvm_unreachable("Unimplemented call");
171   }
172   virtual uint8_t* startExceptionTable(const Function* F,
173                                        uintptr_t &ActualSize) {
174     llvm_unreachable("Unimplemented call");
175     return 0;
176   }
177   virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
178                                  uint8_t *TableEnd, uint8_t* FrameRegister) {
179     llvm_unreachable("Unimplemented call");
180   }
181   virtual void deallocateExceptionTable(void *ET) {
182     llvm_unreachable("Unimplemented call");
183   }
184 };
185
186 bool RustMCJITMemoryManager::loadCrate(const char* file, std::string* err) {
187   DynamicLibrary crate = DynamicLibrary::getPermanentLibrary(file,
188                                                              err);
189
190   if(crate.isValid()) {
191     crates.insert(&crate);
192
193     return true;
194   }
195
196   return false;
197 }
198
199 uint8_t *RustMCJITMemoryManager::allocateDataSection(uintptr_t Size,
200                                                      unsigned Alignment,
201                                                      unsigned SectionID,
202                                                      bool isReadOnly) {
203   if (!Alignment)
204     Alignment = 16;
205   uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment);
206   AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size));
207   return Addr;
208 }
209
210 bool RustMCJITMemoryManager::applyPermissions(std::string *Str) {
211     // Empty.
212     return true;
213 }
214
215 uint8_t *RustMCJITMemoryManager::allocateCodeSection(uintptr_t Size,
216                                                      unsigned Alignment,
217                                                      unsigned SectionID) {
218   if (!Alignment)
219     Alignment = 16;
220   unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1);
221   uintptr_t Addr = 0;
222   // Look in the list of free code memory regions and use a block there if one
223   // is available.
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;
235     }
236   }
237
238   // No pre-allocated free block was large enough. Allocate a new memory region.
239   sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0);
240
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;
249   if (FreeSize > 16)
250     FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize));
251
252   // Return aligned address
253   return (uint8_t*)Addr;
254 }
255
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());
260 }
261
262 void *RustMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
263                                                        bool AbortOnFailure) {
264 #ifdef __linux__
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;
279 #endif
280
281   if (Name == "__morestack" || Name == "___morestack") return &__morestack;
282
283   const char *NameStr = Name.c_str();
284
285   // Look through loaded crates and main for symbols.
286
287   void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
288   if (Ptr) return Ptr;
289
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);
294     if (Ptr) return Ptr;
295   }
296
297   if (AbortOnFailure)
298     report_fatal_error("Program used external function '" + Name +
299                       "' which could not be resolved!");
300   return 0;
301 }
302
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());
308 }
309
310 extern "C" void*
311 LLVMRustPrepareJIT(void* __morestack) {
312   // An execution engine will take ownership of this later
313   // and clean it up for us.
314
315   return (void*) new RustMCJITMemoryManager(__morestack);
316 }
317
318 extern "C" bool
319 LLVMRustLoadCrate(void* mem, const char* crate) {
320   RustMCJITMemoryManager* manager = (RustMCJITMemoryManager*) mem;
321   std::string Err;
322
323   assert(manager);
324
325   if(!manager->loadCrate(crate, &Err)) {
326     LLVMRustError = Err.c_str();
327     return false;
328   }
329
330   return true;
331 }
332
333 extern "C" LLVMExecutionEngineRef
334 LLVMRustBuildJIT(void* mem,
335                  LLVMModuleRef M,
336                  bool EnableSegmentedStacks) {
337
338   InitializeNativeTarget();
339   InitializeNativeTargetAsmPrinter();
340   InitializeNativeTargetAsmParser();
341
342   std::string Err;
343   TargetOptions Options;
344   Options.JITEmitDebugInfo = true;
345   Options.NoFramePointerElim = true;
346   Options.EnableSegmentedStacks = EnableSegmentedStacks;
347   RustMCJITMemoryManager* MM = (RustMCJITMemoryManager*) mem;
348   assert(MM);
349
350   ExecutionEngine* EE = EngineBuilder(unwrap(M))
351     .setErrorStr(&Err)
352     .setTargetOptions(Options)
353     .setJITMemoryManager(MM)
354     .setUseMCJIT(true)
355     .setAllocateGVsWithCode(false)
356     .create();
357
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);
363     delete MM;
364     return NULL;
365   }
366
367   MM->invalidateInstructionCache();
368   return wrap(EE);
369 }
370
371 extern "C" bool
372 LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
373                         LLVMModuleRef M,
374                         const char *triple,
375                         const char *feature,
376                         const char *path,
377                         TargetMachine::CodeGenFileType FileType,
378                         CodeGenOpt::Level OptLevel,
379       bool EnableSegmentedStacks) {
380
381   LLVMRustInitializeTargets();
382
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
386   // example.)
387   if (!EnableARMEHABI) {
388     int argc = 3;
389     const char* argv[] = {"rustc", "-arm-enable-ehabi",
390         "-arm-enable-ehabi-descriptors"};
391     cl::ParseCommandLineOptions(argc, argv);
392   }
393
394   TargetOptions Options;
395   Options.NoFramePointerElim = true;
396   Options.EnableSegmentedStacks = EnableSegmentedStacks;
397   Options.FixedStackSegmentSize = 2 * 1024 * 1024;  // XXX: This is too big.
398
399   PassManager *PM = unwrap<PassManager>(PMR);
400
401   std::string Err;
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);
411
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();
418     return false;
419   }
420   formatted_raw_ostream FOS(OS);
421
422   bool foo = Target->addPassesToEmitFile(*PM, FOS, FileType, NoVerify);
423   assert(!foo);
424   (void)foo;
425   PM->run(*unwrap(M));
426   delete Target;
427   return true;
428 }
429
430 extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(LLVMContextRef C,
431                                                    const char *Filename) {
432   SMDiagnostic d;
433   Module *m = ParseAssemblyFile(Filename, d, *unwrap(C));
434   if (m) {
435     return wrap(m);
436   } else {
437     LLVMRustError = d.getMessage().str().c_str();
438     return NULL;
439   }
440 }
441
442 extern "C" LLVMModuleRef LLVMRustParseBitcode(LLVMMemoryBufferRef MemBuf) {
443   LLVMModuleRef M;
444   return LLVMParseBitcode(MemBuf, &M, const_cast<char **>(&LLVMRustError))
445          ? NULL : M;
446 }
447
448 extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
449                                               LLVMBool SignExtend) {
450   return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
451 }
452
453 extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
454            unsigned N_hi,
455            unsigned N_lo,
456            LLVMBool SignExtend) {
457   unsigned long long N = N_hi;
458   N <<= 32;
459   N |= N_lo;
460   return LLVMConstInt(IntTy, N, SignExtend);
461 }
462
463 extern bool llvm::TimePassesIsEnabled;
464 extern "C" void LLVMRustEnableTimePasses() {
465   TimePassesIsEnabled = true;
466 }
467
468 extern "C" void LLVMRustPrintPassTimings() {
469   raw_fd_ostream OS (2, false); // stderr.
470   TimerGroup::printAll(OS);
471 }
472
473 extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
474                                                 const char* Name,
475                                                 LLVMTypeRef FunctionTy) {
476   return wrap(unwrap(M)->getOrInsertFunction(Name,
477                                              unwrap<FunctionType>(FunctionTy)));
478 }
479
480 extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
481   return wrap(Type::getMetadataTy(*unwrap(C)));
482 }
483
484 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
485                                             LLVMValueRef source,
486                                             const char* Name,
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));
494 }
495
496 extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
497                                              LLVMValueRef val,
498                                              LLVMValueRef target,
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));
506 }
507
508 extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
509                                                LLVMValueRef target,
510                                                LLVMValueRef old,
511                                                LLVMValueRef source,
512                                                AtomicOrdering order) {
513     return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
514                                                unwrap(source), order));
515 }
516 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
517     return wrap(unwrap(B)->CreateFence(order));
518 }
519
520 extern "C" void LLVMSetDebug(int Enabled) {
521 #ifndef NDEBUG
522   DebugFlag = Enabled;
523 #endif
524 }
525
526 extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
527                                       char *AsmString,
528                                       char *Constraints,
529                                       LLVMBool HasSideEffects,
530                                       LLVMBool IsAlignStack,
531                                       unsigned Dialect) {
532     return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
533                                Constraints, HasSideEffects,
534                                IsAlignStack, (InlineAsm::AsmDialect) Dialect));
535 }
536
537 /**
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.
541  *
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.
546  */
547 extern "C" bool LLVMRustStartMultithreading() {
548     static Mutex lock;
549     bool ret = true;
550     assert(lock.acquire());
551     if (!LLVMIsMultithreaded()) {
552         ret = LLVMStartMultithreaded();
553     }
554     assert(lock.release());
555     return ret;
556 }
557
558
559 typedef DIBuilder* DIBuilderRef;
560
561 template<typename DIT>
562 DIT unwrapDI(LLVMValueRef ref) {
563     return DIT(ref ? unwrap<MDNode>(ref) : NULL);
564 }
565
566 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
567     return new DIBuilder(*unwrap(M));
568 }
569
570 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
571     delete Builder;
572 }
573
574 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
575     Builder->finalize();
576 }
577
578 extern "C" void LLVMDIBuilderCreateCompileUnit(
579     DIBuilderRef Builder,
580     unsigned Lang,
581     const char* File,
582     const char* Dir,
583     const char* Producer,
584     bool isOptimized,
585     const char* Flags,
586     unsigned RuntimeVer,
587     const char* SplitName) {
588     Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
589         Flags, RuntimeVer, SplitName);
590 }
591
592 extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
593     DIBuilderRef Builder,
594     const char* Filename,
595     const char* Directory) {
596     return wrap(Builder->createFile(Filename, Directory));
597 }
598
599 extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
600     DIBuilderRef Builder,
601     LLVMValueRef File,
602     LLVMValueRef ParameterTypes) {
603     return wrap(Builder->createSubroutineType(
604         unwrapDI<DIFile>(File),
605         unwrapDI<DIArray>(ParameterTypes)));
606 }
607
608 extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
609     DIBuilderRef Builder,
610     LLVMValueRef Scope,
611     const char* Name,
612     const char* LinkageName,
613     LLVMValueRef File,
614     unsigned LineNo,
615     LLVMValueRef Ty,
616     bool isLocalToUnit,
617     bool isDefinition,
618     unsigned ScopeLine,
619     unsigned Flags,
620     bool isOptimized,
621     LLVMValueRef Fn,
622     LLVMValueRef TParam,
623     LLVMValueRef Decl) {
624     return wrap(Builder->createFunction(
625         unwrapDI<DIScope>(Scope), Name, LinkageName,
626         unwrapDI<DIFile>(File), LineNo,
627         unwrapDI<DIType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
628         Flags, isOptimized,
629         unwrap<Function>(Fn),
630         unwrapDI<MDNode*>(TParam),
631         unwrapDI<MDNode*>(Decl)));
632 }
633
634 extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType(
635     DIBuilderRef Builder,
636     const char* Name,
637     uint64_t SizeInBits,
638     uint64_t AlignInBits,
639     unsigned Encoding) {
640     return wrap(Builder->createBasicType(
641         Name, SizeInBits,
642         AlignInBits, Encoding));
643 }
644
645 extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType(
646     DIBuilderRef Builder,
647     LLVMValueRef PointeeTy,
648     uint64_t SizeInBits,
649     uint64_t AlignInBits,
650     const char* Name) {
651     return wrap(Builder->createPointerType(
652         unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
653 }
654
655 extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
656     DIBuilderRef Builder,
657     LLVMValueRef Scope,
658     const char* Name,
659     LLVMValueRef File,
660     unsigned LineNumber,
661     uint64_t SizeInBits,
662     uint64_t AlignInBits,
663     unsigned Flags,
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)));
675 }
676
677 extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
678     DIBuilderRef Builder,
679     LLVMValueRef Scope,
680     const char* Name,
681     LLVMValueRef File,
682     unsigned LineNo,
683     uint64_t SizeInBits,
684     uint64_t AlignInBits,
685     uint64_t OffsetInBits,
686     unsigned Flags,
687     LLVMValueRef Ty) {
688     return wrap(Builder->createMemberType(
689         unwrapDI<DIDescriptor>(Scope), Name,
690         unwrapDI<DIFile>(File), LineNo,
691         SizeInBits, AlignInBits, OffsetInBits, Flags,
692         unwrapDI<DIType>(Ty)));
693 }
694
695 extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
696     DIBuilderRef Builder,
697     LLVMValueRef Scope,
698     LLVMValueRef File,
699     unsigned Line,
700     unsigned Col) {
701     return wrap(Builder->createLexicalBlock(
702         unwrapDI<DIDescriptor>(Scope),
703         unwrapDI<DIFile>(File), Line, Col));
704 }
705
706 extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
707     DIBuilderRef Builder,
708     unsigned Tag,
709     LLVMValueRef Scope,
710     const char* Name,
711     LLVMValueRef File,
712     unsigned LineNo,
713     LLVMValueRef Ty,
714     bool AlwaysPreserve,
715     unsigned Flags,
716     unsigned ArgNo) {
717     return wrap(Builder->createLocalVariable(Tag,
718         unwrapDI<DIDescriptor>(Scope), Name,
719         unwrapDI<DIFile>(File),
720         LineNo,
721         unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
722 }
723
724 extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType(
725     DIBuilderRef Builder,
726     uint64_t Size,
727     uint64_t AlignInBits,
728     LLVMValueRef Ty,
729     LLVMValueRef Subscripts) {
730     return wrap(Builder->createArrayType(Size, AlignInBits,
731         unwrapDI<DIType>(Ty),
732         unwrapDI<DIArray>(Subscripts)));
733 }
734
735 extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType(
736     DIBuilderRef Builder,
737     uint64_t Size,
738     uint64_t AlignInBits,
739     LLVMValueRef Ty,
740     LLVMValueRef Subscripts) {
741     return wrap(Builder->createVectorType(Size, AlignInBits,
742         unwrapDI<DIType>(Ty),
743         unwrapDI<DIArray>(Subscripts)));
744 }
745
746 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(
747     DIBuilderRef Builder,
748     int64_t Lo,
749     int64_t Count) {
750     return wrap(Builder->getOrCreateSubrange(Lo, Count));
751 }
752
753 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray(
754     DIBuilderRef Builder,
755     LLVMValueRef* Ptr,
756     unsigned Count) {
757     return wrap(Builder->getOrCreateArray(
758         ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
759 }
760
761 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
762     DIBuilderRef Builder,
763     LLVMValueRef Val,
764     LLVMValueRef VarInfo,
765     LLVMBasicBlockRef InsertAtEnd) {
766     return wrap(Builder->insertDeclare(
767         unwrap(Val),
768         unwrapDI<DIVariable>(VarInfo),
769         unwrap(InsertAtEnd)));
770 }
771
772 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
773     DIBuilderRef Builder,
774     LLVMValueRef Val,
775     LLVMValueRef VarInfo,
776     LLVMValueRef InsertBefore) {
777     return wrap(Builder->insertDeclare(
778         unwrap(Val),
779         unwrapDI<DIVariable>(VarInfo),
780         unwrap<Instruction>(InsertBefore)));
781 }
782
783 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator(
784     DIBuilderRef Builder,
785     const char* Name,
786     uint64_t Val)
787 {
788     return wrap(Builder->createEnumerator(Name, Val));
789 }
790
791 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerationType(
792     DIBuilderRef Builder,
793     LLVMValueRef Scope,
794     const char* Name,
795     LLVMValueRef File,
796     unsigned LineNumber,
797     uint64_t SizeInBits,
798     uint64_t AlignInBits,
799     LLVMValueRef Elements,
800     LLVMValueRef ClassType)
801 {
802     return wrap(Builder->createEnumerationType(
803         unwrapDI<DIDescriptor>(Scope),
804         Name,
805         unwrapDI<DIFile>(File),
806         LineNumber,
807         SizeInBits,
808         AlignInBits,
809         unwrapDI<DIArray>(Elements),
810         unwrapDI<DIType>(ClassType)));
811 }
812
813 extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
814     DIBuilderRef Builder,
815     LLVMValueRef Scope,
816     const char* Name,
817     LLVMValueRef File,
818     unsigned LineNumber,
819     uint64_t SizeInBits,
820     uint64_t AlignInBits,
821     unsigned Flags,
822     LLVMValueRef Elements,
823     unsigned RunTimeLang)
824 {
825     return wrap(Builder->createUnionType(
826         unwrapDI<DIDescriptor>(Scope),
827         Name,
828         unwrapDI<DIFile>(File),
829         LineNumber,
830         SizeInBits,
831         AlignInBits,
832         Flags,
833         unwrapDI<DIArray>(Elements),
834         RunTimeLang));
835 }