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