[LLVM] Introduce a stable representation of DIFlags

In LLVM 4.0, this enum becomes an actual type-safe enum, which breaks
all of the interfaces. Introduce our own copy of the bitflags that we
can then safely convert to the LLVM one.
This commit is contained in:
Jake Goulding 2016-11-18 17:15:14 -05:00
parent c80c31a502
commit dbdd60e6d7
8 changed files with 172 additions and 60 deletions

1
src/Cargo.lock generated
View File

@ -403,6 +403,7 @@ version = "0.0.0"
dependencies = [
"build_helper 0.1.0",
"gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_bitflags 0.0.0",
]
[[package]]

22
src/librustc_llvm/Cargo.lock generated Normal file
View File

@ -0,0 +1,22 @@
[root]
name = "rustc_llvm"
version = "0.0.0"
dependencies = [
"build_helper 0.1.0",
"gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_bitflags 0.0.0",
]
[[package]]
name = "build_helper"
version = "0.1.0"
[[package]]
name = "gcc"
version = "0.3.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc_bitflags"
version = "0.0.0"

View File

@ -12,6 +12,9 @@ crate-type = ["dylib"]
[features]
static-libstdcpp = []
[dependencies]
rustc_bitflags = { path = "../librustc_bitflags" }
[build-dependencies]
build_helper = { path = "../build_helper" }
gcc = "0.3.27"

View File

