提交 f76e28aa 编写于 作者: J Jed Davis

Allow consts' LLVM types to depend on their initializers.

Loosening the connection between the LLVM type and the Rust type
is necessary to use non-nullary enum constructors as const initializers,
because the const needs to be initialized with data of the actual type of
the variant in question, which is (generally) not the same as the u8
array in the `type_of` type.

Thus, referring to a const now requires casting the LLVM global to the
expected pointer type instead of using it as-is.
上级 45264242
......@@ -2308,16 +2308,21 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
let my_path = vec::append(/*bad*/copy *pth,
~[path_name(i.ident)]);
match i.node {
ast::item_const(_, _) => {
ast::item_const(_, expr) => {
let typ = ty::node_id_to_type(ccx.tcx, i.id);
let s = mangle_exported_name(ccx, my_path, typ);
let g = str::as_c_str(s, |buf| {
unsafe {
llvm::LLVMAddGlobal(ccx.llmod, type_of(ccx, typ), buf)
}
});
ccx.item_symbols.insert(i.id, s);
g
// We need the translated value here, because for enums the
// LLVM type is not fully determined by the Rust type.
let v = consts::const_expr(ccx, expr);
ccx.const_values.insert(id, v);
unsafe {
let llty = llvm::LLVMTypeOf(v);
let g = str::as_c_str(s, |buf| {
llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
});
ccx.item_symbols.insert(i.id, s);
g
}
}
ast::item_fn(_, purity, _, _) => {
let llfn = if purity != ast::extern_fn {
......
......@@ -464,12 +464,13 @@ fn const_expr(cx: @crate_ctxt, e: @ast::expr) -> ValueRef {
}
}
fn trans_const(ccx: @crate_ctxt, e: @ast::expr, id: ast::node_id) {
fn trans_const(ccx: @crate_ctxt, _e: @ast::expr, id: ast::node_id) {
unsafe {
let _icx = ccx.insn_ctxt("trans_const");
let g = base::get_item_val(ccx, id);
let v = const_expr(ccx, e);
ccx.const_values.insert(id, v);
// At this point, get_item_val has already translated the
// constant's initializer to determine its LLVM type.
let v = ccx.const_values.get(id);
llvm::LLVMSetInitializer(g, v);
llvm::LLVMSetGlobalConstant(g, True);
}
......
......@@ -798,7 +798,11 @@ fn trans_def_lvalue(bcx: block,
ast::def_const(did) => {
let const_ty = expr_ty(bcx, ref_expr);
let val = if did.crate == ast::local_crate {
base::get_item_val(ccx, did.node)
// The LLVM global has the type of its initializer,
// which may not be equal to the enum's type for
// non-C-like enums.
PointerCast(bcx, base::get_item_val(ccx, did.node),
T_ptr(type_of(bcx.ccx(), const_ty)))
} else {
base::trans_external_path(ccx, did, const_ty)
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册