]> git.lizzy.rs Git - rust.git/blob - src/rustllvm/RustWrapper.cpp
debuginfo: Remove some outdated stuff from LLVM DIBuilder binding.
[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 #include "llvm/Object/Archive.h"
13 #include "llvm/Object/ObjectFile.h"
14 #include "llvm/IR/DiagnosticInfo.h"
15 #include "llvm/IR/DiagnosticPrinter.h"
16 #include "llvm/IR/Instructions.h"
17
18 #include "llvm/IR/CallSite.h"
19
20 //===----------------------------------------------------------------------===
21 //
22 // This file defines alternate interfaces to core functions that are more
23 // readily callable by Rust's FFI.
24 //
25 //===----------------------------------------------------------------------===
26
27 using namespace llvm;
28 using namespace llvm::sys;
29 using namespace llvm::object;
30
31 // LLVMAtomicOrdering is already an enum - don't create another
32 // one.
33 static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) {
34   switch (Ordering) {
35     case LLVMAtomicOrderingNotAtomic:
36         return AtomicOrdering::NotAtomic;
37     case LLVMAtomicOrderingUnordered:
38         return AtomicOrdering::Unordered;
39     case LLVMAtomicOrderingMonotonic:
40         return AtomicOrdering::Monotonic;
41     case LLVMAtomicOrderingAcquire:
42         return AtomicOrdering::Acquire;
43     case LLVMAtomicOrderingRelease:
44         return AtomicOrdering::Release;
45     case LLVMAtomicOrderingAcquireRelease:
46         return AtomicOrdering::AcquireRelease;
47     case LLVMAtomicOrderingSequentiallyConsistent:
48         return AtomicOrdering::SequentiallyConsistent;
49   }
50
51   llvm_unreachable("Invalid LLVMAtomicOrdering value!");
52 }
53
54
55 static char *LastError;
56
57 extern "C" LLVMMemoryBufferRef
58 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
59   ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
60                                                                         -1,
61                                                                         false);
62   if (!buf_or) {
63       LLVMRustSetLastError(buf_or.getError().message().c_str());
64       return nullptr;
65   }
66   return wrap(buf_or.get().release());
67 }
68
69 extern "C" char *LLVMRustGetLastError(void) {
70   char *ret = LastError;
71   LastError = NULL;
72   return ret;
73 }
74
75 void LLVMRustSetLastError(const char *err) {
76   free((void*) LastError);
77   LastError = strdup(err);
78 }
79
80 extern "C" void
81 LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
82     unwrap(M)->setTargetTriple(Triple::normalize(triple));
83 }
84
85 extern "C" void LLVMRustPrintPassTimings() {
86   raw_fd_ostream OS (2, false); // stderr.
87   TimerGroup::printAll(OS);
88 }
89
90 extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
91                                               const char* Name) {
92     return wrap(unwrap(M)->getNamedValue(Name));
93 }
94
95 extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
96                                                     const char* Name,
97                                                     LLVMTypeRef FunctionTy) {
98   return wrap(unwrap(M)->getOrInsertFunction(Name,
99                                              unwrap<FunctionType>(FunctionTy)));
100 }
101
102 extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
103                                                   const char* Name,
104                                                   LLVMTypeRef Ty) {
105   return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
106 }
107
108 extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
109   return wrap(Type::getMetadataTy(*unwrap(C)));
110 }
111
112 extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, uint64_t Val) {
113   CallSite Call = CallSite(unwrap<Instruction>(Instr));
114   AttrBuilder B;
115   B.addRawValue(Val);
116   Call.setAttributes(
117     Call.getAttributes().addAttributes(Call->getContext(), index,
118                                        AttributeSet::get(Call->getContext(),
119                                                          index, B)));
120 }
121
122
123 extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
124                                                        unsigned idx,
125                                                        uint64_t b)
126 {
127   CallSite Call = CallSite(unwrap<Instruction>(Instr));
128   AttrBuilder B;
129   B.addDereferenceableAttr(b);
130   Call.setAttributes(
131     Call.getAttributes().addAttributes(Call->getContext(), idx,
132                                        AttributeSet::get(Call->getContext(),
133                                                          idx, B)));
134 }
135
136 extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
137                                              unsigned index,
138                                              uint64_t Val)
139 {
140   Function *A = unwrap<Function>(Fn);
141   AttrBuilder B;
142   B.addRawValue(Val);
143   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
144 }
145
146 extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
147                                                unsigned index,
148                                                uint64_t bytes)
149 {
150   Function *A = unwrap<Function>(Fn);
151   AttrBuilder B;
152   B.addDereferenceableAttr(bytes);
153   A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
154 }
155
156 extern "C" void LLVMRustAddFunctionAttrString(LLVMValueRef Fn,
157                                               unsigned index,
158                                               const char *Name)
159 {
160   Function *F = unwrap<Function>(Fn);
161   AttrBuilder B;
162   B.addAttribute(Name);
163   F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
164 }
165
166 extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
167                                                    unsigned index,
168                                                    const char *Name,
169                                                    const char *Value) {
170   Function *F = unwrap<Function>(Fn);
171   AttrBuilder B;
172   B.addAttribute(Name, Value);
173   F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
174 }
175
176 extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
177                                                  unsigned index,
178                                                  uint64_t Val)
179 {
180   Function *A = unwrap<Function>(Fn);
181   const AttributeSet PAL = A->getAttributes();
182   AttrBuilder B(Val);
183   const AttributeSet PALnew =
184     PAL.removeAttributes(A->getContext(), index,
185                          AttributeSet::get(A->getContext(), index, B));
186   A->setAttributes(PALnew);
187 }
188
189 extern "C" void LLVMRustRemoveFunctionAttrString(LLVMValueRef fn,
190                                                  unsigned index,
191                                                  const char *Name)
192 {
193   Function *f = unwrap<Function>(fn);
194   LLVMContext &C = f->getContext();
195   AttrBuilder B;
196   B.addAttribute(Name);
197   AttributeSet to_remove = AttributeSet::get(C, index, B);
198
199   AttributeSet attrs = f->getAttributes();
200   f->setAttributes(attrs.removeAttributes(f->getContext(),
201                                           index,
202                                           to_remove));
203 }
204
205 // enable fpmath flag UnsafeAlgebra
206 extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
207     if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
208         I->setHasUnsafeAlgebra(true);
209     }
210 }
211
212 extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B,
213                                                 LLVMValueRef source,
214                                                 const char* Name,
215                                                 LLVMAtomicOrdering order,
216                                                 unsigned alignment) {
217     LoadInst* li = new LoadInst(unwrap(source),0);
218     li->setAtomic(from_rust(order));
219     li->setAlignment(alignment);
220     return wrap(unwrap(B)->Insert(li, Name));
221 }
222
223 extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
224                                                  LLVMValueRef val,
225                                                  LLVMValueRef target,
226                                                  LLVMAtomicOrdering order,
227                                                  unsigned alignment) {
228     StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
229     si->setAtomic(from_rust(order));
230     si->setAlignment(alignment);
231     return wrap(unwrap(B)->Insert(si));
232 }
233
234 extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B,
235                                                LLVMValueRef target,
236                                                LLVMValueRef old,
237                                                LLVMValueRef source,
238                                                LLVMAtomicOrdering order,
239                                                LLVMAtomicOrdering failure_order,
240                                                LLVMBool weak) {
241     AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(
242         unwrap(target),
243         unwrap(old),
244         unwrap(source),
245         from_rust(order),
246         from_rust(failure_order));
247     acxi->setWeak(weak);
248     return wrap(acxi);
249 }
250
251 enum class LLVMRustSynchronizationScope {
252     Other,
253     SingleThread,
254     CrossThread,
255 };
256
257 static SynchronizationScope
258 from_rust(LLVMRustSynchronizationScope scope)
259 {
260     switch (scope) {
261     case LLVMRustSynchronizationScope::SingleThread:
262         return SingleThread;
263     case LLVMRustSynchronizationScope::CrossThread:
264         return CrossThread;
265     default:
266         llvm_unreachable("bad SynchronizationScope.");
267     }
268 }
269
270 extern "C" LLVMValueRef LLVMRustBuildAtomicFence(
271     LLVMBuilderRef B,
272     LLVMAtomicOrdering order,
273     LLVMRustSynchronizationScope scope)
274 {
275     return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope)));
276 }
277
278 extern "C" void LLVMRustSetDebug(int Enabled) {
279 #ifndef NDEBUG
280   DebugFlag = Enabled;
281 #endif
282 }
283
284 enum class LLVMRustAsmDialect {
285     Other,
286     Att,
287     Intel,
288 };
289
290 static InlineAsm::AsmDialect
291 from_rust(LLVMRustAsmDialect dialect)
292 {
293     switch (dialect) {
294     case LLVMRustAsmDialect::Att:
295         return InlineAsm::AD_ATT;
296     case LLVMRustAsmDialect::Intel:
297         return InlineAsm::AD_Intel;
298     default:
299         llvm_unreachable("bad AsmDialect.");
300     }
301 }
302
303 extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty,
304                                           char *AsmString,
305                                           char *Constraints,
306                                           LLVMBool HasSideEffects,
307                                           LLVMBool IsAlignStack,
308                                           LLVMRustAsmDialect Dialect) {
309     return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
310                                Constraints, HasSideEffects,
311                                IsAlignStack, from_rust(Dialect)));
312 }
313
314 typedef DIBuilder* LLVMRustDIBuilderRef;
315
316 typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
317
318 namespace llvm {
319 DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
320
321 inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
322   return reinterpret_cast<Metadata**>(Vals);
323 }
324 }
325
326 template<typename DIT>
327 DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
328     return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
329 }
330
331 #define DIDescriptor DIScope
332 #define DIArray DINodeArray
333 #define unwrapDI unwrapDIptr
334
335 extern "C" uint32_t LLVMRustDebugMetadataVersion() {
336     return DEBUG_METADATA_VERSION;
337 }
338
339 extern "C" uint32_t LLVMRustVersionMinor() {
340   return LLVM_VERSION_MINOR;
341 }
342
343 extern "C" uint32_t LLVMRustVersionMajor() {
344   return LLVM_VERSION_MAJOR;
345 }
346
347 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
348                                       const char *name,
349                                       uint32_t value) {
350     unwrap(M)->addModuleFlag(Module::Warning, name, value);
351 }
352
353 extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
354     return new DIBuilder(*unwrap(M));
355 }
356
357 extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
358     delete Builder;
359 }
360
361 extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
362     Builder->finalize();
363 }
364
365 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
366     LLVMRustDIBuilderRef Builder,
367     unsigned Lang,
368     const char* File,
369     const char* Dir,
370     const char* Producer,
371     bool isOptimized,
372     const char* Flags,
373     unsigned RuntimeVer,
374     const char* SplitName) {
375     return wrap(Builder->createCompileUnit(Lang,
376                                            File,
377                                            Dir,
378                                            Producer,
379                                            isOptimized,
380                                            Flags,
381                                            RuntimeVer,
382                                            SplitName));
383 }
384
385 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile(
386     LLVMRustDIBuilderRef Builder,
387     const char* Filename,
388     const char* Directory) {
389     return wrap(Builder->createFile(Filename, Directory));
390 }
391
392 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType(
393     LLVMRustDIBuilderRef Builder,
394     LLVMRustMetadataRef File,
395     LLVMRustMetadataRef ParameterTypes) {
396     return wrap(Builder->createSubroutineType(
397 #if LLVM_VERSION_EQ(3, 7)
398         unwrapDI<DIFile>(File),
399 #endif
400         DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
401 }
402
403 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
404     LLVMRustDIBuilderRef Builder,
405     LLVMRustMetadataRef Scope,
406     const char* Name,
407     const char* LinkageName,
408     LLVMRustMetadataRef File,
409     unsigned LineNo,
410     LLVMRustMetadataRef Ty,
411     bool isLocalToUnit,
412     bool isDefinition,
413     unsigned ScopeLine,
414     unsigned Flags,
415     bool isOptimized,
416     LLVMValueRef Fn,
417     LLVMRustMetadataRef TParam,
418     LLVMRustMetadataRef Decl) {
419 #if LLVM_VERSION_GE(3, 8)
420     DITemplateParameterArray TParams =
421         DITemplateParameterArray(unwrap<MDTuple>(TParam));
422     DISubprogram *Sub = Builder->createFunction(
423         unwrapDI<DIScope>(Scope), Name, LinkageName,
424         unwrapDI<DIFile>(File), LineNo,
425         unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
426         Flags, isOptimized,
427         TParams,
428         unwrapDIptr<DISubprogram>(Decl));
429     unwrap<Function>(Fn)->setSubprogram(Sub);
430     return wrap(Sub);
431 #else
432     return wrap(Builder->createFunction(
433         unwrapDI<DIScope>(Scope), Name, LinkageName,
434         unwrapDI<DIFile>(File), LineNo,
435         unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
436         Flags, isOptimized,
437         unwrap<Function>(Fn),
438         unwrapDIptr<MDNode>(TParam),
439         unwrapDIptr<MDNode>(Decl)));
440 #endif
441 }
442
443 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType(
444     LLVMRustDIBuilderRef Builder,
445     const char* Name,
446     uint64_t SizeInBits,
447     uint64_t AlignInBits,
448     unsigned Encoding) {
449     return wrap(Builder->createBasicType(
450         Name, SizeInBits,
451         AlignInBits, Encoding));
452 }
453
454 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
455     LLVMRustDIBuilderRef Builder,
456     LLVMRustMetadataRef PointeeTy,
457     uint64_t SizeInBits,
458     uint64_t AlignInBits,
459     const char* Name) {
460     return wrap(Builder->createPointerType(
461         unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
462 }
463
464 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
465     LLVMRustDIBuilderRef Builder,
466     LLVMRustMetadataRef Scope,
467     const char* Name,
468     LLVMRustMetadataRef File,
469     unsigned LineNumber,
470     uint64_t SizeInBits,
471     uint64_t AlignInBits,
472     unsigned Flags,
473     LLVMRustMetadataRef DerivedFrom,
474     LLVMRustMetadataRef Elements,
475     unsigned RunTimeLang,
476     LLVMRustMetadataRef VTableHolder,
477     const char *UniqueId) {
478     return wrap(Builder->createStructType(
479         unwrapDI<DIDescriptor>(Scope),
480         Name,
481         unwrapDI<DIFile>(File),
482         LineNumber,
483         SizeInBits,
484         AlignInBits,
485         Flags,
486         unwrapDI<DIType>(DerivedFrom),
487         DINodeArray(unwrapDI<MDTuple>(Elements)),
488         RunTimeLang,
489         unwrapDI<DIType>(VTableHolder),
490         UniqueId
491         ));
492 }
493
494 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
495     LLVMRustDIBuilderRef Builder,
496     LLVMRustMetadataRef Scope,
497     const char* Name,
498     LLVMRustMetadataRef File,
499     unsigned LineNo,
500     uint64_t SizeInBits,
501     uint64_t AlignInBits,
502     uint64_t OffsetInBits,
503     unsigned Flags,
504     LLVMRustMetadataRef Ty) {
505     return wrap(Builder->createMemberType(
506         unwrapDI<DIDescriptor>(Scope), Name,
507         unwrapDI<DIFile>(File), LineNo,
508         SizeInBits, AlignInBits, OffsetInBits, Flags,
509         unwrapDI<DIType>(Ty)));
510 }
511
512 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
513     LLVMRustDIBuilderRef Builder,
514     LLVMRustMetadataRef Scope,
515     LLVMRustMetadataRef File,
516     unsigned Line,
517     unsigned Col) {
518     return wrap(Builder->createLexicalBlock(
519         unwrapDI<DIDescriptor>(Scope),
520         unwrapDI<DIFile>(File), Line, Col
521         ));
522 }
523
524 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile(
525     LLVMRustDIBuilderRef Builder,
526     LLVMRustMetadataRef Scope,
527     LLVMRustMetadataRef File) {
528     return wrap(Builder->createLexicalBlockFile(
529         unwrapDI<DIDescriptor>(Scope),
530         unwrapDI<DIFile>(File)));
531 }
532
533 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
534     LLVMRustDIBuilderRef Builder,
535     LLVMRustMetadataRef Context,
536     const char* Name,
537     const char* LinkageName,
538     LLVMRustMetadataRef File,
539     unsigned LineNo,
540     LLVMRustMetadataRef Ty,
541     bool isLocalToUnit,
542     LLVMValueRef Val,
543     LLVMRustMetadataRef Decl = NULL) {
544     return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
545         Name,
546         LinkageName,
547         unwrapDI<DIFile>(File),
548         LineNo,
549         unwrapDI<DIType>(Ty),
550         isLocalToUnit,
551         cast<Constant>(unwrap(Val)),
552         unwrapDIptr<MDNode>(Decl)));
553 }
554
555 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
556     LLVMRustDIBuilderRef Builder,
557     unsigned Tag,
558     LLVMRustMetadataRef Scope,
559     const char* Name,
560     LLVMRustMetadataRef File,
561     unsigned LineNo,
562     LLVMRustMetadataRef Ty,
563     bool AlwaysPreserve,
564     unsigned Flags,
565     unsigned ArgNo) {
566 #if LLVM_VERSION_GE(3, 8)
567     if (Tag == 0x100) { // DW_TAG_auto_variable
568         return wrap(Builder->createAutoVariable(
569             unwrapDI<DIDescriptor>(Scope), Name,
570             unwrapDI<DIFile>(File),
571             LineNo,
572             unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
573     } else {
574         return wrap(Builder->createParameterVariable(
575             unwrapDI<DIDescriptor>(Scope), Name, ArgNo,
576             unwrapDI<DIFile>(File),
577             LineNo,
578             unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
579     }
580 #else
581     return wrap(Builder->createLocalVariable(Tag,
582         unwrapDI<DIDescriptor>(Scope), Name,
583         unwrapDI<DIFile>(File),
584         LineNo,
585         unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
586 #endif
587 }
588
589 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
590     LLVMRustDIBuilderRef Builder,
591     uint64_t Size,
592     uint64_t AlignInBits,
593     LLVMRustMetadataRef Ty,
594     LLVMRustMetadataRef Subscripts) {
595     return wrap(Builder->createArrayType(Size, AlignInBits,
596         unwrapDI<DIType>(Ty),
597         DINodeArray(unwrapDI<MDTuple>(Subscripts))
598     ));
599 }
600
601 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
602     LLVMRustDIBuilderRef Builder,
603     uint64_t Size,
604     uint64_t AlignInBits,
605     LLVMRustMetadataRef Ty,
606     LLVMRustMetadataRef Subscripts) {
607     return wrap(Builder->createVectorType(Size, AlignInBits,
608         unwrapDI<DIType>(Ty),
609         DINodeArray(unwrapDI<MDTuple>(Subscripts))
610     ));
611 }
612
613 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
614     LLVMRustDIBuilderRef Builder,
615     int64_t Lo,
616     int64_t Count) {
617     return wrap(Builder->getOrCreateSubrange(Lo, Count));
618 }
619
620 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
621     LLVMRustDIBuilderRef Builder,
622     LLVMRustMetadataRef* Ptr,
623     unsigned Count) {
624     Metadata **DataValue = unwrap(Ptr);
625     return wrap(Builder->getOrCreateArray(
626         ArrayRef<Metadata*>(DataValue, Count)).get());
627 }
628
629 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
630     LLVMRustDIBuilderRef Builder,
631     LLVMValueRef Val,
632     LLVMRustMetadataRef VarInfo,
633     int64_t* AddrOps,
634     unsigned AddrOpsCount,
635     LLVMValueRef DL,
636     LLVMBasicBlockRef InsertAtEnd) {
637     return wrap(Builder->insertDeclare(
638         unwrap(Val),
639         unwrap<DILocalVariable>(VarInfo),
640         Builder->createExpression(
641           llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
642         DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
643         unwrap(InsertAtEnd)));
644 }
645
646 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
647     LLVMRustDIBuilderRef Builder,
648     const char* Name,
649     uint64_t Val)
650 {
651     return wrap(Builder->createEnumerator(Name, Val));
652 }
653
654 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
655     LLVMRustDIBuilderRef Builder,
656     LLVMRustMetadataRef Scope,
657     const char* Name,
658     LLVMRustMetadataRef File,
659     unsigned LineNumber,
660     uint64_t SizeInBits,
661     uint64_t AlignInBits,
662     LLVMRustMetadataRef Elements,
663     LLVMRustMetadataRef ClassType)
664 {
665     return wrap(Builder->createEnumerationType(
666         unwrapDI<DIDescriptor>(Scope),
667         Name,
668         unwrapDI<DIFile>(File),
669         LineNumber,
670         SizeInBits,
671         AlignInBits,
672         DINodeArray(unwrapDI<MDTuple>(Elements)),
673         unwrapDI<DIType>(ClassType)));
674 }
675
676 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
677     LLVMRustDIBuilderRef Builder,
678     LLVMRustMetadataRef Scope,
679     const char* Name,
680     LLVMRustMetadataRef File,
681     unsigned LineNumber,
682     uint64_t SizeInBits,
683     uint64_t AlignInBits,
684     unsigned Flags,
685     LLVMRustMetadataRef Elements,
686     unsigned RunTimeLang,
687     const char* UniqueId)
688 {
689     return wrap(Builder->createUnionType(
690         unwrapDI<DIDescriptor>(Scope),
691         Name,
692         unwrapDI<DIFile>(File),
693         LineNumber,
694         SizeInBits,
695         AlignInBits,
696         Flags,
697         DINodeArray(unwrapDI<MDTuple>(Elements)),
698         RunTimeLang,
699         UniqueId
700         ));
701 }
702
703 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
704     LLVMRustDIBuilderRef Builder,
705     LLVMRustMetadataRef Scope,
706     const char* Name,
707     LLVMRustMetadataRef Ty,
708     LLVMRustMetadataRef File,
709     unsigned LineNo,
710     unsigned ColumnNo)
711 {
712     return wrap(Builder->createTemplateTypeParameter(
713       unwrapDI<DIDescriptor>(Scope),
714       Name,
715       unwrapDI<DIType>(Ty)
716       ));
717 }
718
719 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
720     LLVMRustDIBuilderRef Builder,
721     LLVMRustMetadataRef Scope,
722     const char* Name,
723     LLVMRustMetadataRef File,
724     unsigned LineNo)
725 {
726     return wrap(Builder->createNameSpace(
727         unwrapDI<DIDescriptor>(Scope),
728         Name,
729         unwrapDI<DIFile>(File),
730         LineNo));
731 }
732
733 extern "C" void LLVMRustDICompositeTypeSetTypeArray(
734     LLVMRustDIBuilderRef Builder,
735     LLVMRustMetadataRef CompositeType,
736     LLVMRustMetadataRef TypeArray)
737 {
738     DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
739     Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
740 }
741
742 extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
743   LLVMContextRef Context,
744   unsigned Line,
745   unsigned Column,
746   LLVMRustMetadataRef Scope,
747   LLVMRustMetadataRef InlinedAt)
748 {
749     LLVMContext& context = *unwrap(Context);
750
751     DebugLoc debug_loc = DebugLoc::get(Line,
752                                        Column,
753                                        unwrapDIptr<MDNode>(Scope),
754                                        unwrapDIptr<MDNode>(InlinedAt));
755
756     return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
757 }
758
759 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
760 {
761     return dwarf::DW_OP_deref;
762 }
763
764 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
765 {
766     return dwarf::DW_OP_plus;
767 }
768
769 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
770     raw_rust_string_ostream os(str);
771     unwrap<llvm::Type>(Type)->print(os);
772 }
773
774 extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
775     raw_rust_string_ostream os(str);
776     os << "(";
777     unwrap<llvm::Value>(Value)->getType()->print(os);
778     os << ":";
779     unwrap<llvm::Value>(Value)->print(os);
780     os << ")";
781 }
782
783 extern "C" bool
784 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
785     Module *Dst = unwrap(dst);
786     std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
787     ErrorOr<std::unique_ptr<Module>> Src =
788         llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
789     if (!Src) {
790         LLVMRustSetLastError(Src.getError().message().c_str());
791         return false;
792     }
793
794     std::string Err;
795
796     raw_string_ostream Stream(Err);
797     DiagnosticPrinterRawOStream DP(Stream);
798 #if LLVM_VERSION_GE(3, 8)
799     if (Linker::linkModules(*Dst, std::move(Src.get()))) {
800 #else
801     if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
802 #endif
803         LLVMRustSetLastError(Err.c_str());
804         return false;
805     }
806     return true;
807 }
808
809 // Note that the two following functions look quite similar to the
810 // LLVMGetSectionName function. Sadly, it appears that this function only
811 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
812 // function provided by LLVM doesn't return the length, so we've created our own
813 // function which returns the length as well as the data pointer.
814 //
815 // For an example of this not returning a null terminated string, see
816 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
817 // branches explicitly creates a StringRef without a null terminator, and then
818 // that's returned.
819
820 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
821     return reinterpret_cast<section_iterator*>(SI);
822 }
823
824 extern "C" size_t
825 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
826     StringRef ret;
827     if (std::error_code ec = (*unwrap(SI))->getName(ret))
828       report_fatal_error(ec.message());
829     *ptr = ret.data();
830     return ret.size();
831 }
832
833 // LLVMArrayType function does not support 64-bit ElementCount
834 extern "C" LLVMTypeRef
835 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
836     return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
837 }
838
839 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
840 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
841
842 extern "C" void
843 LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
844     raw_rust_string_ostream os(str);
845     unwrap(T)->print(os);
846 }
847
848 extern "C" void
849 LLVMRustUnpackOptimizationDiagnostic(
850     LLVMDiagnosticInfoRef di,
851     const char **pass_name_out,
852     LLVMValueRef *function_out,
853     LLVMDebugLocRef *debugloc_out,
854     LLVMTwineRef *message_out)
855 {
856     // Undefined to call this not on an optimization diagnostic!
857     llvm::DiagnosticInfoOptimizationBase *opt
858         = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
859
860     *pass_name_out = opt->getPassName();
861     *function_out = wrap(&opt->getFunction());
862     *debugloc_out = wrap(&opt->getDebugLoc());
863     *message_out = wrap(&opt->getMsg());
864 }
865
866 extern "C" void
867 LLVMRustUnpackInlineAsmDiagnostic(
868     LLVMDiagnosticInfoRef di,
869     unsigned *cookie_out,
870     LLVMTwineRef *message_out,
871     LLVMValueRef *instruction_out)
872 {
873     // Undefined to call this not on an inline assembly diagnostic!
874     llvm::DiagnosticInfoInlineAsm *ia
875         = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
876
877     *cookie_out = ia->getLocCookie();
878     *message_out = wrap(&ia->getMsgStr());
879     *instruction_out = wrap(ia->getInstruction());
880 }
881
882 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
883     raw_rust_string_ostream os(str);
884     DiagnosticPrinterRawOStream dp(os);
885     unwrap(di)->print(dp);
886 }
887
888 enum class LLVMRustDiagnosticKind {
889     Other,
890     InlineAsm,
891     StackSize,
892     DebugMetadataVersion,
893     SampleProfile,
894     OptimizationRemark,
895     OptimizationRemarkMissed,
896     OptimizationRemarkAnalysis,
897     OptimizationRemarkAnalysisFPCommute,
898     OptimizationRemarkAnalysisAliasing,
899     OptimizationRemarkOther,
900     OptimizationFailure,
901 };
902
903 static LLVMRustDiagnosticKind
904 to_rust(DiagnosticKind kind)
905 {
906     switch (kind) {
907     case DK_InlineAsm:
908         return LLVMRustDiagnosticKind::InlineAsm;
909     case DK_StackSize:
910         return LLVMRustDiagnosticKind::StackSize;
911     case DK_DebugMetadataVersion:
912         return LLVMRustDiagnosticKind::DebugMetadataVersion;
913     case DK_SampleProfile:
914         return LLVMRustDiagnosticKind::SampleProfile;
915     case DK_OptimizationRemark:
916         return LLVMRustDiagnosticKind::OptimizationRemark;
917     case DK_OptimizationRemarkMissed:
918         return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
919     case DK_OptimizationRemarkAnalysis:
920         return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
921 #if LLVM_VERSION_GE(3, 8)
922     case DK_OptimizationRemarkAnalysisFPCommute:
923         return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
924     case DK_OptimizationRemarkAnalysisAliasing:
925         return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
926 #endif
927     default:
928 #if LLVM_VERSION_GE(3, 9)
929         return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
930             LLVMRustDiagnosticKind::OptimizationRemarkOther :
931             LLVMRustDiagnosticKind::Other;
932 #else
933         return LLVMRustDiagnosticKind::Other;
934 #endif
935   }
936 }
937
938 extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
939     return to_rust((DiagnosticKind) unwrap(di)->getKind());
940 }
941 // This is kept distinct from LLVMGetTypeKind, because when
942 // a new type kind is added, the Rust-side enum must be
943 // updated or UB will result.
944 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
945   switch (unwrap(Ty)->getTypeID()) {
946   case Type::VoidTyID:
947     return LLVMVoidTypeKind;
948   case Type::HalfTyID:
949     return LLVMHalfTypeKind;
950   case Type::FloatTyID:
951     return LLVMFloatTypeKind;
952   case Type::DoubleTyID:
953     return LLVMDoubleTypeKind;
954   case Type::X86_FP80TyID:
955     return LLVMX86_FP80TypeKind;
956   case Type::FP128TyID:
957     return LLVMFP128TypeKind;
958   case Type::PPC_FP128TyID:
959     return LLVMPPC_FP128TypeKind;
960   case Type::LabelTyID:
961     return LLVMLabelTypeKind;
962   case Type::MetadataTyID:
963     return LLVMMetadataTypeKind;
964   case Type::IntegerTyID:
965     return LLVMIntegerTypeKind;
966   case Type::FunctionTyID:
967     return LLVMFunctionTypeKind;
968   case Type::StructTyID:
969     return LLVMStructTypeKind;
970   case Type::ArrayTyID:
971     return LLVMArrayTypeKind;
972   case Type::PointerTyID:
973     return LLVMPointerTypeKind;
974   case Type::VectorTyID:
975     return LLVMVectorTypeKind;
976   case Type::X86_MMXTyID:
977     return LLVMX86_MMXTypeKind;
978 #if LLVM_VERSION_GE(3, 8)
979   case Type::TokenTyID:
980     return LLVMTokenTypeKind;
981 #endif
982   }
983   llvm_unreachable("Unhandled TypeID.");
984 }
985
986 extern "C" void LLVMRustWriteDebugLocToString(
987     LLVMContextRef C,
988     LLVMDebugLocRef dl,
989     RustStringRef str)
990 {
991     raw_rust_string_ostream os(str);
992     unwrap(dl)->print(os);
993 }
994
995 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
996
997 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
998     LLVMContextRef C,
999     LLVMContext::InlineAsmDiagHandlerTy H,
1000     void *CX)
1001 {
1002     unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1003 }
1004
1005 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
1006                                                   RustStringRef str) {
1007     raw_rust_string_ostream os(str);
1008     unwrap(d)->print("", os);
1009 }
1010
1011 extern "C" LLVMValueRef
1012 LLVMRustBuildLandingPad(LLVMBuilderRef Builder,
1013                         LLVMTypeRef Ty,
1014                         LLVMValueRef PersFn,
1015                         unsigned NumClauses,
1016                         const char* Name,
1017                         LLVMValueRef F) {
1018     return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
1019 }
1020
1021 extern "C" LLVMValueRef
1022 LLVMRustBuildCleanupPad(LLVMBuilderRef Builder,
1023                         LLVMValueRef ParentPad,
1024                         unsigned ArgCnt,
1025                         LLVMValueRef *LLArgs,
1026                         const char *Name) {
1027 #if LLVM_VERSION_GE(3, 8)
1028     Value **Args = unwrap(LLArgs);
1029     if (ParentPad == NULL) {
1030         Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1031         ParentPad = wrap(Constant::getNullValue(Ty));
1032     }
1033     return wrap(unwrap(Builder)->CreateCleanupPad(unwrap(ParentPad),
1034                                                   ArrayRef<Value*>(Args, ArgCnt),
1035                                                   Name));
1036 #else
1037     return NULL;
1038 #endif
1039 }
1040
1041 extern "C" LLVMValueRef
1042 LLVMRustBuildCleanupRet(LLVMBuilderRef Builder,
1043                         LLVMValueRef CleanupPad,
1044                         LLVMBasicBlockRef UnwindBB) {
1045 #if LLVM_VERSION_GE(3, 8)
1046     CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1047     return wrap(unwrap(Builder)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1048 #else
1049     return NULL;
1050 #endif
1051 }
1052
1053 extern "C" LLVMValueRef
1054 LLVMRustBuildCatchPad(LLVMBuilderRef Builder,
1055                       LLVMValueRef ParentPad,
1056                       unsigned ArgCnt,
1057                       LLVMValueRef *LLArgs,
1058                       const char *Name) {
1059 #if LLVM_VERSION_GE(3, 8)
1060     Value **Args = unwrap(LLArgs);
1061     return wrap(unwrap(Builder)->CreateCatchPad(unwrap(ParentPad),
1062                                                 ArrayRef<Value*>(Args, ArgCnt),
1063                                                 Name));
1064 #else
1065     return NULL;
1066 #endif
1067 }
1068
1069 extern "C" LLVMValueRef
1070 LLVMRustBuildCatchRet(LLVMBuilderRef Builder,
1071                       LLVMValueRef Pad,
1072                       LLVMBasicBlockRef BB) {
1073 #if LLVM_VERSION_GE(3, 8)
1074     return wrap(unwrap(Builder)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1075                                                 unwrap(BB)));
1076 #else
1077     return NULL;
1078 #endif
1079 }
1080
1081 extern "C" LLVMValueRef
1082 LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder,
1083                          LLVMValueRef ParentPad,
1084                          LLVMBasicBlockRef BB,
1085                          unsigned NumHandlers,
1086                          const char *Name) {
1087 #if LLVM_VERSION_GE(3, 8)
1088     if (ParentPad == NULL) {
1089         Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1090         ParentPad = wrap(Constant::getNullValue(Ty));
1091     }
1092     return wrap(unwrap(Builder)->CreateCatchSwitch(unwrap(ParentPad),
1093                                                    unwrap(BB),
1094                                                    NumHandlers,
1095                                                    Name));
1096 #else
1097     return NULL;
1098 #endif
1099 }
1100
1101 extern "C" void
1102 LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1103                    LLVMBasicBlockRef Handler) {
1104 #if LLVM_VERSION_GE(3, 8)
1105     Value *CatchSwitch = unwrap(CatchSwitchRef);
1106     cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1107 #endif
1108 }
1109
1110 extern "C" void
1111 LLVMRustSetPersonalityFn(LLVMBuilderRef B,
1112                          LLVMValueRef Personality) {
1113 #if LLVM_VERSION_GE(3, 8)
1114     unwrap(B)->GetInsertBlock()
1115              ->getParent()
1116              ->setPersonalityFn(cast<Function>(unwrap(Personality)));
1117 #endif
1118 }
1119
1120 #if LLVM_VERSION_GE(3, 8)
1121 extern "C" OperandBundleDef*
1122 LLVMRustBuildOperandBundleDef(const char *Name,
1123                               LLVMValueRef *Inputs,
1124                               unsigned NumInputs) {
1125   return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1126 }
1127
1128 extern "C" void
1129 LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) {
1130   delete Bundle;
1131 }
1132
1133 extern "C" LLVMValueRef
1134 LLVMRustBuildCall(LLVMBuilderRef B,
1135                     LLVMValueRef Fn,
1136                     LLVMValueRef *Args,
1137                     unsigned NumArgs,
1138                     OperandBundleDef *Bundle,
1139                     const char *Name) {
1140     unsigned len = Bundle ? 1 : 0;
1141     ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1142     return wrap(unwrap(B)->CreateCall(unwrap(Fn),
1143                                       makeArrayRef(unwrap(Args), NumArgs),
1144                                       Bundles,
1145                                       Name));
1146 }
1147
1148 extern "C" LLVMValueRef
1149 LLVMRustBuildInvoke(LLVMBuilderRef B,
1150                     LLVMValueRef Fn,
1151                     LLVMValueRef *Args,
1152                     unsigned NumArgs,
1153                     LLVMBasicBlockRef Then,
1154                     LLVMBasicBlockRef Catch,
1155                     OperandBundleDef *Bundle,
1156                     const char *Name) {
1157     unsigned len = Bundle ? 1 : 0;
1158     ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1159     return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1160                                         makeArrayRef(unwrap(Args), NumArgs),
1161                                         Bundles,
1162                                         Name));
1163 }
1164 #else
1165 extern "C" void*
1166 LLVMRustBuildOperandBundleDef(const char *Name,
1167                               LLVMValueRef *Inputs,
1168                               unsigned NumInputs) {
1169   return NULL;
1170 }
1171
1172 extern "C" void
1173 LLVMRustFreeOperandBundleDef(void* Bundle) {
1174 }
1175
1176 extern "C" LLVMValueRef
1177 LLVMRustBuildCall(LLVMBuilderRef B,
1178                     LLVMValueRef Fn,
1179                     LLVMValueRef *Args,
1180                     unsigned NumArgs,
1181                     void *Bundle,
1182                     const char *Name) {
1183     return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
1184 }
1185
1186 extern "C" LLVMValueRef
1187 LLVMRustBuildInvoke(LLVMBuilderRef B,
1188                     LLVMValueRef Fn,
1189                     LLVMValueRef *Args,
1190                     unsigned NumArgs,
1191                     LLVMBasicBlockRef Then,
1192                     LLVMBasicBlockRef Catch,
1193                     void *Bundle,
1194                     const char *Name) {
1195     return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
1196 }
1197 #endif
1198
1199 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) {
1200     auto point = unwrap(BB)->getFirstInsertionPt();
1201     unwrap(B)->SetInsertPoint(unwrap(BB), point);
1202 }
1203
1204 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V, const char *Name) {
1205     Triple TargetTriple(unwrap(M)->getTargetTriple());
1206     GlobalObject *GV = unwrap<GlobalObject>(V);
1207     if (!TargetTriple.isOSBinFormatMachO()) {
1208         GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1209     }
1210 }
1211
1212 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1213     GlobalObject *GV = unwrap<GlobalObject>(V);
1214     GV->setComdat(nullptr);
1215 }
1216
1217 enum class LLVMRustLinkage {
1218     ExternalLinkage = 0,
1219     AvailableExternallyLinkage = 1,
1220     LinkOnceAnyLinkage = 2,
1221     LinkOnceODRLinkage = 3,
1222     WeakAnyLinkage = 4,
1223     WeakODRLinkage = 5,
1224     AppendingLinkage = 6,
1225     InternalLinkage = 7,
1226     PrivateLinkage = 8,
1227     ExternalWeakLinkage = 9,
1228     CommonLinkage = 10,
1229 };
1230
1231 static LLVMRustLinkage to_rust(LLVMLinkage linkage) {
1232     switch (linkage) {
1233         case LLVMExternalLinkage:
1234             return LLVMRustLinkage::ExternalLinkage;
1235         case LLVMAvailableExternallyLinkage:
1236             return LLVMRustLinkage::AvailableExternallyLinkage;
1237         case LLVMLinkOnceAnyLinkage:
1238             return LLVMRustLinkage::LinkOnceAnyLinkage;
1239         case LLVMLinkOnceODRLinkage:
1240             return LLVMRustLinkage::LinkOnceODRLinkage;
1241         case LLVMWeakAnyLinkage:
1242             return LLVMRustLinkage::WeakAnyLinkage;
1243         case LLVMWeakODRLinkage:
1244             return LLVMRustLinkage::WeakODRLinkage;
1245         case LLVMAppendingLinkage:
1246             return LLVMRustLinkage::AppendingLinkage;
1247         case LLVMInternalLinkage:
1248             return LLVMRustLinkage::InternalLinkage;
1249         case LLVMPrivateLinkage:
1250             return LLVMRustLinkage::PrivateLinkage;
1251         case LLVMExternalWeakLinkage:
1252             return LLVMRustLinkage::ExternalWeakLinkage;
1253         case LLVMCommonLinkage:
1254             return LLVMRustLinkage::CommonLinkage;
1255         default:
1256             llvm_unreachable("Invalid LLVMRustLinkage value!");
1257     }
1258 }
1259
1260 static LLVMLinkage from_rust(LLVMRustLinkage linkage) {
1261     switch (linkage) {
1262         case LLVMRustLinkage::ExternalLinkage:
1263             return LLVMExternalLinkage;
1264         case LLVMRustLinkage::AvailableExternallyLinkage:
1265             return LLVMAvailableExternallyLinkage;
1266         case LLVMRustLinkage::LinkOnceAnyLinkage:
1267             return LLVMLinkOnceAnyLinkage;
1268         case LLVMRustLinkage::LinkOnceODRLinkage:
1269             return LLVMLinkOnceODRLinkage;
1270         case LLVMRustLinkage::WeakAnyLinkage:
1271             return LLVMWeakAnyLinkage;
1272         case LLVMRustLinkage::WeakODRLinkage:
1273             return LLVMWeakODRLinkage;
1274         case LLVMRustLinkage::AppendingLinkage:
1275             return LLVMAppendingLinkage;
1276         case LLVMRustLinkage::InternalLinkage:
1277             return LLVMInternalLinkage;
1278         case LLVMRustLinkage::PrivateLinkage:
1279             return LLVMPrivateLinkage;
1280         case LLVMRustLinkage::ExternalWeakLinkage:
1281             return LLVMExternalWeakLinkage;
1282         case LLVMRustLinkage::CommonLinkage:
1283             return LLVMCommonLinkage;
1284         default:
1285             llvm_unreachable("Invalid LLVMRustLinkage value!");
1286     }
1287 }
1288
1289 extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
1290     return to_rust(LLVMGetLinkage(V));
1291 }
1292
1293 extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) {
1294     LLVMSetLinkage(V, from_rust(RustLinkage));
1295 }