]> git.lizzy.rs Git - rust.git/blob - src/rustllvm/RustWrapper.cpp
Auto merge of #35856 - phimuemue:master, r=brson
[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_MINOR == 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_MINOR >= 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     int64_t* AddrOps,
566     unsigned AddrOpsCount,
567     unsigned ArgNo) {
568 #if LLVM_VERSION_MINOR >= 8
569     if (Tag == 0x100) { // DW_TAG_auto_variable
570         return wrap(Builder->createAutoVariable(
571             unwrapDI<DIDescriptor>(Scope), Name,
572             unwrapDI<DIFile>(File),
573             LineNo,
574             unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
575     } else {
576         return wrap(Builder->createParameterVariable(
577             unwrapDI<DIDescriptor>(Scope), Name, ArgNo,
578             unwrapDI<DIFile>(File),
579             LineNo,
580             unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
581     }
582 #else
583     return wrap(Builder->createLocalVariable(Tag,
584         unwrapDI<DIDescriptor>(Scope), Name,
585         unwrapDI<DIFile>(File),
586         LineNo,
587         unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
588 #endif
589 }
590
591 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
592     LLVMRustDIBuilderRef Builder,
593     uint64_t Size,
594     uint64_t AlignInBits,
595     LLVMRustMetadataRef Ty,
596     LLVMRustMetadataRef Subscripts) {
597     return wrap(Builder->createArrayType(Size, AlignInBits,
598         unwrapDI<DIType>(Ty),
599         DINodeArray(unwrapDI<MDTuple>(Subscripts))
600     ));
601 }
602
603 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
604     LLVMRustDIBuilderRef Builder,
605     uint64_t Size,
606     uint64_t AlignInBits,
607     LLVMRustMetadataRef Ty,
608     LLVMRustMetadataRef Subscripts) {
609     return wrap(Builder->createVectorType(Size, AlignInBits,
610         unwrapDI<DIType>(Ty),
611         DINodeArray(unwrapDI<MDTuple>(Subscripts))
612     ));
613 }
614
615 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
616     LLVMRustDIBuilderRef Builder,
617     int64_t Lo,
618     int64_t Count) {
619     return wrap(Builder->getOrCreateSubrange(Lo, Count));
620 }
621
622 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
623     LLVMRustDIBuilderRef Builder,
624     LLVMRustMetadataRef* Ptr,
625     unsigned Count) {
626     Metadata **DataValue = unwrap(Ptr);
627     return wrap(Builder->getOrCreateArray(
628         ArrayRef<Metadata*>(DataValue, Count)).get());
629 }
630
631 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
632     LLVMRustDIBuilderRef Builder,
633     LLVMValueRef Val,
634     LLVMRustMetadataRef VarInfo,
635     int64_t* AddrOps,
636     unsigned AddrOpsCount,
637     LLVMValueRef DL,
638     LLVMBasicBlockRef InsertAtEnd) {
639     return wrap(Builder->insertDeclare(
640         unwrap(Val),
641         unwrap<DILocalVariable>(VarInfo),
642         Builder->createExpression(
643           llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
644         DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
645         unwrap(InsertAtEnd)));
646 }
647
648 extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareBefore(
649     LLVMRustDIBuilderRef Builder,
650     LLVMValueRef Val,
651     LLVMRustMetadataRef VarInfo,
652     int64_t* AddrOps,
653     unsigned AddrOpsCount,
654     LLVMValueRef DL,
655     LLVMValueRef InsertBefore) {
656     return wrap(Builder->insertDeclare(
657         unwrap(Val),
658         unwrap<DILocalVariable>(VarInfo),
659         Builder->createExpression(
660           llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
661         DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
662         unwrap<Instruction>(InsertBefore)));
663 }
664
665 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
666     LLVMRustDIBuilderRef Builder,
667     const char* Name,
668     uint64_t Val)
669 {
670     return wrap(Builder->createEnumerator(Name, Val));
671 }
672
673 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
674     LLVMRustDIBuilderRef Builder,
675     LLVMRustMetadataRef Scope,
676     const char* Name,
677     LLVMRustMetadataRef File,
678     unsigned LineNumber,
679     uint64_t SizeInBits,
680     uint64_t AlignInBits,
681     LLVMRustMetadataRef Elements,
682     LLVMRustMetadataRef ClassType)
683 {
684     return wrap(Builder->createEnumerationType(
685         unwrapDI<DIDescriptor>(Scope),
686         Name,
687         unwrapDI<DIFile>(File),
688         LineNumber,
689         SizeInBits,
690         AlignInBits,
691         DINodeArray(unwrapDI<MDTuple>(Elements)),
692         unwrapDI<DIType>(ClassType)));
693 }
694
695 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
696     LLVMRustDIBuilderRef Builder,
697     LLVMRustMetadataRef Scope,
698     const char* Name,
699     LLVMRustMetadataRef File,
700     unsigned LineNumber,
701     uint64_t SizeInBits,
702     uint64_t AlignInBits,
703     unsigned Flags,
704     LLVMRustMetadataRef Elements,
705     unsigned RunTimeLang,
706     const char* UniqueId)
707 {
708     return wrap(Builder->createUnionType(
709         unwrapDI<DIDescriptor>(Scope),
710         Name,
711         unwrapDI<DIFile>(File),
712         LineNumber,
713         SizeInBits,
714         AlignInBits,
715         Flags,
716         DINodeArray(unwrapDI<MDTuple>(Elements)),
717         RunTimeLang,
718         UniqueId
719         ));
720 }
721
722 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
723     LLVMRustDIBuilderRef Builder,
724     LLVMRustMetadataRef Scope,
725     const char* Name,
726     LLVMRustMetadataRef Ty,
727     LLVMRustMetadataRef File,
728     unsigned LineNo,
729     unsigned ColumnNo)
730 {
731     return wrap(Builder->createTemplateTypeParameter(
732       unwrapDI<DIDescriptor>(Scope),
733       Name,
734       unwrapDI<DIType>(Ty)
735       ));
736 }
737
738 extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
739     LLVMRustDIBuilderRef Builder,
740     LLVMRustMetadataRef Scope,
741     const char* Name,
742     LLVMRustMetadataRef File,
743     unsigned LineNo)
744 {
745     return wrap(Builder->createNameSpace(
746         unwrapDI<DIDescriptor>(Scope),
747         Name,
748         unwrapDI<DIFile>(File),
749         LineNo));
750 }
751
752 extern "C" void LLVMRustDICompositeTypeSetTypeArray(
753     LLVMRustDIBuilderRef Builder,
754     LLVMRustMetadataRef CompositeType,
755     LLVMRustMetadataRef TypeArray)
756 {
757     DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
758     Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
759 }
760
761 extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
762   LLVMContextRef Context,
763   unsigned Line,
764   unsigned Column,
765   LLVMRustMetadataRef Scope,
766   LLVMRustMetadataRef InlinedAt)
767 {
768     LLVMContext& context = *unwrap(Context);
769
770     DebugLoc debug_loc = DebugLoc::get(Line,
771                                        Column,
772                                        unwrapDIptr<MDNode>(Scope),
773                                        unwrapDIptr<MDNode>(InlinedAt));
774
775     return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
776 }
777
778 extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
779 {
780     return dwarf::DW_OP_deref;
781 }
782
783 extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
784 {
785     return dwarf::DW_OP_plus;
786 }
787
788 extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
789     raw_rust_string_ostream os(str);
790     unwrap<llvm::Type>(Type)->print(os);
791 }
792
793 extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
794     raw_rust_string_ostream os(str);
795     os << "(";
796     unwrap<llvm::Value>(Value)->getType()->print(os);
797     os << ":";
798     unwrap<llvm::Value>(Value)->print(os);
799     os << ")";
800 }
801
802 extern "C" bool
803 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
804     Module *Dst = unwrap(dst);
805     std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
806     ErrorOr<std::unique_ptr<Module>> Src =
807         llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
808     if (!Src) {
809         LLVMRustSetLastError(Src.getError().message().c_str());
810         return false;
811     }
812
813     std::string Err;
814
815     raw_string_ostream Stream(Err);
816     DiagnosticPrinterRawOStream DP(Stream);
817 #if LLVM_VERSION_MINOR >= 8
818     if (Linker::linkModules(*Dst, std::move(Src.get()))) {
819 #else
820     if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
821 #endif
822         LLVMRustSetLastError(Err.c_str());
823         return false;
824     }
825     return true;
826 }
827
828 // Note that the two following functions look quite similar to the
829 // LLVMGetSectionName function. Sadly, it appears that this function only
830 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
831 // function provided by LLVM doesn't return the length, so we've created our own
832 // function which returns the length as well as the data pointer.
833 //
834 // For an example of this not returning a null terminated string, see
835 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
836 // branches explicitly creates a StringRef without a null terminator, and then
837 // that's returned.
838
839 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
840     return reinterpret_cast<section_iterator*>(SI);
841 }
842
843 extern "C" size_t
844 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
845     StringRef ret;
846     if (std::error_code ec = (*unwrap(SI))->getName(ret))
847       report_fatal_error(ec.message());
848     *ptr = ret.data();
849     return ret.size();
850 }
851
852 // LLVMArrayType function does not support 64-bit ElementCount
853 extern "C" LLVMTypeRef
854 LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
855     return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
856 }
857
858 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
859 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
860
861 extern "C" void
862 LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
863     raw_rust_string_ostream os(str);
864     unwrap(T)->print(os);
865 }
866
867 extern "C" void
868 LLVMRustUnpackOptimizationDiagnostic(
869     LLVMDiagnosticInfoRef di,
870     const char **pass_name_out,
871     LLVMValueRef *function_out,
872     LLVMDebugLocRef *debugloc_out,
873     LLVMTwineRef *message_out)
874 {
875     // Undefined to call this not on an optimization diagnostic!
876     llvm::DiagnosticInfoOptimizationBase *opt
877         = static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
878
879     *pass_name_out = opt->getPassName();
880     *function_out = wrap(&opt->getFunction());
881     *debugloc_out = wrap(&opt->getDebugLoc());
882     *message_out = wrap(&opt->getMsg());
883 }
884
885 extern "C" void
886 LLVMRustUnpackInlineAsmDiagnostic(
887     LLVMDiagnosticInfoRef di,
888     unsigned *cookie_out,
889     LLVMTwineRef *message_out,
890     LLVMValueRef *instruction_out)
891 {
892     // Undefined to call this not on an inline assembly diagnostic!
893     llvm::DiagnosticInfoInlineAsm *ia
894         = static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
895
896     *cookie_out = ia->getLocCookie();
897     *message_out = wrap(&ia->getMsgStr());
898     *instruction_out = wrap(ia->getInstruction());
899 }
900
901 extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
902     raw_rust_string_ostream os(str);
903     DiagnosticPrinterRawOStream dp(os);
904     unwrap(di)->print(dp);
905 }
906
907 enum class LLVMRustDiagnosticKind {
908     Other,
909     InlineAsm,
910     StackSize,
911     DebugMetadataVersion,
912     SampleProfile,
913     OptimizationRemark,
914     OptimizationRemarkMissed,
915     OptimizationRemarkAnalysis,
916     OptimizationRemarkAnalysisFPCommute,
917     OptimizationRemarkAnalysisAliasing,
918     OptimizationRemarkOther,
919     OptimizationFailure,
920 };
921
922 static LLVMRustDiagnosticKind
923 to_rust(DiagnosticKind kind)
924 {
925     switch (kind) {
926     case DK_InlineAsm:
927         return LLVMRustDiagnosticKind::InlineAsm;
928     case DK_StackSize:
929         return LLVMRustDiagnosticKind::StackSize;
930     case DK_DebugMetadataVersion:
931         return LLVMRustDiagnosticKind::DebugMetadataVersion;
932     case DK_SampleProfile:
933         return LLVMRustDiagnosticKind::SampleProfile;
934     case DK_OptimizationRemark:
935         return LLVMRustDiagnosticKind::OptimizationRemark;
936     case DK_OptimizationRemarkMissed:
937         return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
938     case DK_OptimizationRemarkAnalysis:
939         return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
940 #if LLVM_VERSION_MINOR >= 8
941     case DK_OptimizationRemarkAnalysisFPCommute:
942         return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
943     case DK_OptimizationRemarkAnalysisAliasing:
944         return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
945 #endif
946     default:
947 #if LLVM_VERSION_MINOR >= 9
948         return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
949             LLVMRustDiagnosticKind::OptimizationRemarkOther :
950             LLVMRustDiagnosticKind::Other;
951 #else
952         return LLVMRustDiagnosticKind::Other;
953 #endif
954   }
955 }
956
957 extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
958     return to_rust((DiagnosticKind) unwrap(di)->getKind());
959 }
960 // This is kept distinct from LLVMGetTypeKind, because when
961 // a new type kind is added, the Rust-side enum must be
962 // updated or UB will result.
963 extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
964   switch (unwrap(Ty)->getTypeID()) {
965   case Type::VoidTyID:
966     return LLVMVoidTypeKind;
967   case Type::HalfTyID:
968     return LLVMHalfTypeKind;
969   case Type::FloatTyID:
970     return LLVMFloatTypeKind;
971   case Type::DoubleTyID:
972     return LLVMDoubleTypeKind;
973   case Type::X86_FP80TyID:
974     return LLVMX86_FP80TypeKind;
975   case Type::FP128TyID:
976     return LLVMFP128TypeKind;
977   case Type::PPC_FP128TyID:
978     return LLVMPPC_FP128TypeKind;
979   case Type::LabelTyID:
980     return LLVMLabelTypeKind;
981   case Type::MetadataTyID:
982     return LLVMMetadataTypeKind;
983   case Type::IntegerTyID:
984     return LLVMIntegerTypeKind;
985   case Type::FunctionTyID:
986     return LLVMFunctionTypeKind;
987   case Type::StructTyID:
988     return LLVMStructTypeKind;
989   case Type::ArrayTyID:
990     return LLVMArrayTypeKind;
991   case Type::PointerTyID:
992     return LLVMPointerTypeKind;
993   case Type::VectorTyID:
994     return LLVMVectorTypeKind;
995   case Type::X86_MMXTyID:
996     return LLVMX86_MMXTypeKind;
997 #if LLVM_VERSION_MINOR >= 8
998   case Type::TokenTyID:
999     return LLVMTokenTypeKind;
1000 #endif
1001   }
1002   llvm_unreachable("Unhandled TypeID.");
1003 }
1004
1005 extern "C" void LLVMRustWriteDebugLocToString(
1006     LLVMContextRef C,
1007     LLVMDebugLocRef dl,
1008     RustStringRef str)
1009 {
1010     raw_rust_string_ostream os(str);
1011     unwrap(dl)->print(os);
1012 }
1013
1014 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
1015
1016 extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
1017     LLVMContextRef C,
1018     LLVMContext::InlineAsmDiagHandlerTy H,
1019     void *CX)
1020 {
1021     unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
1022 }
1023
1024 extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
1025                                                   RustStringRef str) {
1026     raw_rust_string_ostream os(str);
1027     unwrap(d)->print("", os);
1028 }
1029
1030 extern "C" LLVMValueRef
1031 LLVMRustBuildLandingPad(LLVMBuilderRef Builder,
1032                         LLVMTypeRef Ty,
1033                         LLVMValueRef PersFn,
1034                         unsigned NumClauses,
1035                         const char* Name,
1036                         LLVMValueRef F) {
1037     return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
1038 }
1039
1040 extern "C" LLVMValueRef
1041 LLVMRustBuildCleanupPad(LLVMBuilderRef Builder,
1042                         LLVMValueRef ParentPad,
1043                         unsigned ArgCnt,
1044                         LLVMValueRef *LLArgs,
1045                         const char *Name) {
1046 #if LLVM_VERSION_MINOR >= 8
1047     Value **Args = unwrap(LLArgs);
1048     if (ParentPad == NULL) {
1049         Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1050         ParentPad = wrap(Constant::getNullValue(Ty));
1051     }
1052     return wrap(unwrap(Builder)->CreateCleanupPad(unwrap(ParentPad),
1053                                                   ArrayRef<Value*>(Args, ArgCnt),
1054                                                   Name));
1055 #else
1056     return NULL;
1057 #endif
1058 }
1059
1060 extern "C" LLVMValueRef
1061 LLVMRustBuildCleanupRet(LLVMBuilderRef Builder,
1062                         LLVMValueRef CleanupPad,
1063                         LLVMBasicBlockRef UnwindBB) {
1064 #if LLVM_VERSION_MINOR >= 8
1065     CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
1066     return wrap(unwrap(Builder)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
1067 #else
1068     return NULL;
1069 #endif
1070 }
1071
1072 extern "C" LLVMValueRef
1073 LLVMRustBuildCatchPad(LLVMBuilderRef Builder,
1074                       LLVMValueRef ParentPad,
1075                       unsigned ArgCnt,
1076                       LLVMValueRef *LLArgs,
1077                       const char *Name) {
1078 #if LLVM_VERSION_MINOR >= 8
1079     Value **Args = unwrap(LLArgs);
1080     return wrap(unwrap(Builder)->CreateCatchPad(unwrap(ParentPad),
1081                                                 ArrayRef<Value*>(Args, ArgCnt),
1082                                                 Name));
1083 #else
1084     return NULL;
1085 #endif
1086 }
1087
1088 extern "C" LLVMValueRef
1089 LLVMRustBuildCatchRet(LLVMBuilderRef Builder,
1090                       LLVMValueRef Pad,
1091                       LLVMBasicBlockRef BB) {
1092 #if LLVM_VERSION_MINOR >= 8
1093     return wrap(unwrap(Builder)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
1094                                                 unwrap(BB)));
1095 #else
1096     return NULL;
1097 #endif
1098 }
1099
1100 extern "C" LLVMValueRef
1101 LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder,
1102                          LLVMValueRef ParentPad,
1103                          LLVMBasicBlockRef BB,
1104                          unsigned NumHandlers,
1105                          const char *Name) {
1106 #if LLVM_VERSION_MINOR >= 8
1107     if (ParentPad == NULL) {
1108         Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
1109         ParentPad = wrap(Constant::getNullValue(Ty));
1110     }
1111     return wrap(unwrap(Builder)->CreateCatchSwitch(unwrap(ParentPad),
1112                                                    unwrap(BB),
1113                                                    NumHandlers,
1114                                                    Name));
1115 #else
1116     return NULL;
1117 #endif
1118 }
1119
1120 extern "C" void
1121 LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
1122                    LLVMBasicBlockRef Handler) {
1123 #if LLVM_VERSION_MINOR >= 8
1124     Value *CatchSwitch = unwrap(CatchSwitchRef);
1125     cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
1126 #endif
1127 }
1128
1129 extern "C" void
1130 LLVMRustSetPersonalityFn(LLVMBuilderRef B,
1131                          LLVMValueRef Personality) {
1132 #if LLVM_VERSION_MINOR >= 8
1133     unwrap(B)->GetInsertBlock()
1134              ->getParent()
1135              ->setPersonalityFn(cast<Function>(unwrap(Personality)));
1136 #endif
1137 }
1138
1139 #if LLVM_VERSION_MINOR >= 8
1140 extern "C" OperandBundleDef*
1141 LLVMRustBuildOperandBundleDef(const char *Name,
1142                               LLVMValueRef *Inputs,
1143                               unsigned NumInputs) {
1144   return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
1145 }
1146
1147 extern "C" void
1148 LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) {
1149   delete Bundle;
1150 }
1151
1152 extern "C" LLVMValueRef
1153 LLVMRustBuildCall(LLVMBuilderRef B,
1154                     LLVMValueRef Fn,
1155                     LLVMValueRef *Args,
1156                     unsigned NumArgs,
1157                     OperandBundleDef *Bundle,
1158                     const char *Name) {
1159     unsigned len = Bundle ? 1 : 0;
1160     ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1161     return wrap(unwrap(B)->CreateCall(unwrap(Fn),
1162                                       makeArrayRef(unwrap(Args), NumArgs),
1163                                       Bundles,
1164                                       Name));
1165 }
1166
1167 extern "C" LLVMValueRef
1168 LLVMRustBuildInvoke(LLVMBuilderRef B,
1169                     LLVMValueRef Fn,
1170                     LLVMValueRef *Args,
1171                     unsigned NumArgs,
1172                     LLVMBasicBlockRef Then,
1173                     LLVMBasicBlockRef Catch,
1174                     OperandBundleDef *Bundle,
1175                     const char *Name) {
1176     unsigned len = Bundle ? 1 : 0;
1177     ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
1178     return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
1179                                         makeArrayRef(unwrap(Args), NumArgs),
1180                                         Bundles,
1181                                         Name));
1182 }
1183 #else
1184 extern "C" void*
1185 LLVMRustBuildOperandBundleDef(const char *Name,
1186                               LLVMValueRef *Inputs,
1187                               unsigned NumInputs) {
1188   return NULL;
1189 }
1190
1191 extern "C" void
1192 LLVMRustFreeOperandBundleDef(void* Bundle) {
1193 }
1194
1195 extern "C" LLVMValueRef
1196 LLVMRustBuildCall(LLVMBuilderRef B,
1197                     LLVMValueRef Fn,
1198                     LLVMValueRef *Args,
1199                     unsigned NumArgs,
1200                     void *Bundle,
1201                     const char *Name) {
1202     return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
1203 }
1204
1205 extern "C" LLVMValueRef
1206 LLVMRustBuildInvoke(LLVMBuilderRef B,
1207                     LLVMValueRef Fn,
1208                     LLVMValueRef *Args,
1209                     unsigned NumArgs,
1210                     LLVMBasicBlockRef Then,
1211                     LLVMBasicBlockRef Catch,
1212                     void *Bundle,
1213                     const char *Name) {
1214     return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
1215 }
1216 #endif
1217
1218 extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) {
1219     auto point = unwrap(BB)->getFirstInsertionPt();
1220     unwrap(B)->SetInsertPoint(unwrap(BB), point);
1221 }
1222
1223 extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V, const char *Name) {
1224     Triple TargetTriple(unwrap(M)->getTargetTriple());
1225     GlobalObject *GV = unwrap<GlobalObject>(V);
1226     if (!TargetTriple.isOSBinFormatMachO()) {
1227         GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
1228     }
1229 }
1230
1231 extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
1232     GlobalObject *GV = unwrap<GlobalObject>(V);
1233     GV->setComdat(nullptr);
1234 }