1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 #include "llvm/Object/Archive.h"
13 #include "llvm/Object/ObjectFile.h"
15 //===----------------------------------------------------------------------===
17 // This file defines alternate interfaces to core functions that are more
18 // readily callable by Rust's FFI.
20 //===----------------------------------------------------------------------===
23 using namespace llvm::sys;
24 using namespace llvm::object;
26 static char *LastError;
28 extern "C" LLVMMemoryBufferRef
29 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
30 LLVMMemoryBufferRef MemBuf = NULL;
32 LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf, &err);
34 LLVMRustSetLastError(err);
39 extern "C" char *LLVMRustGetLastError(void) {
40 char *ret = LastError;
45 void LLVMRustSetLastError(const char *err) {
46 free((void*) LastError);
47 LastError = strdup(err);
51 LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
52 unwrap(M)->setTargetTriple(Triple::normalize(triple));
55 extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
56 LLVMBool SignExtend) {
57 return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
60 extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
63 LLVMBool SignExtend) {
64 unsigned long long N = N_hi;
67 return LLVMConstInt(IntTy, N, SignExtend);
70 extern "C" void LLVMRustPrintPassTimings() {
71 raw_fd_ostream OS (2, false); // stderr.
72 TimerGroup::printAll(OS);
75 extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
77 LLVMTypeRef FunctionTy) {
78 return wrap(unwrap(M)->getOrInsertFunction(Name,
79 unwrap<FunctionType>(FunctionTy)));
82 extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
83 return wrap(Type::getMetadataTy(*unwrap(C)));
86 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
87 unwrap<Function>(fn)->addFnAttr(Name);
90 extern "C" void LLVMRemoveFunctionAttrString(LLVMValueRef fn, const char *Name) {
91 Function *f = unwrap<Function>(fn);
92 LLVMContext &C = f->getContext();
95 AttributeSet to_remove = AttributeSet::get(C, AttributeSet::FunctionIndex, B);
97 AttributeSet attrs = f->getAttributes();
98 f->setAttributes(attrs.removeAttributes(f->getContext(),
99 AttributeSet::FunctionIndex,
103 extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
104 Function *A = unwrap<Function>(Fn);
106 A->addAttributes(AttributeSet::ReturnIndex,
107 AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
110 extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
111 Function *A = unwrap<Function>(Fn);
113 A->removeAttributes(AttributeSet::ReturnIndex,
114 AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
117 #if LLVM_VERSION_MINOR >= 5
118 extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {
119 Function *A = unwrap<Function>(Fn);
120 A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold);
123 extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {}
126 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
129 AtomicOrdering order,
130 unsigned alignment) {
131 LoadInst* li = new LoadInst(unwrap(source),0);
132 li->setVolatile(true);
133 li->setAtomic(order);
134 li->setAlignment(alignment);
135 return wrap(unwrap(B)->Insert(li, Name));
138 extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
141 AtomicOrdering order,
142 unsigned alignment) {
143 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
144 si->setVolatile(true);
145 si->setAtomic(order);
146 si->setAlignment(alignment);
147 return wrap(unwrap(B)->Insert(si));
150 extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
154 AtomicOrdering order,
155 AtomicOrdering failure_order) {
156 return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
157 unwrap(source), order
158 #if LLVM_VERSION_MINOR >= 5
163 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
164 return wrap(unwrap(B)->CreateFence(order));
167 extern "C" void LLVMSetDebug(int Enabled) {
173 extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
176 LLVMBool HasSideEffects,
177 LLVMBool IsAlignStack,
179 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
180 Constraints, HasSideEffects,
181 IsAlignStack, (InlineAsm::AsmDialect) Dialect));
184 typedef DIBuilder* DIBuilderRef;
186 template<typename DIT>
187 DIT unwrapDI(LLVMValueRef ref) {
188 return DIT(ref ? unwrap<MDNode>(ref) : NULL);
191 #if LLVM_VERSION_MINOR >= 5
192 extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION;
194 extern "C" const uint32_t LLVMRustDebugMetadataVersion = 1;
197 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
200 unwrap(M)->addModuleFlag(Module::Warning, name, value);
203 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
204 return new DIBuilder(*unwrap(M));
207 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
211 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
215 extern "C" void LLVMDIBuilderCreateCompileUnit(
216 DIBuilderRef Builder,
220 const char* Producer,
224 const char* SplitName) {
225 Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
226 Flags, RuntimeVer, SplitName);
229 extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
230 DIBuilderRef Builder,
231 const char* Filename,
232 const char* Directory) {
233 return wrap(Builder->createFile(Filename, Directory));
236 extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
237 DIBuilderRef Builder,
239 LLVMValueRef ParameterTypes) {
240 return wrap(Builder->createSubroutineType(
241 unwrapDI<DIFile>(File),
242 unwrapDI<DIArray>(ParameterTypes)));
245 extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
246 DIBuilderRef Builder,
249 const char* LinkageName,
261 return wrap(Builder->createFunction(
262 unwrapDI<DIScope>(Scope), Name, LinkageName,
263 unwrapDI<DIFile>(File), LineNo,
264 unwrapDI<DICompositeType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
266 unwrap<Function>(Fn),
267 unwrapDI<MDNode*>(TParam),
268 unwrapDI<MDNode*>(Decl)));
271 extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType(
272 DIBuilderRef Builder,
275 uint64_t AlignInBits,
277 return wrap(Builder->createBasicType(
279 AlignInBits, Encoding));
282 extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType(
283 DIBuilderRef Builder,
284 LLVMValueRef PointeeTy,
286 uint64_t AlignInBits,
288 return wrap(Builder->createPointerType(
289 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
292 extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
293 DIBuilderRef Builder,
299 uint64_t AlignInBits,
301 LLVMValueRef DerivedFrom,
302 LLVMValueRef Elements,
303 unsigned RunTimeLang,
304 LLVMValueRef VTableHolder,
305 const char *UniqueId) {
306 return wrap(Builder->createStructType(
307 unwrapDI<DIDescriptor>(Scope),
309 unwrapDI<DIFile>(File),
314 unwrapDI<DIType>(DerivedFrom),
315 unwrapDI<DIArray>(Elements),
317 unwrapDI<DIType>(VTableHolder)
318 #if LLVM_VERSION_MINOR >= 5
324 extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
325 DIBuilderRef Builder,
331 uint64_t AlignInBits,
332 uint64_t OffsetInBits,
335 return wrap(Builder->createMemberType(
336 unwrapDI<DIDescriptor>(Scope), Name,
337 unwrapDI<DIFile>(File), LineNo,
338 SizeInBits, AlignInBits, OffsetInBits, Flags,
339 unwrapDI<DIType>(Ty)));
342 extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
343 DIBuilderRef Builder,
348 unsigned Discriminator) {
349 return wrap(Builder->createLexicalBlock(
350 unwrapDI<DIDescriptor>(Scope),
351 unwrapDI<DIFile>(File), Line, Col
352 #if LLVM_VERSION_MINOR >= 5
358 extern "C" LLVMValueRef LLVMDIBuilderCreateStaticVariable(
359 DIBuilderRef Builder,
360 LLVMValueRef Context,
362 const char* LinkageName,
368 LLVMValueRef Decl = NULL) {
369 return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
372 unwrapDI<DIFile>(File),
374 unwrapDI<DIType>(Ty),
377 unwrapDI<MDNode*>(Decl)));
380 extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
381 DIBuilderRef Builder,
391 return wrap(Builder->createLocalVariable(Tag,
392 unwrapDI<DIDescriptor>(Scope), Name,
393 unwrapDI<DIFile>(File),
395 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
398 extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType(
399 DIBuilderRef Builder,
401 uint64_t AlignInBits,
403 LLVMValueRef Subscripts) {
404 return wrap(Builder->createArrayType(Size, AlignInBits,
405 unwrapDI<DIType>(Ty),
406 unwrapDI<DIArray>(Subscripts)));
409 extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType(
410 DIBuilderRef Builder,
412 uint64_t AlignInBits,
414 LLVMValueRef Subscripts) {
415 return wrap(Builder->createVectorType(Size, AlignInBits,
416 unwrapDI<DIType>(Ty),
417 unwrapDI<DIArray>(Subscripts)));
420 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(
421 DIBuilderRef Builder,
424 return wrap(Builder->getOrCreateSubrange(Lo, Count));
427 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray(
428 DIBuilderRef Builder,
431 return wrap(Builder->getOrCreateArray(
432 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
435 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
436 DIBuilderRef Builder,
438 LLVMValueRef VarInfo,
439 LLVMBasicBlockRef InsertAtEnd) {
440 return wrap(Builder->insertDeclare(
442 unwrapDI<DIVariable>(VarInfo),
443 unwrap(InsertAtEnd)));
446 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
447 DIBuilderRef Builder,
449 LLVMValueRef VarInfo,
450 LLVMValueRef InsertBefore) {
451 return wrap(Builder->insertDeclare(
453 unwrapDI<DIVariable>(VarInfo),
454 unwrap<Instruction>(InsertBefore)));
457 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator(
458 DIBuilderRef Builder,
462 return wrap(Builder->createEnumerator(Name, Val));
465 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerationType(
466 DIBuilderRef Builder,
472 uint64_t AlignInBits,
473 LLVMValueRef Elements,
474 LLVMValueRef ClassType)
476 return wrap(Builder->createEnumerationType(
477 unwrapDI<DIDescriptor>(Scope),
479 unwrapDI<DIFile>(File),
483 unwrapDI<DIArray>(Elements),
484 unwrapDI<DIType>(ClassType)));
487 extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
488 DIBuilderRef Builder,
494 uint64_t AlignInBits,
496 LLVMValueRef Elements,
497 unsigned RunTimeLang,
498 const char* UniqueId)
500 return wrap(Builder->createUnionType(
501 unwrapDI<DIDescriptor>(Scope),
503 unwrapDI<DIFile>(File),
508 unwrapDI<DIArray>(Elements),
510 #if LLVM_VERSION_MINOR >= 5
516 #if LLVM_VERSION_MINOR < 5
517 extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) {
518 unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
522 extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter(
523 DIBuilderRef Builder,
531 return wrap(Builder->createTemplateTypeParameter(
532 unwrapDI<DIDescriptor>(Scope),
534 unwrapDI<DIType>(Ty),
535 unwrapDI<MDNode*>(File),
540 extern "C" LLVMValueRef LLVMDIBuilderCreateOpDeref(LLVMTypeRef IntTy)
542 return LLVMConstInt(IntTy, DIBuilder::OpDeref, true);
545 extern "C" LLVMValueRef LLVMDIBuilderCreateOpPlus(LLVMTypeRef IntTy)
547 return LLVMConstInt(IntTy, DIBuilder::OpPlus, true);
550 extern "C" LLVMValueRef LLVMDIBuilderCreateComplexVariable(
551 DIBuilderRef Builder,
558 LLVMValueRef* AddrOps,
559 unsigned AddrOpsCount,
562 llvm::ArrayRef<llvm::Value*> addr_ops((llvm::Value**)AddrOps, AddrOpsCount);
564 return wrap(Builder->createComplexVariable(
566 unwrapDI<DIDescriptor>(Scope),
568 unwrapDI<DIFile>(File),
570 unwrapDI<DIType>(Ty),
576 extern "C" LLVMValueRef LLVMDIBuilderCreateNameSpace(
577 DIBuilderRef Builder,
583 return wrap(Builder->createNameSpace(
584 unwrapDI<DIDescriptor>(Scope),
586 unwrapDI<DIFile>(File),
590 extern "C" void LLVMDICompositeTypeSetTypeArray(
591 LLVMValueRef CompositeType,
592 LLVMValueRef TypeArray)
594 unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
597 extern "C" char *LLVMTypeToString(LLVMTypeRef Type) {
599 llvm::raw_string_ostream os(s);
600 unwrap<llvm::Type>(Type)->print(os);
601 return strdup(os.str().data());
604 extern "C" char *LLVMValueToString(LLVMValueRef Value) {
606 llvm::raw_string_ostream os(s);
608 unwrap<llvm::Value>(Value)->getType()->print(os);
610 unwrap<llvm::Value>(Value)->print(os);
612 return strdup(os.str().data());
615 #if LLVM_VERSION_MINOR >= 5
617 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
618 Module *Dst = unwrap(dst);
619 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
620 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
622 LLVMRustSetLastError(Src.getError().message().c_str());
628 if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
629 LLVMRustSetLastError(Err.c_str());
636 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
637 Module *Dst = unwrap(dst);
638 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
640 Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
642 LLVMRustSetLastError(Err.c_str());
647 if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
648 LLVMRustSetLastError(Err.c_str());
655 #if LLVM_VERSION_MINOR >= 5
657 LLVMRustOpenArchive(char *path) {
658 std::unique_ptr<MemoryBuffer> buf;
659 error_code err = MemoryBuffer::getFile(path, buf);
661 LLVMRustSetLastError(err.message().c_str());
664 Archive *ret = new Archive(buf.release(), err);
666 LLVMRustSetLastError(err.message().c_str());
673 LLVMRustOpenArchive(char *path) {
674 OwningPtr<MemoryBuffer> buf;
675 error_code err = MemoryBuffer::getFile(path, buf);
677 LLVMRustSetLastError(err.message().c_str());
680 Archive *ret = new Archive(buf.take(), err);
682 LLVMRustSetLastError(err.message().c_str());
689 extern "C" const char*
690 LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
691 #if LLVM_VERSION_MINOR >= 5
692 Archive::child_iterator child = ar->child_begin(),
693 end = ar->child_end();
695 Archive::child_iterator child = ar->begin_children(),
696 end = ar->end_children();
698 for (; child != end; ++child) {
700 error_code err = child->getName(sect_name);
702 if (sect_name.trim(" ") == name) {
703 StringRef buf = child->getBuffer();
712 LLVMRustDestroyArchive(Archive *ar) {
716 #if LLVM_VERSION_MINOR >= 5
718 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
719 GlobalValue *V = unwrap<GlobalValue>(Value);
720 V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
724 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
725 LLVMSetLinkage(Value, LLVMDLLExportLinkage);
731 return LLVM_VERSION_MINOR;
734 // Note that the two following functions look quite similar to the
735 // LLVMGetSectionName function. Sadly, it appears that this function only
736 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
737 // function provided by LLVM doesn't return the length, so we've created our own
738 // function which returns the length as well as the data pointer.
740 // For an example of this not returning a null terminated string, see
741 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
742 // branches explicitly creates a StringRef without a null terminator, and then
745 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
746 return reinterpret_cast<section_iterator*>(SI);
750 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
752 if (error_code ec = (*unwrap(SI))->getName(ret))
753 report_fatal_error(ec.message());