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 const char *LLVMRustError;
28 extern "C" LLVMMemoryBufferRef
29 LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
30 LLVMMemoryBufferRef MemBuf = NULL;
31 LLVMCreateMemoryBufferWithContentsOfFile(Path, &MemBuf,
32 const_cast<char **>(&LLVMRustError));
36 extern "C" const char *LLVMRustGetLastError(void) {
41 LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
42 unwrap(M)->setTargetTriple(Triple::normalize(triple));
45 extern "C" LLVMValueRef LLVMRustConstSmallInt(LLVMTypeRef IntTy, unsigned N,
46 LLVMBool SignExtend) {
47 return LLVMConstInt(IntTy, (unsigned long long)N, SignExtend);
50 extern "C" LLVMValueRef LLVMRustConstInt(LLVMTypeRef IntTy,
53 LLVMBool SignExtend) {
54 unsigned long long N = N_hi;
57 return LLVMConstInt(IntTy, N, SignExtend);
60 extern "C" void LLVMRustPrintPassTimings() {
61 raw_fd_ostream OS (2, false); // stderr.
62 TimerGroup::printAll(OS);
65 extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
67 LLVMTypeRef FunctionTy) {
68 return wrap(unwrap(M)->getOrInsertFunction(Name,
69 unwrap<FunctionType>(FunctionTy)));
72 extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
73 return wrap(Type::getMetadataTy(*unwrap(C)));
76 extern "C" void LLVMAddFunctionAttrString(LLVMValueRef fn, const char *Name) {
77 unwrap<Function>(fn)->addFnAttr(Name);
81 extern "C" void LLVMAddReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
82 Function *A = unwrap<Function>(Fn);
84 A->addAttributes(AttributeSet::ReturnIndex,
85 AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
88 extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
89 Function *A = unwrap<Function>(Fn);
91 A->removeAttributes(AttributeSet::ReturnIndex,
92 AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
95 #if LLVM_VERSION_MINOR >= 5
96 extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {
97 Function *A = unwrap<Function>(Fn);
98 A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold);
101 extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {}
104 extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
107 AtomicOrdering order,
108 unsigned alignment) {
109 LoadInst* li = new LoadInst(unwrap(source),0);
110 li->setVolatile(true);
111 li->setAtomic(order);
112 li->setAlignment(alignment);
113 return wrap(unwrap(B)->Insert(li, Name));
116 extern "C" LLVMValueRef LLVMBuildAtomicStore(LLVMBuilderRef B,
119 AtomicOrdering order,
120 unsigned alignment) {
121 StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
122 si->setVolatile(true);
123 si->setAtomic(order);
124 si->setAlignment(alignment);
125 return wrap(unwrap(B)->Insert(si));
128 extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B,
132 AtomicOrdering order) {
133 return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old),
134 unwrap(source), order));
136 extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) {
137 return wrap(unwrap(B)->CreateFence(order));
140 extern "C" void LLVMSetDebug(int Enabled) {
146 extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
149 LLVMBool HasSideEffects,
150 LLVMBool IsAlignStack,
152 return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
153 Constraints, HasSideEffects,
154 IsAlignStack, (InlineAsm::AsmDialect) Dialect));
157 typedef DIBuilder* DIBuilderRef;
159 template<typename DIT>
160 DIT unwrapDI(LLVMValueRef ref) {
161 return DIT(ref ? unwrap<MDNode>(ref) : NULL);
164 #if LLVM_VERSION_MINOR >= 5
165 extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION;
167 extern "C" const uint32_t LLVMRustDebugMetadataVersion = 1;
170 extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
173 unwrap(M)->addModuleFlag(Module::Warning, name, value);
176 extern "C" DIBuilderRef LLVMDIBuilderCreate(LLVMModuleRef M) {
177 return new DIBuilder(*unwrap(M));
180 extern "C" void LLVMDIBuilderDispose(DIBuilderRef Builder) {
184 extern "C" void LLVMDIBuilderFinalize(DIBuilderRef Builder) {
188 extern "C" void LLVMDIBuilderCreateCompileUnit(
189 DIBuilderRef Builder,
193 const char* Producer,
197 const char* SplitName) {
198 Builder->createCompileUnit(Lang, File, Dir, Producer, isOptimized,
199 Flags, RuntimeVer, SplitName);
202 extern "C" LLVMValueRef LLVMDIBuilderCreateFile(
203 DIBuilderRef Builder,
204 const char* Filename,
205 const char* Directory) {
206 return wrap(Builder->createFile(Filename, Directory));
209 extern "C" LLVMValueRef LLVMDIBuilderCreateSubroutineType(
210 DIBuilderRef Builder,
212 LLVMValueRef ParameterTypes) {
213 return wrap(Builder->createSubroutineType(
214 unwrapDI<DIFile>(File),
215 unwrapDI<DIArray>(ParameterTypes)));
218 extern "C" LLVMValueRef LLVMDIBuilderCreateFunction(
219 DIBuilderRef Builder,
222 const char* LinkageName,
234 return wrap(Builder->createFunction(
235 unwrapDI<DIScope>(Scope), Name, LinkageName,
236 unwrapDI<DIFile>(File), LineNo,
237 unwrapDI<DICompositeType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
239 unwrap<Function>(Fn),
240 unwrapDI<MDNode*>(TParam),
241 unwrapDI<MDNode*>(Decl)));
244 extern "C" LLVMValueRef LLVMDIBuilderCreateBasicType(
245 DIBuilderRef Builder,
248 uint64_t AlignInBits,
250 return wrap(Builder->createBasicType(
252 AlignInBits, Encoding));
255 extern "C" LLVMValueRef LLVMDIBuilderCreatePointerType(
256 DIBuilderRef Builder,
257 LLVMValueRef PointeeTy,
259 uint64_t AlignInBits,
261 return wrap(Builder->createPointerType(
262 unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
265 extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
266 DIBuilderRef Builder,
272 uint64_t AlignInBits,
274 LLVMValueRef DerivedFrom,
275 LLVMValueRef Elements,
276 unsigned RunTimeLang,
277 LLVMValueRef VTableHolder,
278 const char *UniqueId) {
279 return wrap(Builder->createStructType(
280 unwrapDI<DIDescriptor>(Scope),
282 unwrapDI<DIFile>(File),
287 unwrapDI<DIType>(DerivedFrom),
288 unwrapDI<DIArray>(Elements),
290 unwrapDI<DIType>(VTableHolder)
291 #if LLVM_VERSION_MINOR >= 5
298 extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
299 DIBuilderRef Builder,
305 uint64_t AlignInBits,
306 uint64_t OffsetInBits,
309 return wrap(Builder->createMemberType(
310 unwrapDI<DIDescriptor>(Scope), Name,
311 unwrapDI<DIFile>(File), LineNo,
312 SizeInBits, AlignInBits, OffsetInBits, Flags,
313 unwrapDI<DIType>(Ty)));
316 extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock(
317 DIBuilderRef Builder,
322 return wrap(Builder->createLexicalBlock(
323 unwrapDI<DIDescriptor>(Scope),
324 unwrapDI<DIFile>(File), Line, Col));
327 extern "C" LLVMValueRef LLVMDIBuilderCreateStaticVariable(
328 DIBuilderRef Builder,
329 LLVMValueRef Context,
331 const char* LinkageName,
337 LLVMValueRef Decl = NULL) {
338 return wrap(Builder->createStaticVariable(unwrapDI<DIDescriptor>(Context),
341 unwrapDI<DIFile>(File),
343 unwrapDI<DIType>(Ty),
346 unwrapDI<MDNode*>(Decl)));
349 extern "C" LLVMValueRef LLVMDIBuilderCreateLocalVariable(
350 DIBuilderRef Builder,
360 return wrap(Builder->createLocalVariable(Tag,
361 unwrapDI<DIDescriptor>(Scope), Name,
362 unwrapDI<DIFile>(File),
364 unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
367 extern "C" LLVMValueRef LLVMDIBuilderCreateArrayType(
368 DIBuilderRef Builder,
370 uint64_t AlignInBits,
372 LLVMValueRef Subscripts) {
373 return wrap(Builder->createArrayType(Size, AlignInBits,
374 unwrapDI<DIType>(Ty),
375 unwrapDI<DIArray>(Subscripts)));
378 extern "C" LLVMValueRef LLVMDIBuilderCreateVectorType(
379 DIBuilderRef Builder,
381 uint64_t AlignInBits,
383 LLVMValueRef Subscripts) {
384 return wrap(Builder->createVectorType(Size, AlignInBits,
385 unwrapDI<DIType>(Ty),
386 unwrapDI<DIArray>(Subscripts)));
389 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateSubrange(
390 DIBuilderRef Builder,
393 return wrap(Builder->getOrCreateSubrange(Lo, Count));
396 extern "C" LLVMValueRef LLVMDIBuilderGetOrCreateArray(
397 DIBuilderRef Builder,
400 return wrap(Builder->getOrCreateArray(
401 ArrayRef<Value*>(reinterpret_cast<Value**>(Ptr), Count)));
404 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareAtEnd(
405 DIBuilderRef Builder,
407 LLVMValueRef VarInfo,
408 LLVMBasicBlockRef InsertAtEnd) {
409 return wrap(Builder->insertDeclare(
411 unwrapDI<DIVariable>(VarInfo),
412 unwrap(InsertAtEnd)));
415 extern "C" LLVMValueRef LLVMDIBuilderInsertDeclareBefore(
416 DIBuilderRef Builder,
418 LLVMValueRef VarInfo,
419 LLVMValueRef InsertBefore) {
420 return wrap(Builder->insertDeclare(
422 unwrapDI<DIVariable>(VarInfo),
423 unwrap<Instruction>(InsertBefore)));
426 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerator(
427 DIBuilderRef Builder,
431 return wrap(Builder->createEnumerator(Name, Val));
434 extern "C" LLVMValueRef LLVMDIBuilderCreateEnumerationType(
435 DIBuilderRef Builder,
441 uint64_t AlignInBits,
442 LLVMValueRef Elements,
443 LLVMValueRef ClassType)
445 return wrap(Builder->createEnumerationType(
446 unwrapDI<DIDescriptor>(Scope),
448 unwrapDI<DIFile>(File),
452 unwrapDI<DIArray>(Elements),
453 unwrapDI<DIType>(ClassType)));
456 extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
457 DIBuilderRef Builder,
463 uint64_t AlignInBits,
465 LLVMValueRef Elements,
466 unsigned RunTimeLang,
467 const char* UniqueId)
469 return wrap(Builder->createUnionType(
470 unwrapDI<DIDescriptor>(Scope),
472 unwrapDI<DIFile>(File),
477 unwrapDI<DIArray>(Elements),
479 #if LLVM_VERSION_MINOR >= 5
486 extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) {
487 unwrap<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
490 extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter(
491 DIBuilderRef Builder,
499 return wrap(Builder->createTemplateTypeParameter(
500 unwrapDI<DIDescriptor>(Scope),
502 unwrapDI<DIType>(Ty),
503 unwrapDI<MDNode*>(File),
508 extern "C" LLVMValueRef LLVMDIBuilderCreateOpDeref(LLVMTypeRef IntTy)
510 return LLVMConstInt(IntTy, DIBuilder::OpDeref, true);
513 extern "C" LLVMValueRef LLVMDIBuilderCreateOpPlus(LLVMTypeRef IntTy)
515 return LLVMConstInt(IntTy, DIBuilder::OpPlus, true);
518 extern "C" LLVMValueRef LLVMDIBuilderCreateComplexVariable(
519 DIBuilderRef Builder,
526 LLVMValueRef* AddrOps,
527 unsigned AddrOpsCount,
530 llvm::ArrayRef<llvm::Value*> addr_ops((llvm::Value**)AddrOps, AddrOpsCount);
532 return wrap(Builder->createComplexVariable(
534 unwrapDI<DIDescriptor>(Scope),
536 unwrapDI<DIFile>(File),
538 unwrapDI<DIType>(Ty),
544 extern "C" LLVMValueRef LLVMDIBuilderCreateNameSpace(
545 DIBuilderRef Builder,
551 return wrap(Builder->createNameSpace(
552 unwrapDI<DIDescriptor>(Scope),
554 unwrapDI<DIFile>(File),
558 extern "C" void LLVMDICompositeTypeSetTypeArray(
559 LLVMValueRef CompositeType,
560 LLVMValueRef TypeArray)
562 unwrapDI<DICompositeType>(CompositeType).setTypeArray(unwrapDI<DIArray>(TypeArray));
565 extern "C" char *LLVMTypeToString(LLVMTypeRef Type) {
567 llvm::raw_string_ostream os(s);
568 unwrap<llvm::Type>(Type)->print(os);
569 return strdup(os.str().data());
572 extern "C" char *LLVMValueToString(LLVMValueRef Value) {
574 llvm::raw_string_ostream os(s);
576 unwrap<llvm::Value>(Value)->getType()->print(os);
578 unwrap<llvm::Value>(Value)->print(os);
580 return strdup(os.str().data());
583 #if LLVM_VERSION_MINOR >= 5
585 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
586 Module *Dst = unwrap(dst);
587 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
588 ErrorOr<Module *> Src = llvm::getLazyBitcodeModule(buf, Dst->getContext());
590 LLVMRustError = Src.getError().message().c_str();
596 if (Linker::LinkModules(Dst, *Src, Linker::DestroySource, &Err)) {
597 LLVMRustError = Err.c_str();
604 LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
605 Module *Dst = unwrap(dst);
606 MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
608 Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err);
610 LLVMRustError = Err.c_str();
615 if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) {
616 LLVMRustError = Err.c_str();
624 LLVMRustOpenArchive(char *path) {
625 OwningPtr<MemoryBuffer> buf;
626 error_code err = MemoryBuffer::getFile(path, buf);
628 LLVMRustError = err.message().c_str();
631 Archive *ret = new Archive(buf.take(), err);
633 LLVMRustError = err.message().c_str();
639 extern "C" const char*
640 LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
641 #if LLVM_VERSION_MINOR >= 5
642 Archive::child_iterator child = ar->child_begin(),
643 end = ar->child_end();
645 Archive::child_iterator child = ar->begin_children(),
646 end = ar->end_children();
648 for (; child != end; ++child) {
650 error_code err = child->getName(sect_name);
652 if (sect_name.trim(" ") == name) {
653 StringRef buf = child->getBuffer();
662 LLVMRustDestroyArchive(Archive *ar) {
666 #if LLVM_VERSION_MINOR >= 5
668 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
669 GlobalValue *V = unwrap<GlobalValue>(Value);
670 V->setDLLStorageClass(GlobalValue::DLLExportStorageClass);
674 LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) {
675 LLVMSetLinkage(Value, LLVMDLLExportLinkage);
681 return LLVM_VERSION_MINOR;
684 // Note that the two following functions look quite similar to the
685 // LLVMGetSectionName function. Sadly, it appears that this function only
686 // returns a char* pointer, which isn't guaranteed to be null-terminated. The
687 // function provided by LLVM doesn't return the length, so we've created our own
688 // function which returns the length as well as the data pointer.
690 // For an example of this not returning a null terminated string, see
691 // lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
692 // branches explicitly creates a StringRef without a null terminator, and then
695 inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
696 return reinterpret_cast<section_iterator*>(SI);
700 LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
702 if (error_code ec = (*unwrap(SI))->getName(ret))
703 report_fatal_error(ec.message());