@ -11,7 +11,7 @@
use debuginfo::{DIBuilderRef, DIDescriptor, DIFile, DILexicalBlock, DISubprogram, DIType,
DIBasicType, DIDerivedType, DICompositeType, DIScope, DIVariable,
DIGlobalVariable, DIArray, DISubrange, DITemplateTypeParameter, DIEnumerator,
DINameSpace};
DINameSpace, DIFlags};
use libc::{c_uint, c_int, size_t, c_char};
use libc::{c_longlong, c_ulonglong, c_void};
@ -408,7 +408,6 @@ pub enum Visibility {
}
pub mod debuginfo {
pub use self::DIDescriptorFlags::*;
use super::MetadataRef;
#[allow(missing_copy_implementations)]
@ -433,24 +432,29 @@ pub mod debuginfo {
pub type DIEnumerator = DIDescriptor;
pub type DITemplateTypeParameter = DIDescriptor;
#[derive(Copy, Clone)]
pub enum DIDescriptorFlags {
FlagPrivate = 1 << 0,
FlagProtected = 1 << 1,
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,
FlagIndirectVariable = 1 << 13,
FlagLValueReference = 1 << 14,
FlagRValueReference = 1 << 15,
// These values **must** match with LLVMRustDIFlags!!
bitflags! {
#[repr(C)]
#[derive(Debug, Default)]
flags DIFlags: ::libc::uint32_t {
const FlagZero = 0,
const FlagPrivate = 1,
const FlagProtected = 2,
const FlagPublic = 3,
const FlagFwdDecl = (1 << 2),
const FlagAppleBlock = (1 << 3),
const FlagBlockByrefStruct = (1 << 4),
const FlagVirtual = (1 << 5),
const FlagArtificial = (1 << 6),
const FlagExplicit = (1 << 7),
const FlagPrototyped = (1 << 8),
const FlagObjcClassComplete = (1 << 9),
const FlagObjectPointer = (1 << 10),
const FlagVector = (1 << 11),
const FlagStaticMember = (1 << 12),
const FlagLValueReference = (1 << 13),
const FlagRValueReference = (1 << 14),
}
}
}
@ -1567,7 +1571,7 @@ extern "C" {
isLocalToUnit: bool,
isDefinition: bool,
ScopeLine: c_uint,
Flags: c_uint,
Flags: DIFlags,
isOptimized: bool,
Fn: ValueRef,
TParam: DIArray,
@ -1595,7 +1599,7 @@ extern "C" {
LineNumber: c_uint,
SizeInBits: u64,
AlignInBits: u64,
Flags: c_uint,
Flags: DIFlags,
DerivedFrom: DIType,
Elements: DIArray,
RunTimeLang: c_uint,
@ -1611,7 +1615,7 @@ extern "C" {
SizeInBits: u64,
AlignInBits: u64,
OffsetInBits: u64,
Flags: c_uint,
Flags: DIFlags,
Ty: DIType)
-> DIDerivedType;
@ -1647,7 +1651,7 @@ extern "C" {
LineNo: c_uint,
Ty: DIType,
AlwaysPreserve: bool,
Flags: c_uint,
Flags: DIFlags,
ArgNo: c_uint)
-> DIVariable;
@ -1707,7 +1711,7 @@ extern "C" {
LineNumber: c_uint,
SizeInBits: u64,
AlignInBits: u64,
Flags: c_uint,
Flags: DIFlags,
Elements: DIArray,
RunTimeLang: c_uint,
UniqueId: *const c_char)

View File

@ -29,8 +29,12 @@
#![feature(link_args)]
#![feature(linked_from)]
#![feature(staged_api)]
#![cfg_attr(not(stage0), feature(rustc_private))]
extern crate libc;
#[macro_use]
#[no_link]
extern crate rustc_bitflags;
pub use self::IntPredicate::*;
pub use self::RealPredicate::*;

View File

@ -22,7 +22,8 @@ use context::SharedCrateContext;
use session::Session;
use llvm::{self, ValueRef};
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType, DILexicalBlock};
use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor,
DICompositeType, DILexicalBlock, DIFlags};
use rustc::hir::def::CtorKind;
use rustc::hir::def_id::DefId;
@ -69,8 +70,6 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
// ptr::null() doesn't work :(
pub const NO_SCOPE_METADATA: DIScope = (0 as DIScope);
const FLAGS_NONE: c_uint = 0;
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
pub struct UniqueTypeId(ast::Name);
@ -347,14 +346,14 @@ fn vec_slice_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
llvm_type: member_llvm_types[0],
type_metadata: element_type_metadata,
offset: ComputedMemberOffset,
flags: FLAGS_NONE
flags: DIFlags::FlagZero,
},
MemberDescription {
name: "length".to_string(),
llvm_type: member_llvm_types[1],
type_metadata: type_metadata(cx, cx.tcx().types.usize, span),
offset: ComputedMemberOffset,
flags: FLAGS_NONE
flags: DIFlags::FlagZero,
},
];
@ -838,7 +837,7 @@ struct MemberDescription {
llvm_type: Type,
type_metadata: DIType,
offset: MemberOffset,
flags: c_uint
flags: DIFlags,
}
// A factory for MemberDescriptions. It produces a list of member descriptions
@ -922,7 +921,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
llvm_type: type_of::type_of(cx, fty),
type_metadata: type_metadata(cx, fty, self.span),
offset: offset,
flags: FLAGS_NONE,
flags: DIFlags::FlagZero,
}
}).collect()
}
@ -987,7 +986,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
llvm_type: type_of::type_of(cx, component_type),
type_metadata: type_metadata(cx, component_type, self.span),
offset: ComputedMemberOffset,
flags: FLAGS_NONE,
flags: DIFlags::FlagZero,
}
}).collect()
}
@ -1039,7 +1038,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
llvm_type: type_of::type_of(cx, fty),
type_metadata: type_metadata(cx, fty, self.span),
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE,
flags: DIFlags::FlagZero,
}
}).collect()
}
@ -1137,7 +1136,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
llvm_type: variant_llvm_type,
type_metadata: variant_type_metadata,
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE
flags: DIFlags::FlagZero
}
}).collect()
},
@ -1171,7 +1170,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
llvm_type: variant_llvm_type,
type_metadata: variant_type_metadata,
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE
flags: DIFlags::FlagZero
}
]
}
@ -1208,7 +1207,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
llvm_type: non_null_llvm_type,
type_metadata: non_null_type_metadata,
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE
flags: DIFlags::FlagZero
};
let unique_type_id = debug_context(cx).type_map
@ -1245,7 +1244,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
llvm_type: artificial_struct_llvm_type,
type_metadata: artificial_struct_metadata,
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE
flags: DIFlags::FlagZero
}
]
},
@ -1289,7 +1288,7 @@ impl<'tcx> EnumMemberDescriptionFactory<'tcx> {
llvm_type: variant_llvm_type,
type_metadata: variant_type_metadata,
offset: FixedMemberOffset { bytes: 0 },
flags: FLAGS_NONE
flags: DIFlags::FlagZero
}
]
},
@ -1318,7 +1317,7 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
_ => type_metadata(cx, ty, self.span)
},
offset: ComputedMemberOffset,
flags: FLAGS_NONE
flags: DIFlags::FlagZero
}
}).collect()
}
@ -1535,7 +1534,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
UNKNOWN_LINE_NUMBER,
bytes_to_bits(enum_type_size),
bytes_to_bits(enum_type_align),
0, // Flags
DIFlags::FlagZero,
ptr::null_mut(),
0, // RuntimeLang
unique_type_id_str.as_ptr())
@ -1680,7 +1679,7 @@ fn create_struct_stub(cx: &CrateContext,
UNKNOWN_LINE_NUMBER,
bytes_to_bits(struct_size),
bytes_to_bits(struct_align),
0,
DIFlags::FlagZero,
ptr::null_mut(),
empty_array,
0,
@ -1717,7 +1716,7 @@ fn create_union_stub(cx: &CrateContext,
UNKNOWN_LINE_NUMBER,
bytes_to_bits(union_size),
bytes_to_bits(union_align),
0, // Flags
DIFlags::FlagZero,
empty_array,
0, // RuntimeLang
unique_type_id.as_ptr())

View File

@ -22,8 +22,7 @@ use self::source_loc::InternalDebugLocation::{self, UnknownLocation};
use llvm;
use llvm::{ModuleRef, ContextRef, ValueRef};
use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray,
FlagPrototyped};
use llvm::debuginfo::{DIFile, DIType, DIScope, DIBuilderRef, DISubprogram, DIArray, DIFlags};
use rustc::hir::def_id::DefId;
use rustc::ty::subst::Substs;
@ -286,7 +285,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
is_local_to_unit,
true,
scope_line as c_uint,
FlagPrototyped as c_uint,
DIFlags::FlagPrototyped,
cx.sess().opts.optimize != config::OptLevel::No,
llfn,
template_parameters,
@ -478,7 +477,7 @@ pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
loc.line as c_uint,
type_metadata,
cx.sess().opts.optimize != config::OptLevel::No,
0,
DIFlags::FlagZero,
argument_index)
};
source_loc::set_debug_location(cx, None,

View File

@ -352,6 +352,86 @@ DIT* unwrapDIptr(LLVMRustMetadataRef ref) {
#define DIArray DINodeArray
#define unwrapDI unwrapDIptr
// 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);
}
static unsigned from_rust(LLVMRustDIFlags flags) {
unsigned result = 0;
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;
}
extern "C" uint32_t LLVMRustDebugMetadataVersion() {
return DEBUG_METADATA_VERSION;
}
@ -431,7 +511,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
bool isLocalToUnit,
bool isDefinition,
unsigned ScopeLine,
unsigned Flags,
LLVMRustDIFlags Flags,
bool isOptimized,
LLVMValueRef Fn,
LLVMRustMetadataRef TParam,
@ -443,7 +523,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
unwrapDI<DIScope>(Scope), Name, LinkageName,
unwrapDI<DIFile>(File), LineNo,
unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
Flags, isOptimized,
from_rust(Flags), isOptimized,
TParams,
unwrapDIptr<DISubprogram>(Decl));
unwrap<Function>(Fn)->setSubprogram(Sub);
@ -453,7 +533,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateFunction(
unwrapDI<DIScope>(Scope), Name, LinkageName,
unwrapDI<DIFile>(File), LineNo,
unwrapDI<DISubroutineType>(Ty), isLocalToUnit, isDefinition, ScopeLine,
Flags, isOptimized,
from_rust(Flags), isOptimized,
unwrap<Function>(Fn),
unwrapDIptr<MDNode>(TParam),
unwrapDIptr<MDNode>(Decl)));
@ -489,7 +569,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
unsigned Flags,
LLVMRustDIFlags Flags,
LLVMRustMetadataRef DerivedFrom,
LLVMRustMetadataRef Elements,
unsigned RunTimeLang,
@ -502,7 +582,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateStructType(
LineNumber,
SizeInBits,
AlignInBits,
Flags,
from_rust(Flags),
unwrapDI<DIType>(DerivedFrom),
DINodeArray(unwrapDI<MDTuple>(Elements)),
RunTimeLang,
@ -520,12 +600,12 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateMemberType(
uint64_t SizeInBits,
uint64_t AlignInBits,
uint64_t OffsetInBits,
unsigned Flags,
LLVMRustDIFlags Flags,
LLVMRustMetadataRef Ty) {
return wrap(Builder->createMemberType(
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File), LineNo,
SizeInBits, AlignInBits, OffsetInBits, Flags,
SizeInBits, AlignInBits, OffsetInBits, from_rust(Flags),
unwrapDI<DIType>(Ty)));
}
@ -581,7 +661,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
unsigned LineNo,
LLVMRustMetadataRef Ty,
bool AlwaysPreserve,
unsigned Flags,
LLVMRustDIFlags Flags,
unsigned ArgNo) {
#if LLVM_VERSION_GE(3, 8)
if (Tag == 0x100) { // DW_TAG_auto_variable
@ -589,20 +669,20 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateVariable(
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File),
LineNo,
unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags)));
} else {
return wrap(Builder->createParameterVariable(
unwrapDI<DIDescriptor>(Scope), Name, ArgNo,
unwrapDI<DIFile>(File),
LineNo,
unwrapDI<DIType>(Ty), AlwaysPreserve, Flags));
unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags)));
}
#else
return wrap(Builder->createLocalVariable(Tag,
unwrapDI<DIDescriptor>(Scope), Name,
unwrapDI<DIFile>(File),
LineNo,
unwrapDI<DIType>(Ty), AlwaysPreserve, Flags, ArgNo));
unwrapDI<DIType>(Ty), AlwaysPreserve, from_rust(Flags), ArgNo));
#endif
}
@ -701,7 +781,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
unsigned LineNumber,
uint64_t SizeInBits,
uint64_t AlignInBits,
unsigned Flags,
LLVMRustDIFlags Flags,
LLVMRustMetadataRef Elements,
unsigned RunTimeLang,
const char* UniqueId)
@ -713,7 +793,7 @@ extern "C" LLVMRustMetadataRef LLVMRustDIBuilderCreateUnionType(
LineNumber,
SizeInBits,
AlignInBits,
Flags,
from_rust(Flags),
DINodeArray(unwrapDI<MDTuple>(Elements)),
RunTimeLang,
UniqueId