2013-05-27 23:15:31 +00:00
|
|
|
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
2012-12-10 23:44:02 +00:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
2011-03-15 21:57:26 +00:00
|
|
|
//
|
2012-12-10 23:44:02 +00:00
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-05-27 23:15:31 +00:00
|
|
|
#include "rustllvm.h"
|
2013-12-17 04:58:21 +00:00
|
|
|
#include "llvm/Object/Archive.h"
|
2014-04-03 17:45:36 +00:00
|
|
|
#include "llvm/Object/ObjectFile.h"
|
2014-09-12 15:17:58 +00:00
|
|
|
#include "llvm/IR/DiagnosticInfo.h"
|
|
|
|
#include "llvm/IR/DiagnosticPrinter.h"
|
2016-08-01 23:35:09 +00:00
|
|
|
#include "llvm/IR/Instructions.h"
|
2013-05-27 23:15:31 +00:00
|
|
|
|
2014-05-21 19:07:48 +00:00
|
|
|
#include "llvm/IR/CallSite.h"
|
|
|
|
|
2011-10-22 00:35:52 +00:00
|
|
|
//===----------------------------------------------------------------------===
|
2011-03-15 21:57:26 +00:00
|
|
|
//
|
|
|
|
// This file defines alternate interfaces to core functions that are more
|
|
|
|
// readily callable by Rust's FFI.
|
|
|
|
//
|
2011-10-22 00:35:52 +00:00
|
|
|
//===----------------------------------------------------------------------===
|
2011-03-15 21:57:26 +00:00
|
|
|
|
2011-04-15 21:35:46 +00:00
|
|
|
using namespace llvm;
|
2012-09-11 06:05:51 +00:00
|
|
|
using namespace llvm::sys;
|
2013-12-17 04:58:21 +00:00
|
|
|
using namespace llvm::object;
|
2011-04-15 21:35:46 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
// LLVMAtomicOrdering is already an enum - don't create another
|
|
|
|
// one.
|
|
|
|
static AtomicOrdering from_rust(LLVMAtomicOrdering Ordering) {
|
|
|
|
switch (Ordering) {
|
|
|
|
case LLVMAtomicOrderingNotAtomic:
|
|
|
|
return AtomicOrdering::NotAtomic;
|
|
|
|
case LLVMAtomicOrderingUnordered:
|
|
|
|
return AtomicOrdering::Unordered;
|
|
|
|
case LLVMAtomicOrderingMonotonic:
|
|
|
|
return AtomicOrdering::Monotonic;
|
|
|
|
case LLVMAtomicOrderingAcquire:
|
|
|
|
return AtomicOrdering::Acquire;
|
|
|
|
case LLVMAtomicOrderingRelease:
|
|
|
|
return AtomicOrdering::Release;
|
|
|
|
case LLVMAtomicOrderingAcquireRelease:
|
|
|
|
return AtomicOrdering::AcquireRelease;
|
|
|
|
case LLVMAtomicOrderingSequentiallyConsistent:
|
|
|
|
return AtomicOrdering::SequentiallyConsistent;
|
|
|
|
}
|
|
|
|
|
|
|
|
llvm_unreachable("Invalid LLVMAtomicOrdering value!");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-04-15 14:25:22 +00:00
|
|
|
static char *LastError;
|
2013-04-06 00:17:49 +00:00
|
|
|
|
2014-07-18 14:07:15 +00:00
|
|
|
extern "C" LLVMMemoryBufferRef
|
|
|
|
LLVMRustCreateMemoryBufferWithContentsOfFile(const char *Path) {
|
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> buf_or = MemoryBuffer::getFile(Path,
|
|
|
|
-1,
|
|
|
|
false);
|
|
|
|
if (!buf_or) {
|
|
|
|
LLVMRustSetLastError(buf_or.getError().message().c_str());
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
return wrap(buf_or.get().release());
|
|
|
|
}
|
2011-03-15 21:57:26 +00:00
|
|
|
|
2014-04-15 14:25:22 +00:00
|
|
|
extern "C" char *LLVMRustGetLastError(void) {
|
|
|
|
char *ret = LastError;
|
|
|
|
LastError = NULL;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LLVMRustSetLastError(const char *err) {
|
|
|
|
free((void*) LastError);
|
|
|
|
LastError = strdup(err);
|
2011-03-15 21:57:26 +00:00
|
|
|
}
|
|
|
|
|
2013-08-23 03:58:42 +00:00
|
|
|
extern "C" void
|
|
|
|
LLVMRustSetNormalizedTarget(LLVMModuleRef M, const char *triple) {
|
|
|
|
unwrap(M)->setTargetTriple(Triple::normalize(triple));
|
2011-05-05 18:34:15 +00:00
|
|
|
}
|
|
|
|
|
2011-05-10 23:10:08 +00:00
|
|
|
extern "C" void LLVMRustPrintPassTimings() {
|
|
|
|
raw_fd_ostream OS (2, false); // stderr.
|
|
|
|
TimerGroup::printAll(OS);
|
|
|
|
}
|
2011-10-31 21:42:17 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M,
|
|
|
|
const char* Name) {
|
2015-02-27 11:37:33 +00:00
|
|
|
return wrap(unwrap(M)->getNamedValue(Name));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustGetOrInsertFunction(LLVMModuleRef M,
|
|
|
|
const char* Name,
|
|
|
|
LLVMTypeRef FunctionTy) {
|
2011-11-14 16:32:31 +00:00
|
|
|
return wrap(unwrap(M)->getOrInsertFunction(Name,
|
|
|
|
unwrap<FunctionType>(FunctionTy)));
|
|
|
|
}
|
2011-11-10 05:55:09 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustGetOrInsertGlobal(LLVMModuleRef M,
|
|
|
|
const char* Name,
|
|
|
|
LLVMTypeRef Ty) {
|
2015-03-03 22:57:44 +00:00
|
|
|
return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
|
2011-11-10 05:55:09 +00:00
|
|
|
return wrap(Type::getMetadataTy(*unwrap(C)));
|
|
|
|
}
|
2012-06-21 22:01:32 +00:00
|
|
|
|
2016-11-16 22:36:08 +00:00
|
|
|
static Attribute::AttrKind
|
|
|
|
from_rust(LLVMRustAttribute kind) {
|
|
|
|
switch (kind) {
|
|
|
|
case AlwaysInline:
|
|
|
|
return Attribute::AlwaysInline;
|
|
|
|
case ByVal:
|
|
|
|
return Attribute::ByVal;
|
|
|
|
case Cold:
|
|
|
|
return Attribute::Cold;
|
|
|
|
case InlineHint:
|
|
|
|
return Attribute::InlineHint;
|
|
|
|
case MinSize:
|
|
|
|
return Attribute::MinSize;
|
|
|
|
case Naked:
|
|
|
|
return Attribute::Naked;
|
|
|
|
case NoAlias:
|
|
|
|
return Attribute::NoAlias;
|
|
|
|
case NoCapture:
|
|
|
|
return Attribute::NoCapture;
|
|
|
|
case NoInline:
|
|
|
|
return Attribute::NoInline;
|
|
|
|
case NonNull:
|
|
|
|
return Attribute::NonNull;
|
|
|
|
case NoRedZone:
|
|
|
|
return Attribute::NoRedZone;
|
|
|
|
case NoReturn:
|
|
|
|
return Attribute::NoReturn;
|
|
|
|
case NoUnwind:
|
|
|
|
return Attribute::NoUnwind;
|
|
|
|
case OptimizeForSize:
|
|
|
|
return Attribute::OptimizeForSize;
|
|
|
|
case ReadOnly:
|
|
|
|
return Attribute::ReadOnly;
|
|
|
|
case SExt:
|
|
|
|
return Attribute::SExt;
|
|
|
|
case StructRet:
|
|
|
|
return Attribute::StructRet;
|
|
|
|
case UWTable:
|
|
|
|
return Attribute::UWTable;
|
|
|
|
case ZExt:
|
|
|
|
return Attribute::ZExt;
|
2016-12-21 18:42:10 +00:00
|
|
|
case InReg:
|
|
|
|
return Attribute::InReg;
|
2016-11-16 22:36:08 +00:00
|
|
|
default:
|
|
|
|
llvm_unreachable("bad AttributeKind");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-21 11:30:05 +00:00
|
|
|
extern "C" void LLVMRustAddCallSiteAttribute(LLVMValueRef Instr, unsigned index, LLVMRustAttribute attr) {
|
2014-05-21 19:07:48 +00:00
|
|
|
CallSite Call = CallSite(unwrap<Instruction>(Instr));
|
2016-11-21 11:30:05 +00:00
|
|
|
Attribute Attr = Attribute::get(Call->getContext(), from_rust(attr));
|
|
|
|
AttrBuilder B(Attr);
|
2014-05-21 19:07:48 +00:00
|
|
|
Call.setAttributes(
|
|
|
|
Call.getAttributes().addAttributes(Call->getContext(), index,
|
|
|
|
AttributeSet::get(Call->getContext(),
|
|
|
|
index, B)));
|
2013-08-06 04:21:37 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustAddDereferenceableCallSiteAttr(LLVMValueRef Instr,
|
2016-11-16 22:36:08 +00:00
|
|
|
unsigned index,
|
|
|
|
uint64_t bytes)
|
2016-08-01 23:35:09 +00:00
|
|
|
{
|
2014-07-25 23:06:44 +00:00
|
|
|
CallSite Call = CallSite(unwrap<Instruction>(Instr));
|
|
|
|
AttrBuilder B;
|
2016-11-16 22:36:08 +00:00
|
|
|
B.addDereferenceableAttr(bytes);
|
2014-07-25 23:06:44 +00:00
|
|
|
Call.setAttributes(
|
2016-11-16 22:36:08 +00:00
|
|
|
Call.getAttributes().addAttributes(Call->getContext(), index,
|
2014-07-25 23:06:44 +00:00
|
|
|
AttributeSet::get(Call->getContext(),
|
2016-11-16 22:36:08 +00:00
|
|
|
index, B)));
|
2014-07-25 23:06:44 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustAddFunctionAttribute(LLVMValueRef Fn,
|
|
|
|
unsigned index,
|
2016-11-21 11:30:05 +00:00
|
|
|
LLVMRustAttribute attr)
|
2016-08-01 23:35:09 +00:00
|
|
|
{
|
2014-05-21 19:07:48 +00:00
|
|
|
Function *A = unwrap<Function>(Fn);
|
2016-11-21 11:30:05 +00:00
|
|
|
Attribute Attr = Attribute::get(A->getContext(), from_rust(attr));
|
|
|
|
AttrBuilder B(Attr);
|
2014-05-21 19:07:48 +00:00
|
|
|
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustAddDereferenceableAttr(LLVMValueRef Fn,
|
|
|
|
unsigned index,
|
|
|
|
uint64_t bytes)
|
|
|
|
{
|
2014-07-25 23:06:44 +00:00
|
|
|
Function *A = unwrap<Function>(Fn);
|
|
|
|
AttrBuilder B;
|
|
|
|
B.addDereferenceableAttr(bytes);
|
|
|
|
A->addAttributes(index, AttributeSet::get(A->getContext(), index, B));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustAddFunctionAttrStringValue(LLVMValueRef Fn,
|
|
|
|
unsigned index,
|
|
|
|
const char *Name,
|
|
|
|
const char *Value) {
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
Function *F = unwrap<Function>(Fn);
|
|
|
|
AttrBuilder B;
|
|
|
|
B.addAttribute(Name, Value);
|
|
|
|
F->addAttributes(index, AttributeSet::get(F->getContext(), index, B));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustRemoveFunctionAttributes(LLVMValueRef Fn,
|
|
|
|
unsigned index,
|
2016-11-21 11:30:05 +00:00
|
|
|
LLVMRustAttribute attr)
|
2016-08-01 23:35:09 +00:00
|
|
|
{
|
2016-11-16 22:36:08 +00:00
|
|
|
Function *F = unwrap<Function>(Fn);
|
|
|
|
const AttributeSet PAL = F->getAttributes();
|
2016-11-21 11:30:05 +00:00
|
|
|
Attribute Attr = Attribute::get(F->getContext(), from_rust(attr));
|
|
|
|
AttrBuilder B(Attr);
|
2016-03-26 11:27:33 +00:00
|
|
|
const AttributeSet PALnew =
|
2016-11-16 22:36:08 +00:00
|
|
|
PAL.removeAttributes(F->getContext(), index,
|
|
|
|
AttributeSet::get(F->getContext(), index, B));
|
|
|
|
F->setAttributes(PALnew);
|
2014-04-19 17:33:46 +00:00
|
|
|
}
|
2013-09-09 06:32:30 +00:00
|
|
|
|
2016-03-14 23:01:12 +00:00
|
|
|
// enable fpmath flag UnsafeAlgebra
|
2016-03-19 21:02:33 +00:00
|
|
|
extern "C" void LLVMRustSetHasUnsafeAlgebra(LLVMValueRef V) {
|
|
|
|
if (auto I = dyn_cast<Instruction>(unwrap<Value>(V))) {
|
|
|
|
I->setHasUnsafeAlgebra(true);
|
|
|
|
}
|
2016-03-14 23:01:12 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustBuildAtomicLoad(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef source,
|
|
|
|
const char* Name,
|
|
|
|
LLVMAtomicOrdering order,
|
|
|
|
unsigned alignment) {
|
2013-05-12 19:22:20 +00:00
|
|
|
LoadInst* li = new LoadInst(unwrap(source),0);
|
2016-08-01 23:35:09 +00:00
|
|
|
li->setAtomic(from_rust(order));
|
2013-05-21 00:28:06 +00:00
|
|
|
li->setAlignment(alignment);
|
2013-05-17 02:48:24 +00:00
|
|
|
return wrap(unwrap(B)->Insert(li, Name));
|
2013-05-12 19:22:20 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustBuildAtomicStore(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef val,
|
|
|
|
LLVMValueRef target,
|
|
|
|
LLVMAtomicOrdering order,
|
|
|
|
unsigned alignment) {
|
2013-05-12 19:22:20 +00:00
|
|
|
StoreInst* si = new StoreInst(unwrap(val),unwrap(target));
|
2016-08-01 23:35:09 +00:00
|
|
|
si->setAtomic(from_rust(order));
|
2013-05-21 00:28:06 +00:00
|
|
|
si->setAlignment(alignment);
|
2013-05-12 19:22:20 +00:00
|
|
|
return wrap(unwrap(B)->Insert(si));
|
|
|
|
}
|
|
|
|
|
2016-07-12 22:38:30 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustBuildAtomicCmpXchg(LLVMBuilderRef B,
|
2012-10-22 02:23:50 +00:00
|
|
|
LLVMValueRef target,
|
|
|
|
LLVMValueRef old,
|
|
|
|
LLVMValueRef source,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMAtomicOrdering order,
|
|
|
|
LLVMAtomicOrdering failure_order,
|
2016-01-16 23:40:11 +00:00
|
|
|
LLVMBool weak) {
|
2016-08-01 23:35:09 +00:00
|
|
|
AtomicCmpXchgInst* acxi = unwrap(B)->CreateAtomicCmpXchg(
|
|
|
|
unwrap(target),
|
|
|
|
unwrap(old),
|
|
|
|
unwrap(source),
|
|
|
|
from_rust(order),
|
|
|
|
from_rust(failure_order));
|
2016-01-16 23:40:11 +00:00
|
|
|
acxi->setWeak(weak);
|
|
|
|
return wrap(acxi);
|
2012-10-22 02:23:50 +00:00
|
|
|
}
|
2016-08-01 23:35:09 +00:00
|
|
|
|
|
|
|
enum class LLVMRustSynchronizationScope {
|
|
|
|
Other,
|
|
|
|
SingleThread,
|
|
|
|
CrossThread,
|
|
|
|
};
|
|
|
|
|
|
|
|
static SynchronizationScope
|
|
|
|
from_rust(LLVMRustSynchronizationScope scope)
|
|
|
|
{
|
|
|
|
switch (scope) {
|
|
|
|
case LLVMRustSynchronizationScope::SingleThread:
|
|
|
|
return SingleThread;
|
|
|
|
case LLVMRustSynchronizationScope::CrossThread:
|
|
|
|
return CrossThread;
|
|
|
|
default:
|
2016-08-02 21:25:19 +00:00
|
|
|
llvm_unreachable("bad SynchronizationScope.");
|
2016-08-01 23:35:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef LLVMRustBuildAtomicFence(
|
|
|
|
LLVMBuilderRef B,
|
|
|
|
LLVMAtomicOrdering order,
|
|
|
|
LLVMRustSynchronizationScope scope)
|
|
|
|
{
|
|
|
|
return wrap(unwrap(B)->CreateFence(from_rust(order), from_rust(scope)));
|
2013-07-28 07:48:16 +00:00
|
|
|
}
|
2012-07-25 19:06:03 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustSetDebug(int Enabled) {
|
2012-10-08 19:40:09 +00:00
|
|
|
#ifndef NDEBUG
|
2012-07-25 19:06:03 +00:00
|
|
|
DebugFlag = Enabled;
|
2012-10-08 19:40:09 +00:00
|
|
|
#endif
|
2012-07-25 19:06:03 +00:00
|
|
|
}
|
2013-03-10 06:37:50 +00:00
|
|
|
|
2016-08-02 21:25:19 +00:00
|
|
|
enum class LLVMRustAsmDialect {
|
|
|
|
Other,
|
|
|
|
Att,
|
|
|
|
Intel,
|
|
|
|
};
|
|
|
|
|
|
|
|
static InlineAsm::AsmDialect
|
|
|
|
from_rust(LLVMRustAsmDialect dialect)
|
|
|
|
{
|
|
|
|
switch (dialect) {
|
|
|
|
case LLVMRustAsmDialect::Att:
|
|
|
|
return InlineAsm::AD_ATT;
|
|
|
|
case LLVMRustAsmDialect::Intel:
|
|
|
|
return InlineAsm::AD_Intel;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("bad AsmDialect.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustInlineAsm(LLVMTypeRef Ty,
|
|
|
|
char *AsmString,
|
|
|
|
char *Constraints,
|
|
|
|
LLVMBool HasSideEffects,
|
|
|
|
LLVMBool IsAlignStack,
|
2016-08-02 21:25:19 +00:00
|
|
|
LLVMRustAsmDialect Dialect) {
|
2013-03-10 06:37:50 +00:00
|
|
|
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
|
|
|
|
Constraints, HasSideEffects,
|
2016-08-02 21:25:19 +00:00
|
|
|
IsAlignStack, from_rust(Dialect)));
|
2013-03-10 06:37:50 +00:00
|
|
|
}
|
2013-06-14 04:25:12 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
typedef DIBuilder* LLVMRustDIBuilderRef;
|
2013-06-14 18:38:29 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
typedef struct LLVMOpaqueMetadata *LLVMRustMetadataRef;
|
2015-01-30 18:25:07 +00:00
|
|
|
|
|
|
|
namespace llvm {
|
2016-08-01 23:35:09 +00:00
|
|
|
DEFINE_ISA_CONVERSION_FUNCTIONS(Metadata, LLVMRustMetadataRef)
|
2015-01-30 18:25:07 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
inline Metadata **unwrap(LLVMRustMetadataRef *Vals) {
|
2015-01-30 18:25:07 +00:00
|
|
|
return reinterpret_cast<Metadata**>(Vals);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
template<typename DIT>
|
2016-08-01 23:35:09 +00:00
|
|
|
DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
return (DIT*) (ref ? unwrap<MDNode>(ref) : NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define DIDescriptor DIScope
|
|
|
|
#define DIArray DINodeArray
|
|
|
|
#define unwrapDI unwrapDIptr
|
2013-06-14 18:38:29 +00:00
|
|
|
|
2016-11-18 22:15:14 +00:00
|
|
|
// These values **must** match debuginfo::DIFlags! They also *happen*
|
|
|
|
// to match LLVM, but that isn't required as we do giant sets of
|
|
|
|
// matching below. The value shouldn't be directly passed to LLVM.
|
|
|
|
enum class LLVMRustDIFlags : uint32_t {
|
|
|
|
FlagZero = 0,
|
|
|
|
FlagPrivate = 1,
|
|
|
|
FlagProtected = 2,
|
|
|
|
FlagPublic = 3,
|
|
|
|
FlagFwdDecl = (1 << 2),
|
|
|
|
FlagAppleBlock = (1 << 3),
|
|
|
|
FlagBlockByrefStruct = (1 << 4),
|
|
|
|
FlagVirtual = (1 << 5),
|
|
|
|
FlagArtificial = (1 << 6),
|
|
|
|
FlagExplicit = (1 << 7),
|
|
|
|
FlagPrototyped = (1 << 8),
|
|
|
|
FlagObjcClassComplete = (1 << 9),
|
|
|
|
FlagObjectPointer = (1 << 10),
|
|
|
|
FlagVector = (1 << 11),
|
|
|
|
FlagStaticMember = (1 << 12),
|
|
|
|
FlagLValueReference = (1 << 13),
|
|
|
|
FlagRValueReference = (1 << 14),
|
|
|
|
// Do not add values that are not supported by the minimum LLVM
|
|
|
|
// version we support!
|
|
|
|
};
|
|
|
|
|
|
|
|
inline LLVMRustDIFlags operator& (LLVMRustDIFlags a, LLVMRustDIFlags b) {
|
|
|
|
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(a) & static_cast<uint32_t>(b));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline LLVMRustDIFlags operator| (LLVMRustDIFlags a, LLVMRustDIFlags b) {
|
|
|
|
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(a) | static_cast<uint32_t>(b));
|
|
|
|
}
|
|
|
|
|
|
|
|
inline LLVMRustDIFlags& operator|= (LLVMRustDIFlags& a, LLVMRustDIFlags b) {
|
|
|
|
return a = a | b;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool is_set(LLVMRustDIFlags f) {
|
|
|
|
return f != LLVMRustDIFlags::FlagZero;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline LLVMRustDIFlags visibility(LLVMRustDIFlags f) {
|
|
|
|
return static_cast<LLVMRustDIFlags>(static_cast<uint32_t>(f) & 0x3);
|
|
|
|
}
|
|
|
|
|
2016-11-18 21:22:39 +00:00
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
static DINode::DIFlags from_rust(LLVMRustDIFlags flags) {
|
|
|
|
DINode::DIFlags result = DINode::DIFlags::FlagZero;
|
|
|
|
#else
|
2016-11-18 22:15:14 +00:00
|
|
|
static unsigned from_rust(LLVMRustDIFlags flags) {
|
|
|
|
unsigned result = 0;
|
2016-11-18 21:22:39 +00:00
|
|
|
#endif
|
2016-11-18 22:15:14 +00:00
|
|
|
|
|
|
|
switch (visibility(flags)) {
|
|
|
|
case LLVMRustDIFlags::FlagPrivate:
|
|
|
|
result |= DINode::DIFlags::FlagPrivate;
|
|
|
|
break;
|
|
|
|
case LLVMRustDIFlags::FlagProtected:
|
|
|
|
result |= DINode::DIFlags::FlagProtected;
|
|
|
|
break;
|
|
|
|
case LLVMRustDIFlags::FlagPublic:
|
|
|
|
result |= DINode::DIFlags::FlagPublic;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// The rest are handled below
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagFwdDecl)) { result |= DINode::DIFlags::FlagFwdDecl; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagAppleBlock)) { result |= DINode::DIFlags::FlagAppleBlock; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagBlockByrefStruct)) { result |= DINode::DIFlags::FlagBlockByrefStruct; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagVirtual)) { result |= DINode::DIFlags::FlagVirtual; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagArtificial)) { result |= DINode::DIFlags::FlagArtificial; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagExplicit)) { result |= DINode::DIFlags::FlagExplicit; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagPrototyped)) { result |= DINode::DIFlags::FlagPrototyped; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagObjcClassComplete)) { result |= DINode::DIFlags::FlagObjcClassComplete; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagObjectPointer)) { result |= DINode::DIFlags::FlagObjectPointer; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagVector)) { result |= DINode::DIFlags::FlagVector; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagStaticMember)) { result |= DINode::DIFlags::FlagStaticMember; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagLValueReference)) { result |= DINode::DIFlags::FlagLValueReference; }
|
|
|
|
if (is_set(flags & LLVMRustDIFlags::FlagRValueReference)) { result |= DINode::DIFlags::FlagRValueReference; }
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-05-30 13:50:12 +00:00
|
|
|
extern "C" uint32_t LLVMRustDebugMetadataVersion() {
|
2015-05-12 04:07:38 +00:00
|
|
|
return DEBUG_METADATA_VERSION;
|
|
|
|
}
|
2014-01-28 05:05:33 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" uint32_t LLVMRustVersionMinor() {
|
2015-01-24 11:00:35 +00:00
|
|
|
return LLVM_VERSION_MINOR;
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" uint32_t LLVMRustVersionMajor() {
|
2015-01-24 11:00:35 +00:00
|
|
|
return LLVM_VERSION_MAJOR;
|
|
|
|
}
|
|
|
|
|
2014-01-28 05:05:33 +00:00
|
|
|
extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M,
|
|
|
|
const char *name,
|
|
|
|
uint32_t value) {
|
|
|
|
unwrap(M)->addModuleFlag(Module::Warning, name, value);
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustDIBuilderRef LLVMRustDIBuilderCreate(LLVMModuleRef M) {
|
2013-06-14 18:38:29 +00:00
|
|
|
return new DIBuilder(*unwrap(M));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustDIBuilderDispose(LLVMRustDIBuilderRef Builder) {
|
2013-06-14 18:38:29 +00:00
|
|
|
delete Builder;
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustDIBuilderFinalize(LLVMRustDIBuilderRef Builder) {
|
2013-06-14 18:38:29 +00:00
|
|
|
Builder->finalize();
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateCompileUnit(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned Lang,
|
|
|
|
const char* File,
|
|
|
|
const char* Dir,
|
|
|
|
const char* Producer,
|
|
|
|
bool isOptimized,
|
|
|
|
const char* Flags,
|
|
|
|
unsigned RuntimeVer,
|
|
|
|
const char* SplitName) {
|
2014-12-03 22:48:18 +00:00
|
|
|
return wrap(Builder->createCompileUnit(Lang,
|
|
|
|
File,
|
|
|
|
Dir,
|
|
|
|
Producer,
|
|
|
|
isOptimized,
|
|
|
|
Flags,
|
|
|
|
RuntimeVer,
|
|
|
|
SplitName));
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFile(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-06-14 18:38:29 +00:00
|
|
|
const char* Filename,
|
|
|
|
const char* Directory) {
|
|
|
|
return wrap(Builder->createFile(Filename, Directory));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateSubroutineType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef File,
|
|
|
|
LLVMRustMetadataRef ParameterTypes) {
|
2013-06-14 18:38:29 +00:00
|
|
|
return wrap(Builder->createSubroutineType(
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_EQ(3, 7)
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIFile>(File),
|
2015-10-24 09:42:23 +00:00
|
|
|
#endif
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DITypeRefArray(unwrap<MDTuple>(ParameterTypes))));
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-06-14 18:38:29 +00:00
|
|
|
const char* Name,
|
|
|
|
const char* LinkageName,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned LineNo,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty,
|
2013-06-14 18:38:29 +00:00
|
|
|
bool isLocalToUnit,
|
|
|
|
bool isDefinition,
|
|
|
|
unsigned ScopeLine,
|
2016-11-18 22:15:14 +00:00
|
|
|
LLVMRustDIFlags Flags,
|
2013-06-14 18:38:29 +00:00
|
|
|
bool isOptimized,
|
|
|
|
LLVMValueRef Fn,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef TParam,
|
|
|
|
LLVMRustMetadataRef Decl) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-23 05:07:19 +00:00
|
|
|
DITemplateParameterArray TParams =
|
|
|
|
DITemplateParameterArray(unwrap<MDTuple>(TParam));
|
|
|
|
DISubprogram *Sub = Builder->createFunction(
|
|
|
|
unwrapDI<DIScope>(Scope), Name, LinkageName,
|
|
|
|
unwrapDI<DIFile>(File), LineNo,
|
|
|
|
unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
|
2016-11-18 22:15:14 +00:00
|
|
|
from_rust(Flags), isOptimized,
|
2015-10-23 05:07:19 +00:00
|
|
|
TParams,
|
|
|
|
unwrapDIptr<DISubprogram>(Decl));
|
|
|
|
unwrap<Function>(Fn)->setSubprogram(Sub);
|
|
|
|
return wrap(Sub);
|
|
|
|
#else
|
2013-06-14 18:38:29 +00:00
|
|
|
return wrap(Builder->createFunction(
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIScope>(Scope), Name, LinkageName,
|
|
|
|
unwrapDI<DIFile>(File), LineNo,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
|
2016-11-18 22:15:14 +00:00
|
|
|
from_rust(Flags), isOptimized,
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrap<Function>(Fn),
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
unwrapDIptr<MDNode>(TParam),
|
|
|
|
unwrapDIptr<MDNode>(Decl)));
|
2015-10-23 05:07:19 +00:00
|
|
|
#endif
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateBasicType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-06-14 18:38:29 +00:00
|
|
|
const char* Name,
|
|
|
|
uint64_t SizeInBits,
|
|
|
|
uint64_t AlignInBits,
|
|
|
|
unsigned Encoding) {
|
|
|
|
return wrap(Builder->createBasicType(
|
2016-11-18 16:11:18 +00:00
|
|
|
Name,
|
|
|
|
SizeInBits,
|
|
|
|
#if LLVM_VERSION_LE(3, 9)
|
|
|
|
AlignInBits,
|
|
|
|
#endif
|
|
|
|
Encoding
|
|
|
|
));
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
2013-07-02 16:10:24 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreatePointerType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef PointeeTy,
|
2013-06-14 18:38:29 +00:00
|
|
|
uint64_t SizeInBits,
|
|
|
|
uint64_t AlignInBits,
|
|
|
|
const char* Name) {
|
|
|
|
return wrap(Builder->createPointerType(
|
|
|
|
unwrapDI<DIType>(PointeeTy), SizeInBits, AlignInBits, Name));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-06-14 18:38:29 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned LineNumber,
|
|
|
|
uint64_t SizeInBits,
|
|
|
|
uint64_t AlignInBits,
|
2016-11-18 22:15:14 +00:00
|
|
|
LLVMRustDIFlags Flags,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef DerivedFrom,
|
|
|
|
LLVMRustMetadataRef Elements,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned RunTimeLang,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef VTableHolder,
|
2013-10-01 10:24:50 +00:00
|
|
|
const char *UniqueId) {
|
2013-06-14 18:38:29 +00:00
|
|
|
return wrap(Builder->createStructType(
|
2013-10-01 10:24:50 +00:00
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
Name,
|
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNumber,
|
|
|
|
SizeInBits,
|
|
|
|
AlignInBits,
|
2016-11-18 22:15:14 +00:00
|
|
|
from_rust(Flags),
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIType>(DerivedFrom),
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DINodeArray(unwrapDI<MDTuple>(Elements)),
|
2013-10-01 10:24:50 +00:00
|
|
|
RunTimeLang,
|
2015-03-14 12:14:04 +00:00
|
|
|
unwrapDI<DIType>(VTableHolder),
|
|
|
|
UniqueId
|
2014-03-31 21:43:19 +00:00
|
|
|
));
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-06-14 18:38:29 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned LineNo,
|
|
|
|
uint64_t SizeInBits,
|
|
|
|
uint64_t AlignInBits,
|
|
|
|
uint64_t OffsetInBits,
|
2016-11-18 22:15:14 +00:00
|
|
|
LLVMRustDIFlags Flags,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty) {
|
2013-06-14 18:38:29 +00:00
|
|
|
return wrap(Builder->createMemberType(
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIDescriptor>(Scope), Name,
|
2013-06-14 18:38:29 +00:00
|
|
|
unwrapDI<DIFile>(File), LineNo,
|
2016-11-18 22:15:14 +00:00
|
|
|
SizeInBits, AlignInBits, OffsetInBits, from_rust(Flags),
|
2013-06-14 18:38:29 +00:00
|
|
|
unwrapDI<DIType>(Ty)));
|
|
|
|
}
|
2013-07-02 16:10:24 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlock(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
|
|
|
LLVMRustMetadataRef File,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned Line,
|
2014-09-30 21:20:22 +00:00
|
|
|
unsigned Col) {
|
2013-06-14 18:38:29 +00:00
|
|
|
return wrap(Builder->createLexicalBlock(
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
2014-03-31 21:43:19 +00:00
|
|
|
unwrapDI<DIFile>(File), Line, Col
|
|
|
|
));
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
2013-07-02 16:10:24 +00:00
|
|
|
|
2016-08-25 02:34:31 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateLexicalBlockFile(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
|
|
|
LLVMRustMetadataRef File) {
|
|
|
|
return wrap(Builder->createLexicalBlockFile(
|
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
unwrapDI<DIFile>(File)));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStaticVariable(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Context,
|
2014-02-21 01:44:29 +00:00
|
|
|
const char* Name,
|
|
|
|
const char* LinkageName,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2014-02-21 01:44:29 +00:00
|
|
|
unsigned LineNo,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty,
|
2014-02-21 01:44:29 +00:00
|
|
|
bool isLocalToUnit,
|
|
|
|
LLVMValueRef Val,
|
2016-11-18 16:11:18 +00:00
|
|
|
LLVMRustMetadataRef Decl = NULL,
|
2016-12-11 09:08:20 +00:00
|
|
|
uint64_t AlignInBits = 0) {
|
|
|
|
Constant *InitVal = cast<Constant>(unwrap(Val));
|
|
|
|
|
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
llvm::DIExpression *InitExpr = nullptr;
|
|
|
|
if (llvm::ConstantInt *IntVal = llvm::dyn_cast<llvm::ConstantInt>(InitVal)) {
|
|
|
|
InitExpr = Builder->createConstantValueExpression(
|
|
|
|
IntVal->getValue().getSExtValue());
|
|
|
|
} else if (llvm::ConstantFP *FPVal = llvm::dyn_cast<llvm::ConstantFP>(InitVal)) {
|
|
|
|
InitExpr = Builder->createConstantValueExpression(
|
|
|
|
FPVal->getValueAPF().bitcastToAPInt().getZExtValue());
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return wrap(Builder->createGlobalVariable(unwrapDI<DIDescriptor>(Context),
|
2014-02-21 01:44:29 +00:00
|
|
|
Name,
|
|
|
|
LinkageName,
|
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNo,
|
|
|
|
unwrapDI<DIType>(Ty),
|
|
|
|
isLocalToUnit,
|
2016-12-11 09:08:20 +00:00
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
InitExpr,
|
|
|
|
#else
|
|
|
|
InitVal,
|
|
|
|
#endif
|
2016-11-18 16:11:18 +00:00
|
|
|
unwrapDIptr<MDNode>(Decl)
|
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
, AlignInBits
|
|
|
|
#endif
|
|
|
|
));
|
2014-02-21 01:44:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned Tag,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Scope,
|
2013-06-14 18:38:29 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned LineNo,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty,
|
2013-06-14 18:38:29 +00:00
|
|
|
bool AlwaysPreserve,
|
2016-11-18 22:15:14 +00:00
|
|
|
LLVMRustDIFlags Flags,
|
2016-11-18 16:11:18 +00:00
|
|
|
unsigned ArgNo,
|
|
|
|
uint64_t AlignInBits)
|
|
|
|
{
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 09:42:23 +00:00
|
|
|
if (Tag == 0x100) { // DW_TAG_auto_variable
|
|
|
|
return wrap(Builder->createAutoVariable(
|
2016-11-18 16:11:18 +00:00
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
Name,
|
2015-10-24 09:42:23 +00:00
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNo,
|
2016-11-18 16:11:18 +00:00
|
|
|
unwrapDI<DIType>(Ty),
|
|
|
|
AlwaysPreserve,
|
|
|
|
from_rust(Flags)
|
|
|
|
#if LLVM_VERSION_GE(4,0)
|
|
|
|
, AlignInBits
|
|
|
|
#endif
|
|
|
|
));
|
2015-10-24 09:42:23 +00:00
|
|
|
} else {
|
|
|
|
return wrap(Builder->createParameterVariable(
|
|
|
|
unwrapDI<DIDescriptor>(Scope), Name, ArgNo,
|
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNo,
|
2016-11-18 22:15:14 +00:00
|
|
|
unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags)));
|
2015-10-24 09:42:23 +00:00
|
|
|
}
|
|
|
|
#else
|
2013-07-02 16:10:24 +00:00
|
|
|
return wrap(Builder->createLocalVariable(Tag,
|
|
|
|
unwrapDI<DIDescriptor>(Scope), Name,
|
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNo,
|
2016-11-18 22:15:14 +00:00
|
|
|
unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags), ArgNo));
|
2015-10-24 09:42:23 +00:00
|
|
|
#endif
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateArrayType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-07-02 16:10:24 +00:00
|
|
|
uint64_t Size,
|
|
|
|
uint64_t AlignInBits,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty,
|
|
|
|
LLVMRustMetadataRef Subscripts) {
|
2013-06-14 19:23:42 +00:00
|
|
|
return wrap(Builder->createArrayType(Size, AlignInBits,
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIType>(Ty),
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DINodeArray(unwrapDI<MDTuple>(Subscripts))
|
|
|
|
));
|
2013-06-14 19:23:42 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVectorType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-07-02 16:10:24 +00:00
|
|
|
uint64_t Size,
|
|
|
|
uint64_t AlignInBits,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty,
|
|
|
|
LLVMRustMetadataRef Subscripts) {
|
2013-06-14 18:38:29 +00:00
|
|
|
return wrap(Builder->createVectorType(Size, AlignInBits,
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrapDI<DIType>(Ty),
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DINodeArray(unwrapDI<MDTuple>(Subscripts))
|
|
|
|
));
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateSubrange(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-07-02 16:10:24 +00:00
|
|
|
int64_t Lo,
|
2013-06-14 18:38:29 +00:00
|
|
|
int64_t Count) {
|
|
|
|
return wrap(Builder->getOrCreateSubrange(Lo, Count));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderGetOrCreateArray(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef* Ptr,
|
2013-06-14 18:38:29 +00:00
|
|
|
unsigned Count) {
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
Metadata **DataValue = unwrap(Ptr);
|
|
|
|
return wrap(Builder->getOrCreateArray(
|
|
|
|
ArrayRef<Metadata*>(DataValue, Count)).get());
|
2013-06-14 18:38:29 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustDIBuilderInsertDeclareAtEnd(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-06-11 07:57:25 +00:00
|
|
|
LLVMValueRef Val,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef VarInfo,
|
2015-01-30 18:25:07 +00:00
|
|
|
int64_t* AddrOps,
|
|
|
|
unsigned AddrOpsCount,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
LLVMValueRef DL,
|
2013-06-11 07:57:25 +00:00
|
|
|
LLVMBasicBlockRef InsertAtEnd) {
|
|
|
|
return wrap(Builder->insertDeclare(
|
2013-07-02 16:10:24 +00:00
|
|
|
unwrap(Val),
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
unwrap<DILocalVariable>(VarInfo),
|
|
|
|
Builder->createExpression(
|
|
|
|
llvm::ArrayRef<int64_t>(AddrOps, AddrOpsCount)),
|
|
|
|
DebugLoc(cast<MDNode>(unwrap<MetadataAsValue>(DL)->getMetadata())),
|
2013-06-11 07:57:25 +00:00
|
|
|
unwrap(InsertAtEnd)));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerator(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
2013-07-02 08:33:51 +00:00
|
|
|
const char* Name,
|
|
|
|
uint64_t Val)
|
|
|
|
{
|
|
|
|
return wrap(Builder->createEnumerator(Name, Val));
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateEnumerationType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-07-02 08:33:51 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-07-02 08:33:51 +00:00
|
|
|
unsigned LineNumber,
|
|
|
|
uint64_t SizeInBits,
|
|
|
|
uint64_t AlignInBits,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Elements,
|
|
|
|
LLVMRustMetadataRef ClassType)
|
2013-07-02 08:33:51 +00:00
|
|
|
{
|
|
|
|
return wrap(Builder->createEnumerationType(
|
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
Name,
|
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNumber,
|
|
|
|
SizeInBits,
|
|
|
|
AlignInBits,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DINodeArray(unwrapDI<MDTuple>(Elements)),
|
2013-07-02 08:33:51 +00:00
|
|
|
unwrapDI<DIType>(ClassType)));
|
2013-07-02 16:10:24 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-07-02 16:10:24 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-07-02 16:10:24 +00:00
|
|
|
unsigned LineNumber,
|
|
|
|
uint64_t SizeInBits,
|
|
|
|
uint64_t AlignInBits,
|
2016-11-18 22:15:14 +00:00
|
|
|
LLVMRustDIFlags Flags,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Elements,
|
2014-01-02 14:20:43 +00:00
|
|
|
unsigned RunTimeLang,
|
|
|
|
const char* UniqueId)
|
2013-07-02 16:10:24 +00:00
|
|
|
{
|
|
|
|
return wrap(Builder->createUnionType(
|
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
Name,
|
|
|
|
unwrapDI<DIFile>(File),
|
|
|
|
LineNumber,
|
|
|
|
SizeInBits,
|
|
|
|
AlignInBits,
|
2016-11-18 22:15:14 +00:00
|
|
|
from_rust(Flags),
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DINodeArray(unwrapDI<MDTuple>(Elements)),
|
2015-03-14 12:14:04 +00:00
|
|
|
RunTimeLang,
|
|
|
|
UniqueId
|
2014-03-31 21:43:19 +00:00
|
|
|
));
|
2013-07-28 07:48:16 +00:00
|
|
|
}
|
2013-08-09 20:47:00 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateTemplateTypeParameter(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-08-08 16:33:06 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Ty,
|
|
|
|
LLVMRustMetadataRef File,
|
2013-09-05 11:29:30 +00:00
|
|
|
unsigned LineNo,
|
|
|
|
unsigned ColumnNo)
|
2013-08-08 16:33:06 +00:00
|
|
|
{
|
|
|
|
return wrap(Builder->createTemplateTypeParameter(
|
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
Name,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
unwrapDI<DIType>(Ty)
|
|
|
|
));
|
2013-08-08 16:33:06 +00:00
|
|
|
}
|
2013-08-23 16:45:02 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateNameSpace(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef Scope,
|
2013-09-05 11:29:30 +00:00
|
|
|
const char* Name,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef File,
|
2013-09-05 11:29:30 +00:00
|
|
|
unsigned LineNo)
|
|
|
|
{
|
|
|
|
return wrap(Builder->createNameSpace(
|
|
|
|
unwrapDI<DIDescriptor>(Scope),
|
|
|
|
Name,
|
|
|
|
unwrapDI<DIFile>(File),
|
2016-11-25 16:23:25 +00:00
|
|
|
LineNo
|
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
, false // ExportSymbols (only relevant for C++ anonymous namespaces)
|
|
|
|
#endif
|
|
|
|
));
|
2013-09-05 11:29:30 +00:00
|
|
|
}
|
2013-09-11 14:37:43 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustDICompositeTypeSetTypeArray(
|
|
|
|
LLVMRustDIBuilderRef Builder,
|
|
|
|
LLVMRustMetadataRef CompositeType,
|
|
|
|
LLVMRustMetadataRef TypeArray)
|
2013-09-11 14:37:43 +00:00
|
|
|
{
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
DICompositeType *tmp = unwrapDI<DICompositeType>(CompositeType);
|
|
|
|
Builder->replaceArrays(tmp, DINodeArray(unwrap<MDTuple>(TypeArray)));
|
2013-09-11 14:37:43 +00:00
|
|
|
}
|
2013-10-11 23:56:11 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" LLVMValueRef LLVMRustDIBuilderCreateDebugLocation(
|
2015-01-30 18:25:07 +00:00
|
|
|
LLVMContextRef Context,
|
|
|
|
unsigned Line,
|
|
|
|
unsigned Column,
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustMetadataRef Scope,
|
|
|
|
LLVMRustMetadataRef InlinedAt)
|
|
|
|
{
|
2015-01-30 18:25:07 +00:00
|
|
|
LLVMContext& context = *unwrap(Context);
|
|
|
|
|
|
|
|
DebugLoc debug_loc = DebugLoc::get(Line,
|
|
|
|
Column,
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
unwrapDIptr<MDNode>(Scope),
|
|
|
|
unwrapDIptr<MDNode>(InlinedAt));
|
2015-01-30 18:25:07 +00:00
|
|
|
|
2016-06-09 13:41:17 +00:00
|
|
|
return wrap(MetadataAsValue::get(context, debug_loc.getAsMDNode()));
|
2015-01-30 18:25:07 +00:00
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" int64_t LLVMRustDIBuilderCreateOpDeref()
|
|
|
|
{
|
|
|
|
return dwarf::DW_OP_deref;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" int64_t LLVMRustDIBuilderCreateOpPlus()
|
|
|
|
{
|
|
|
|
return dwarf::DW_OP_plus;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void LLVMRustWriteTypeToString(LLVMTypeRef Type, RustStringRef str) {
|
2014-09-10 06:12:09 +00:00
|
|
|
raw_rust_string_ostream os(str);
|
2013-10-11 23:56:11 +00:00
|
|
|
unwrap<llvm::Type>(Type)->print(os);
|
|
|
|
}
|
Implement LTO
This commit implements LTO for rust leveraging LLVM's passes. What this means
is:
* When compiling an rlib, in addition to insdering foo.o into the archive, also
insert foo.bc (the LLVM bytecode) of the optimized module.
* When the compiler detects the -Z lto option, it will attempt to perform LTO on
a staticlib or binary output. The compiler will emit an error if a dylib or
rlib output is being generated.
* The actual act of performing LTO is as follows:
1. Force all upstream libraries to have an rlib version available.
2. Load the bytecode of each upstream library from the rlib.
3. Link all this bytecode into the current LLVM module (just using llvm
apis)
4. Run an internalization pass which internalizes all symbols except those
found reachable for the local crate of compilation.
5. Run the LLVM LTO pass manager over this entire module
6a. If assembling an archive, then add all upstream rlibs into the output
archive. This ignores all of the object/bitcode/metadata files rust
generated and placed inside the rlibs.
6b. If linking a binary, create copies of all upstream rlibs, remove the
rust-generated object-file, and then link everything as usual.
As I have explained in #10741, this process is excruciatingly slow, so this is
*not* turned on by default, and it is also why I have decided to hide it behind
a -Z flag for now. The good news is that the binary sizes are about as small as
they can be as a result of LTO, so it's definitely working.
Closes #10741
Closes #10740
2013-12-03 07:19:29 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustWriteValueToString(LLVMValueRef Value, RustStringRef str) {
|
2014-09-10 06:12:09 +00:00
|
|
|
raw_rust_string_ostream os(str);
|
2014-01-15 19:39:08 +00:00
|
|
|
os << "(";
|
|
|
|
unwrap<llvm::Value>(Value)->getType()->print(os);
|
|
|
|
os << ":";
|
|
|
|
unwrap<llvm::Value>(Value)->print(os);
|
|
|
|
os << ")";
|
|
|
|
}
|
|
|
|
|
Implement LTO
This commit implements LTO for rust leveraging LLVM's passes. What this means
is:
* When compiling an rlib, in addition to insdering foo.o into the archive, also
insert foo.bc (the LLVM bytecode) of the optimized module.
* When the compiler detects the -Z lto option, it will attempt to perform LTO on
a staticlib or binary output. The compiler will emit an error if a dylib or
rlib output is being generated.
* The actual act of performing LTO is as follows:
1. Force all upstream libraries to have an rlib version available.
2. Load the bytecode of each upstream library from the rlib.
3. Link all this bytecode into the current LLVM module (just using llvm
apis)
4. Run an internalization pass which internalizes all symbols except those
found reachable for the local crate of compilation.
5. Run the LLVM LTO pass manager over this entire module
6a. If assembling an archive, then add all upstream rlibs into the output
archive. This ignores all of the object/bitcode/metadata files rust
generated and placed inside the rlibs.
6b. If linking a binary, create copies of all upstream rlibs, remove the
rust-generated object-file, and then link everything as usual.
As I have explained in #10741, this process is excruciatingly slow, so this is
*not* turned on by default, and it is also why I have decided to hide it behind
a -Z flag for now. The good news is that the binary sizes are about as small as
they can be as a result of LTO, so it's definitely working.
Closes #10741
Closes #10740
2013-12-03 07:19:29 +00:00
|
|
|
extern "C" bool
|
|
|
|
LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) {
|
|
|
|
Module *Dst = unwrap(dst);
|
2016-11-17 14:10:19 +00:00
|
|
|
|
2014-09-30 21:20:22 +00:00
|
|
|
std::unique_ptr<MemoryBuffer> buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len));
|
2016-11-17 14:10:19 +00:00
|
|
|
|
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
Expected<std::unique_ptr<Module>> SrcOrError =
|
|
|
|
llvm::getLazyBitcodeModule(buf->getMemBufferRef(), Dst->getContext());
|
|
|
|
if (!SrcOrError) {
|
|
|
|
LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Src = std::move(*SrcOrError);
|
|
|
|
#else
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
ErrorOr<std::unique_ptr<Module>> Src =
|
|
|
|
llvm::getLazyBitcodeModule(std::move(buf), Dst->getContext());
|
2014-01-27 20:45:48 +00:00
|
|
|
if (!Src) {
|
2014-04-15 14:25:22 +00:00
|
|
|
LLVMRustSetLastError(Src.getError().message().c_str());
|
Implement LTO
This commit implements LTO for rust leveraging LLVM's passes. What this means
is:
* When compiling an rlib, in addition to insdering foo.o into the archive, also
insert foo.bc (the LLVM bytecode) of the optimized module.
* When the compiler detects the -Z lto option, it will attempt to perform LTO on
a staticlib or binary output. The compiler will emit an error if a dylib or
rlib output is being generated.
* The actual act of performing LTO is as follows:
1. Force all upstream libraries to have an rlib version available.
2. Load the bytecode of each upstream library from the rlib.
3. Link all this bytecode into the current LLVM module (just using llvm
apis)
4. Run an internalization pass which internalizes all symbols except those
found reachable for the local crate of compilation.
5. Run the LLVM LTO pass manager over this entire module
6a. If assembling an archive, then add all upstream rlibs into the output
archive. This ignores all of the object/bitcode/metadata files rust
generated and placed inside the rlibs.
6b. If linking a binary, create copies of all upstream rlibs, remove the
rust-generated object-file, and then link everything as usual.
As I have explained in #10741, this process is excruciatingly slow, so this is
*not* turned on by default, and it is also why I have decided to hide it behind
a -Z flag for now. The good news is that the binary sizes are about as small as
they can be as a result of LTO, so it's definitely working.
Closes #10741
Closes #10740
2013-12-03 07:19:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-11-17 14:10:19 +00:00
|
|
|
#endif
|
Implement LTO
This commit implements LTO for rust leveraging LLVM's passes. What this means
is:
* When compiling an rlib, in addition to insdering foo.o into the archive, also
insert foo.bc (the LLVM bytecode) of the optimized module.
* When the compiler detects the -Z lto option, it will attempt to perform LTO on
a staticlib or binary output. The compiler will emit an error if a dylib or
rlib output is being generated.
* The actual act of performing LTO is as follows:
1. Force all upstream libraries to have an rlib version available.
2. Load the bytecode of each upstream library from the rlib.
3. Link all this bytecode into the current LLVM module (just using llvm
apis)
4. Run an internalization pass which internalizes all symbols except those
found reachable for the local crate of compilation.
5. Run the LLVM LTO pass manager over this entire module
6a. If assembling an archive, then add all upstream rlibs into the output
archive. This ignores all of the object/bitcode/metadata files rust
generated and placed inside the rlibs.
6b. If linking a binary, create copies of all upstream rlibs, remove the
rust-generated object-file, and then link everything as usual.
As I have explained in #10741, this process is excruciatingly slow, so this is
*not* turned on by default, and it is also why I have decided to hide it behind
a -Z flag for now. The good news is that the binary sizes are about as small as
they can be as a result of LTO, so it's definitely working.
Closes #10741
Closes #10740
2013-12-03 07:19:29 +00:00
|
|
|
|
2014-01-27 20:45:48 +00:00
|
|
|
std::string Err;
|
2015-01-30 18:25:07 +00:00
|
|
|
|
|
|
|
raw_string_ostream Stream(Err);
|
|
|
|
DiagnosticPrinterRawOStream DP(Stream);
|
2016-11-17 14:10:19 +00:00
|
|
|
#if LLVM_VERSION_GE(4, 0)
|
|
|
|
if (Linker::linkModules(*Dst, std::move(Src))) {
|
|
|
|
#elif LLVM_VERSION_GE(3, 8)
|
2015-10-23 05:07:19 +00:00
|
|
|
if (Linker::linkModules(*Dst, std::move(Src.get()))) {
|
2015-01-30 18:25:07 +00:00
|
|
|
#else
|
2016-06-09 13:41:17 +00:00
|
|
|
if (Linker::LinkModules(Dst, Src->get(), [&](const DiagnosticInfo &DI) { DI.print(DP); })) {
|
2015-01-30 18:25:07 +00:00
|
|
|
#endif
|
2014-04-15 14:25:22 +00:00
|
|
|
LLVMRustSetLastError(Err.c_str());
|
Implement LTO
This commit implements LTO for rust leveraging LLVM's passes. What this means
is:
* When compiling an rlib, in addition to insdering foo.o into the archive, also
insert foo.bc (the LLVM bytecode) of the optimized module.
* When the compiler detects the -Z lto option, it will attempt to perform LTO on
a staticlib or binary output. The compiler will emit an error if a dylib or
rlib output is being generated.
* The actual act of performing LTO is as follows:
1. Force all upstream libraries to have an rlib version available.
2. Load the bytecode of each upstream library from the rlib.
3. Link all this bytecode into the current LLVM module (just using llvm
apis)
4. Run an internalization pass which internalizes all symbols except those
found reachable for the local crate of compilation.
5. Run the LLVM LTO pass manager over this entire module
6a. If assembling an archive, then add all upstream rlibs into the output
archive. This ignores all of the object/bitcode/metadata files rust
generated and placed inside the rlibs.
6b. If linking a binary, create copies of all upstream rlibs, remove the
rust-generated object-file, and then link everything as usual.
As I have explained in #10741, this process is excruciatingly slow, so this is
*not* turned on by default, and it is also why I have decided to hide it behind
a -Z flag for now. The good news is that the binary sizes are about as small as
they can be as a result of LTO, so it's definitely working.
Closes #10741
Closes #10740
2013-12-03 07:19:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2013-12-17 04:58:21 +00:00
|
|
|
|
2014-04-03 17:45:36 +00:00
|
|
|
// Note that the two following functions look quite similar to the
|
|
|
|
// LLVMGetSectionName function. Sadly, it appears that this function only
|
|
|
|
// returns a char* pointer, which isn't guaranteed to be null-terminated. The
|
|
|
|
// function provided by LLVM doesn't return the length, so we've created our own
|
|
|
|
// function which returns the length as well as the data pointer.
|
|
|
|
//
|
|
|
|
// For an example of this not returning a null terminated string, see
|
|
|
|
// lib/Object/COFFObjectFile.cpp in the getSectionName function. One of the
|
|
|
|
// branches explicitly creates a StringRef without a null terminator, and then
|
|
|
|
// that's returned.
|
|
|
|
|
|
|
|
inline section_iterator *unwrap(LLVMSectionIteratorRef SI) {
|
|
|
|
return reinterpret_cast<section_iterator*>(SI);
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" size_t
|
2014-04-03 17:45:36 +00:00
|
|
|
LLVMRustGetSectionName(LLVMSectionIteratorRef SI, const char **ptr) {
|
|
|
|
StringRef ret;
|
2014-06-17 16:34:50 +00:00
|
|
|
if (std::error_code ec = (*unwrap(SI))->getName(ret))
|
2014-04-03 17:45:36 +00:00
|
|
|
report_fatal_error(ec.message());
|
|
|
|
*ptr = ret.data();
|
|
|
|
return ret.size();
|
|
|
|
}
|
2014-05-10 08:30:55 +00:00
|
|
|
|
|
|
|
// LLVMArrayType function does not support 64-bit ElementCount
|
|
|
|
extern "C" LLVMTypeRef
|
|
|
|
LLVMRustArrayType(LLVMTypeRef ElementType, uint64_t ElementCount) {
|
|
|
|
return wrap(ArrayType::get(unwrap(ElementType), ElementCount));
|
|
|
|
}
|
2014-09-12 15:17:58 +00:00
|
|
|
|
|
|
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(Twine, LLVMTwineRef)
|
|
|
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(DebugLoc, LLVMDebugLocRef)
|
|
|
|
|
|
|
|
extern "C" void
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustWriteTwineToString(LLVMTwineRef T, RustStringRef str) {
|
2014-09-12 15:17:58 +00:00
|
|
|
raw_rust_string_ostream os(str);
|
|
|
|
unwrap(T)->print(os);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustUnpackOptimizationDiagnostic(
|
2014-09-12 15:17:58 +00:00
|
|
|
LLVMDiagnosticInfoRef di,
|
2016-11-28 14:15:51 +00:00
|
|
|
RustStringRef pass_name_out,
|
2014-09-12 15:17:58 +00:00
|
|
|
LLVMValueRef *function_out,
|
|
|
|
LLVMDebugLocRef *debugloc_out,
|
2016-11-24 16:33:47 +00:00
|
|
|
RustStringRef message_out)
|
2014-09-12 15:17:58 +00:00
|
|
|
{
|
|
|
|
// Undefined to call this not on an optimization diagnostic!
|
|
|
|
llvm::DiagnosticInfoOptimizationBase *opt
|
|
|
|
= static_cast<llvm::DiagnosticInfoOptimizationBase*>(unwrap(di));
|
|
|
|
|
2016-11-28 14:15:51 +00:00
|
|
|
raw_rust_string_ostream pass_name_os(pass_name_out);
|
|
|
|
pass_name_os << opt->getPassName();
|
2014-09-12 15:17:58 +00:00
|
|
|
*function_out = wrap(&opt->getFunction());
|
|
|
|
*debugloc_out = wrap(&opt->getDebugLoc());
|
2016-11-28 14:15:51 +00:00
|
|
|
raw_rust_string_ostream message_os(message_out);
|
|
|
|
message_os << opt->getMsg();
|
2014-09-12 15:17:58 +00:00
|
|
|
}
|
|
|
|
|
2015-01-22 18:43:39 +00:00
|
|
|
extern "C" void
|
2016-08-01 23:35:09 +00:00
|
|
|
LLVMRustUnpackInlineAsmDiagnostic(
|
2015-01-22 18:43:39 +00:00
|
|
|
LLVMDiagnosticInfoRef di,
|
|
|
|
unsigned *cookie_out,
|
|
|
|
LLVMTwineRef *message_out,
|
|
|
|
LLVMValueRef *instruction_out)
|
|
|
|
{
|
|
|
|
// Undefined to call this not on an inline assembly diagnostic!
|
|
|
|
llvm::DiagnosticInfoInlineAsm *ia
|
|
|
|
= static_cast<llvm::DiagnosticInfoInlineAsm*>(unwrap(di));
|
|
|
|
|
|
|
|
*cookie_out = ia->getLocCookie();
|
|
|
|
*message_out = wrap(&ia->getMsgStr());
|
|
|
|
*instruction_out = wrap(ia->getInstruction());
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustWriteDiagnosticInfoToString(LLVMDiagnosticInfoRef di, RustStringRef str) {
|
2014-09-12 15:17:58 +00:00
|
|
|
raw_rust_string_ostream os(str);
|
|
|
|
DiagnosticPrinterRawOStream dp(os);
|
|
|
|
unwrap(di)->print(dp);
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
enum class LLVMRustDiagnosticKind {
|
|
|
|
Other,
|
|
|
|
InlineAsm,
|
|
|
|
StackSize,
|
|
|
|
DebugMetadataVersion,
|
|
|
|
SampleProfile,
|
|
|
|
OptimizationRemark,
|
|
|
|
OptimizationRemarkMissed,
|
|
|
|
OptimizationRemarkAnalysis,
|
|
|
|
OptimizationRemarkAnalysisFPCommute,
|
|
|
|
OptimizationRemarkAnalysisAliasing,
|
|
|
|
OptimizationRemarkOther,
|
|
|
|
OptimizationFailure,
|
|
|
|
};
|
|
|
|
|
|
|
|
static LLVMRustDiagnosticKind
|
|
|
|
to_rust(DiagnosticKind kind)
|
|
|
|
{
|
|
|
|
switch (kind) {
|
|
|
|
case DK_InlineAsm:
|
|
|
|
return LLVMRustDiagnosticKind::InlineAsm;
|
|
|
|
case DK_StackSize:
|
|
|
|
return LLVMRustDiagnosticKind::StackSize;
|
|
|
|
case DK_DebugMetadataVersion:
|
|
|
|
return LLVMRustDiagnosticKind::DebugMetadataVersion;
|
|
|
|
case DK_SampleProfile:
|
|
|
|
return LLVMRustDiagnosticKind::SampleProfile;
|
|
|
|
case DK_OptimizationRemark:
|
|
|
|
return LLVMRustDiagnosticKind::OptimizationRemark;
|
|
|
|
case DK_OptimizationRemarkMissed:
|
|
|
|
return LLVMRustDiagnosticKind::OptimizationRemarkMissed;
|
|
|
|
case DK_OptimizationRemarkAnalysis:
|
|
|
|
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysis;
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2016-08-01 23:35:09 +00:00
|
|
|
case DK_OptimizationRemarkAnalysisFPCommute:
|
|
|
|
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisFPCommute;
|
|
|
|
case DK_OptimizationRemarkAnalysisAliasing:
|
|
|
|
return LLVMRustDiagnosticKind::OptimizationRemarkAnalysisAliasing;
|
|
|
|
#endif
|
|
|
|
default:
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 9)
|
2016-08-01 23:35:09 +00:00
|
|
|
return (kind >= DK_FirstRemark && kind <= DK_LastRemark) ?
|
|
|
|
LLVMRustDiagnosticKind::OptimizationRemarkOther :
|
|
|
|
LLVMRustDiagnosticKind::Other;
|
|
|
|
#else
|
|
|
|
return LLVMRustDiagnosticKind::Other;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMRustDiagnosticKind LLVMRustGetDiagInfoKind(LLVMDiagnosticInfoRef di) {
|
|
|
|
return to_rust((DiagnosticKind) unwrap(di)->getKind());
|
2014-09-12 15:17:58 +00:00
|
|
|
}
|
2016-08-02 21:25:19 +00:00
|
|
|
// This is kept distinct from LLVMGetTypeKind, because when
|
|
|
|
// a new type kind is added, the Rust-side enum must be
|
|
|
|
// updated or UB will result.
|
|
|
|
extern "C" LLVMTypeKind LLVMRustGetTypeKind(LLVMTypeRef Ty) {
|
|
|
|
switch (unwrap(Ty)->getTypeID()) {
|
|
|
|
case Type::VoidTyID:
|
|
|
|
return LLVMVoidTypeKind;
|
|
|
|
case Type::HalfTyID:
|
|
|
|
return LLVMHalfTypeKind;
|
|
|
|
case Type::FloatTyID:
|
|
|
|
return LLVMFloatTypeKind;
|
|
|
|
case Type::DoubleTyID:
|
|
|
|
return LLVMDoubleTypeKind;
|
|
|
|
case Type::X86_FP80TyID:
|
|
|
|
return LLVMX86_FP80TypeKind;
|
|
|
|
case Type::FP128TyID:
|
|
|
|
return LLVMFP128TypeKind;
|
|
|
|
case Type::PPC_FP128TyID:
|
|
|
|
return LLVMPPC_FP128TypeKind;
|
|
|
|
case Type::LabelTyID:
|
|
|
|
return LLVMLabelTypeKind;
|
|
|
|
case Type::MetadataTyID:
|
|
|
|
return LLVMMetadataTypeKind;
|
|
|
|
case Type::IntegerTyID:
|
|
|
|
return LLVMIntegerTypeKind;
|
|
|
|
case Type::FunctionTyID:
|
|
|
|
return LLVMFunctionTypeKind;
|
|
|
|
case Type::StructTyID:
|
|
|
|
return LLVMStructTypeKind;
|
|
|
|
case Type::ArrayTyID:
|
|
|
|
return LLVMArrayTypeKind;
|
|
|
|
case Type::PointerTyID:
|
|
|
|
return LLVMPointerTypeKind;
|
|
|
|
case Type::VectorTyID:
|
|
|
|
return LLVMVectorTypeKind;
|
|
|
|
case Type::X86_MMXTyID:
|
|
|
|
return LLVMX86_MMXTypeKind;
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2016-08-02 21:25:19 +00:00
|
|
|
case Type::TokenTyID:
|
|
|
|
return LLVMTokenTypeKind;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unhandled TypeID.");
|
|
|
|
}
|
2014-09-12 15:17:58 +00:00
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustWriteDebugLocToString(
|
2014-09-12 15:17:58 +00:00
|
|
|
LLVMContextRef C,
|
|
|
|
LLVMDebugLocRef dl,
|
|
|
|
RustStringRef str)
|
|
|
|
{
|
|
|
|
raw_rust_string_ostream os(str);
|
rustc: Update LLVM
This commit updates the LLVM submodule in use to the current HEAD of the LLVM
repository. This is primarily being done to start picking up unwinding support
for MSVC, which is currently unimplemented in the revision of LLVM we are using.
Along the way a few changes had to be made:
* As usual, lots of C++ debuginfo bindings in LLVM changed, so there were some
significant changes to our RustWrapper.cpp
* As usual, some pass management changed in LLVM, so clang was re-scrutinized to
ensure that we're doing the same thing as clang.
* Some optimization options are now passed directly into the
`PassManagerBuilder` instead of through CLI switches to LLVM.
* The `NoFramePointerElim` option was removed from LLVM, favoring instead the
`no-frame-pointer-elim` function attribute instead.
Additionally, LLVM has picked up some new optimizations which required fixing an
existing soundness hole in the IR we generate. It appears that the current LLVM
we use does not expose this hole. When an enum is moved, the previous slot in
memory is overwritten with a bit pattern corresponding to "dropped". When the
drop glue for this slot is run, however, the switch on the discriminant can
often start executing the `unreachable` block of the switch due to the
discriminant now being outside the normal range. This was patched over locally
for now by having the `unreachable` block just change to a `ret void`.
2015-05-14 19:10:43 +00:00
|
|
|
unwrap(dl)->print(os);
|
2014-09-12 15:17:58 +00:00
|
|
|
}
|
2014-09-27 08:33:36 +00:00
|
|
|
|
|
|
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef)
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustSetInlineAsmDiagnosticHandler(
|
2014-09-27 08:33:36 +00:00
|
|
|
LLVMContextRef C,
|
|
|
|
LLVMContext::InlineAsmDiagHandlerTy H,
|
|
|
|
void *CX)
|
|
|
|
{
|
|
|
|
unwrap(C)->setInlineAsmDiagnosticHandler(H, CX);
|
|
|
|
}
|
|
|
|
|
2016-08-01 23:35:09 +00:00
|
|
|
extern "C" void LLVMRustWriteSMDiagnosticToString(LLVMSMDiagnosticRef d,
|
|
|
|
RustStringRef str) {
|
2014-09-27 08:33:36 +00:00
|
|
|
raw_rust_string_ostream os(str);
|
|
|
|
unwrap(d)->print("", os);
|
|
|
|
}
|
2015-06-30 15:56:56 +00:00
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildLandingPad(LLVMBuilderRef Builder,
|
|
|
|
LLVMTypeRef Ty,
|
|
|
|
LLVMValueRef PersFn,
|
|
|
|
unsigned NumClauses,
|
|
|
|
const char* Name,
|
|
|
|
LLVMValueRef F) {
|
|
|
|
return LLVMBuildLandingPad(Builder, Ty, PersFn, NumClauses, Name);
|
|
|
|
}
|
2015-10-24 01:18:44 +00:00
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCleanupPad(LLVMBuilderRef Builder,
|
|
|
|
LLVMValueRef ParentPad,
|
|
|
|
unsigned ArgCnt,
|
|
|
|
LLVMValueRef *LLArgs,
|
|
|
|
const char *Name) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
Value **Args = unwrap(LLArgs);
|
|
|
|
if (ParentPad == NULL) {
|
|
|
|
Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
|
|
|
|
ParentPad = wrap(Constant::getNullValue(Ty));
|
|
|
|
}
|
|
|
|
return wrap(unwrap(Builder)->CreateCleanupPad(unwrap(ParentPad),
|
|
|
|
ArrayRef<Value*>(Args, ArgCnt),
|
|
|
|
Name));
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCleanupRet(LLVMBuilderRef Builder,
|
|
|
|
LLVMValueRef CleanupPad,
|
|
|
|
LLVMBasicBlockRef UnwindBB) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
CleanupPadInst *Inst = cast<CleanupPadInst>(unwrap(CleanupPad));
|
|
|
|
return wrap(unwrap(Builder)->CreateCleanupRet(Inst, unwrap(UnwindBB)));
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCatchPad(LLVMBuilderRef Builder,
|
|
|
|
LLVMValueRef ParentPad,
|
|
|
|
unsigned ArgCnt,
|
|
|
|
LLVMValueRef *LLArgs,
|
|
|
|
const char *Name) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
Value **Args = unwrap(LLArgs);
|
|
|
|
return wrap(unwrap(Builder)->CreateCatchPad(unwrap(ParentPad),
|
|
|
|
ArrayRef<Value*>(Args, ArgCnt),
|
|
|
|
Name));
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCatchRet(LLVMBuilderRef Builder,
|
|
|
|
LLVMValueRef Pad,
|
|
|
|
LLVMBasicBlockRef BB) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
return wrap(unwrap(Builder)->CreateCatchRet(cast<CatchPadInst>(unwrap(Pad)),
|
|
|
|
unwrap(BB)));
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCatchSwitch(LLVMBuilderRef Builder,
|
|
|
|
LLVMValueRef ParentPad,
|
|
|
|
LLVMBasicBlockRef BB,
|
|
|
|
unsigned NumHandlers,
|
|
|
|
const char *Name) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
if (ParentPad == NULL) {
|
|
|
|
Type *Ty = Type::getTokenTy(unwrap(Builder)->getContext());
|
|
|
|
ParentPad = wrap(Constant::getNullValue(Ty));
|
|
|
|
}
|
|
|
|
return wrap(unwrap(Builder)->CreateCatchSwitch(unwrap(ParentPad),
|
|
|
|
unwrap(BB),
|
|
|
|
NumHandlers,
|
|
|
|
Name));
|
|
|
|
#else
|
|
|
|
return NULL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
LLVMRustAddHandler(LLVMValueRef CatchSwitchRef,
|
|
|
|
LLVMBasicBlockRef Handler) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
Value *CatchSwitch = unwrap(CatchSwitchRef);
|
|
|
|
cast<CatchSwitchInst>(CatchSwitch)->addHandler(unwrap(Handler));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
LLVMRustSetPersonalityFn(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef Personality) {
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
unwrap(B)->GetInsertBlock()
|
|
|
|
->getParent()
|
|
|
|
->setPersonalityFn(cast<Function>(unwrap(Personality)));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-09-24 14:44:21 +00:00
|
|
|
#if LLVM_VERSION_GE(3, 8)
|
2015-10-24 01:18:44 +00:00
|
|
|
extern "C" OperandBundleDef*
|
|
|
|
LLVMRustBuildOperandBundleDef(const char *Name,
|
|
|
|
LLVMValueRef *Inputs,
|
|
|
|
unsigned NumInputs) {
|
|
|
|
return new OperandBundleDef(Name, makeArrayRef(unwrap(Inputs), NumInputs));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
LLVMRustFreeOperandBundleDef(OperandBundleDef* Bundle) {
|
|
|
|
delete Bundle;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCall(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args,
|
|
|
|
unsigned NumArgs,
|
|
|
|
OperandBundleDef *Bundle,
|
|
|
|
const char *Name) {
|
|
|
|
unsigned len = Bundle ? 1 : 0;
|
|
|
|
ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
|
|
|
|
return wrap(unwrap(B)->CreateCall(unwrap(Fn),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs),
|
|
|
|
Bundles,
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildInvoke(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args,
|
|
|
|
unsigned NumArgs,
|
|
|
|
LLVMBasicBlockRef Then,
|
|
|
|
LLVMBasicBlockRef Catch,
|
|
|
|
OperandBundleDef *Bundle,
|
|
|
|
const char *Name) {
|
|
|
|
unsigned len = Bundle ? 1 : 0;
|
|
|
|
ArrayRef<OperandBundleDef> Bundles = makeArrayRef(Bundle, len);
|
|
|
|
return wrap(unwrap(B)->CreateInvoke(unwrap(Fn), unwrap(Then), unwrap(Catch),
|
|
|
|
makeArrayRef(unwrap(Args), NumArgs),
|
|
|
|
Bundles,
|
|
|
|
Name));
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
extern "C" void*
|
|
|
|
LLVMRustBuildOperandBundleDef(const char *Name,
|
|
|
|
LLVMValueRef *Inputs,
|
|
|
|
unsigned NumInputs) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void
|
|
|
|
LLVMRustFreeOperandBundleDef(void* Bundle) {
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildCall(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args,
|
|
|
|
unsigned NumArgs,
|
|
|
|
void *Bundle,
|
|
|
|
const char *Name) {
|
|
|
|
return LLVMBuildCall(B, Fn, Args, NumArgs, Name);
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMValueRef
|
|
|
|
LLVMRustBuildInvoke(LLVMBuilderRef B,
|
|
|
|
LLVMValueRef Fn,
|
|
|
|
LLVMValueRef *Args,
|
|
|
|
unsigned NumArgs,
|
|
|
|
LLVMBasicBlockRef Then,
|
|
|
|
LLVMBasicBlockRef Catch,
|
|
|
|
void *Bundle,
|
|
|
|
const char *Name) {
|
|
|
|
return LLVMBuildInvoke(B, Fn, Args, NumArgs, Then, Catch, Name);
|
|
|
|
}
|
|
|
|
#endif
|
2016-02-04 17:40:28 +00:00
|
|
|
|
|
|
|
extern "C" void LLVMRustPositionBuilderAtStart(LLVMBuilderRef B, LLVMBasicBlockRef BB) {
|
|
|
|
auto point = unwrap(BB)->getFirstInsertionPt();
|
|
|
|
unwrap(B)->SetInsertPoint(unwrap(BB), point);
|
|
|
|
}
|
2016-03-28 15:57:31 +00:00
|
|
|
|
|
|
|
extern "C" void LLVMRustSetComdat(LLVMModuleRef M, LLVMValueRef V, const char *Name) {
|
|
|
|
Triple TargetTriple(unwrap(M)->getTargetTriple());
|
|
|
|
GlobalObject *GV = unwrap<GlobalObject>(V);
|
|
|
|
if (!TargetTriple.isOSBinFormatMachO()) {
|
|
|
|
GV->setComdat(unwrap(M)->getOrInsertComdat(Name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void LLVMRustUnsetComdat(LLVMValueRef V) {
|
|
|
|
GlobalObject *GV = unwrap<GlobalObject>(V);
|
|
|
|
GV->setComdat(nullptr);
|
|
|
|
}
|
2016-09-01 18:52:33 +00:00
|
|
|
|
|
|
|
enum class LLVMRustLinkage {
|
|
|
|
ExternalLinkage = 0,
|
|
|
|
AvailableExternallyLinkage = 1,
|
|
|
|
LinkOnceAnyLinkage = 2,
|
|
|
|
LinkOnceODRLinkage = 3,
|
|
|
|
WeakAnyLinkage = 4,
|
|
|
|
WeakODRLinkage = 5,
|
|
|
|
AppendingLinkage = 6,
|
|
|
|
InternalLinkage = 7,
|
|
|
|
PrivateLinkage = 8,
|
|
|
|
ExternalWeakLinkage = 9,
|
|
|
|
CommonLinkage = 10,
|
|
|
|
};
|
|
|
|
|
|
|
|
static LLVMRustLinkage to_rust(LLVMLinkage linkage) {
|
|
|
|
switch (linkage) {
|
|
|
|
case LLVMExternalLinkage:
|
|
|
|
return LLVMRustLinkage::ExternalLinkage;
|
|
|
|
case LLVMAvailableExternallyLinkage:
|
|
|
|
return LLVMRustLinkage::AvailableExternallyLinkage;
|
|
|
|
case LLVMLinkOnceAnyLinkage:
|
|
|
|
return LLVMRustLinkage::LinkOnceAnyLinkage;
|
|
|
|
case LLVMLinkOnceODRLinkage:
|
|
|
|
return LLVMRustLinkage::LinkOnceODRLinkage;
|
|
|
|
case LLVMWeakAnyLinkage:
|
|
|
|
return LLVMRustLinkage::WeakAnyLinkage;
|
|
|
|
case LLVMWeakODRLinkage:
|
|
|
|
return LLVMRustLinkage::WeakODRLinkage;
|
|
|
|
case LLVMAppendingLinkage:
|
|
|
|
return LLVMRustLinkage::AppendingLinkage;
|
|
|
|
case LLVMInternalLinkage:
|
|
|
|
return LLVMRustLinkage::InternalLinkage;
|
|
|
|
case LLVMPrivateLinkage:
|
|
|
|
return LLVMRustLinkage::PrivateLinkage;
|
|
|
|
case LLVMExternalWeakLinkage:
|
|
|
|
return LLVMRustLinkage::ExternalWeakLinkage;
|
|
|
|
case LLVMCommonLinkage:
|
|
|
|
return LLVMRustLinkage::CommonLinkage;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Invalid LLVMRustLinkage value!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static LLVMLinkage from_rust(LLVMRustLinkage linkage) {
|
|
|
|
switch (linkage) {
|
|
|
|
case LLVMRustLinkage::ExternalLinkage:
|
|
|
|
return LLVMExternalLinkage;
|
|
|
|
case LLVMRustLinkage::AvailableExternallyLinkage:
|
|
|
|
return LLVMAvailableExternallyLinkage;
|
|
|
|
case LLVMRustLinkage::LinkOnceAnyLinkage:
|
|
|
|
return LLVMLinkOnceAnyLinkage;
|
|
|
|
case LLVMRustLinkage::LinkOnceODRLinkage:
|
|
|
|
return LLVMLinkOnceODRLinkage;
|
|
|
|
case LLVMRustLinkage::WeakAnyLinkage:
|
|
|
|
return LLVMWeakAnyLinkage;
|
|
|
|
case LLVMRustLinkage::WeakODRLinkage:
|
|
|
|
return LLVMWeakODRLinkage;
|
|
|
|
case LLVMRustLinkage::AppendingLinkage:
|
|
|
|
return LLVMAppendingLinkage;
|
|
|
|
case LLVMRustLinkage::InternalLinkage:
|
|
|
|
return LLVMInternalLinkage;
|
|
|
|
case LLVMRustLinkage::PrivateLinkage:
|
|
|
|
return LLVMPrivateLinkage;
|
|
|
|
case LLVMRustLinkage::ExternalWeakLinkage:
|
|
|
|
return LLVMExternalWeakLinkage;
|
|
|
|
case LLVMRustLinkage::CommonLinkage:
|
|
|
|
return LLVMCommonLinkage;
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Invalid LLVMRustLinkage value!");
|
2016-10-14 18:53:17 +00:00
|
|
|
}
|
2016-09-01 18:52:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMRustLinkage LLVMRustGetLinkage(LLVMValueRef V) {
|
|
|
|
return to_rust(LLVMGetLinkage(V));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void LLVMRustSetLinkage(LLVMValueRef V, LLVMRustLinkage RustLinkage) {
|
|
|
|
LLVMSetLinkage(V, from_rust(RustLinkage));
|
|
|
|
}
|
2016-11-16 22:36:08 +00:00
|
|
|
|
|
|
|
extern "C" LLVMContextRef LLVMRustGetValueContext(LLVMValueRef V) {
|
|
|
|
return wrap(&unwrap(V)->getContext());
|
|
|
|
}
|
2016-11-28 22:44:51 +00:00
|
|
|
|
|
|
|
enum class LLVMRustVisibility {
|
|
|
|
Default = 0,
|
|
|
|
Hidden = 1,
|
|
|
|
Protected = 2,
|
|
|
|
};
|
|
|
|
|
|
|
|
static LLVMRustVisibility to_rust(LLVMVisibility vis) {
|
|
|
|
switch (vis) {
|
|
|
|
case LLVMDefaultVisibility:
|
|
|
|
return LLVMRustVisibility::Default;
|
|
|
|
case LLVMHiddenVisibility:
|
|
|
|
return LLVMRustVisibility::Hidden;
|
|
|
|
case LLVMProtectedVisibility:
|
|
|
|
return LLVMRustVisibility::Protected;
|
|
|
|
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Invalid LLVMRustVisibility value!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static LLVMVisibility from_rust(LLVMRustVisibility vis) {
|
|
|
|
switch (vis) {
|
|
|
|
case LLVMRustVisibility::Default:
|
|
|
|
return LLVMDefaultVisibility;
|
|
|
|
case LLVMRustVisibility::Hidden:
|
|
|
|
return LLVMHiddenVisibility;
|
|
|
|
case LLVMRustVisibility::Protected:
|
|
|
|
return LLVMProtectedVisibility;
|
|
|
|
|
|
|
|
default:
|
|
|
|
llvm_unreachable("Invalid LLVMRustVisibility value!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" LLVMRustVisibility LLVMRustGetVisibility(LLVMValueRef V) {
|
|
|
|
return to_rust(LLVMGetVisibility(V));
|
|
|
|
}
|
|
|
|
|
|
|
|
extern "C" void LLVMRustSetVisibility(LLVMValueRef V, LLVMRustVisibility RustVisibility) {
|
|
|
|
LLVMSetVisibility(V, from_rust(RustVisibility));
|
|
|
|
}
|