1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
14 use lib::llvm::{ContextRef, ModuleRef, ValueRef};
15 use lib::llvm::{llvm, TargetData, TypeNames};
16 use lib::llvm::{mk_target_data};
17 use metadata::common::LinkMeta;
18 use middle::astencode;
20 use middle::trans::adt;
21 use middle::trans::base;
22 use middle::trans::builder::Builder;
23 use middle::trans::debuginfo;
24 use middle::trans::type_use;
27 use middle::trans::type_::Type;
30 use std::hashmap::{HashMap, HashSet};
35 use middle::trans::common::{mono_id,ExternMap,tydesc_info,BuilderRef_res,Stats};
37 use middle::trans::base::{decl_crate_map};
39 pub struct CrateContext {
40 sess: session::Session,
46 intrinsics: HashMap<&'static str, ValueRef>,
47 item_vals: HashMap<ast::node_id, ValueRef>,
48 exp_map2: resolve::ExportMap2,
49 reachable: @mut HashSet<ast::node_id>,
50 item_symbols: HashMap<ast::node_id, ~str>,
52 enum_sizes: HashMap<ty::t, uint>,
53 discrims: HashMap<ast::def_id, ValueRef>,
54 discrim_symbols: HashMap<ast::node_id, @str>,
55 tydescs: HashMap<ty::t, @mut tydesc_info>,
56 // Set when running emit_tydescs to enforce that no more tydescs are
58 finished_tydescs: bool,
59 // Track mapping of external ids to local items imported for inlining
60 external: HashMap<ast::def_id, Option<ast::node_id>>,
61 // Cache instances of monomorphized functions
62 monomorphized: HashMap<mono_id, ValueRef>,
63 monomorphizing: HashMap<ast::def_id, uint>,
64 // Cache computed type parameter uses (see type_use.rs)
65 type_use_cache: HashMap<ast::def_id, @~[type_use::type_uses]>,
66 // Cache generated vtables
67 vtables: HashMap<mono_id, ValueRef>,
68 // Cache of constant strings,
69 const_cstr_cache: HashMap<@str, ValueRef>,
71 // Reverse-direction for const ptrs cast from globals.
72 // Key is an int, cast from a ValueRef holding a *T,
73 // Val is a ValueRef holding a *[T].
75 // Needed because LLVM loses pointer->pointee association
76 // when we ptrcast, and we have to ptrcast during translation
77 // of a [T] const because we form a slice, a [*T,int] pair, not
78 // a pointer to an LLVM array type.
79 const_globals: HashMap<int, ValueRef>,
81 // Cache of emitted const values
82 const_values: HashMap<ast::node_id, ValueRef>,
84 // Cache of external const values
85 extern_const_values: HashMap<ast::def_id, ValueRef>,
87 impl_method_cache: HashMap<(ast::def_id, ast::ident), ast::def_id>,
89 module_data: HashMap<~str, ValueRef>,
90 lltypes: HashMap<ty::t, Type>,
91 llsizingtypes: HashMap<ty::t, Type>,
92 adt_reprs: HashMap<ty::t, @adt::Repr>,
93 symbol_hasher: hash::State,
94 type_hashcodes: HashMap<ty::t, @str>,
95 type_short_names: HashMap<ty::t, ~str>,
96 all_llvm_symbols: HashSet<@str>,
98 maps: astencode::Maps,
100 upcalls: @upcall::Upcalls,
104 opaque_vec_type: Type,
105 builder: BuilderRef_res,
107 // Set when at least one function uses GC. Needed so that
108 // decl_gc_metadata knows whether to link to the module metadata, which
109 // is not emitted by LLVM's GC pass when no functions use GC.
111 dbg_cx: Option<debuginfo::DebugContext>,
112 do_not_commit_warning_issued: bool
116 pub fn new(sess: session::Session,
119 emap2: resolve::ExportMap2,
120 maps: astencode::Maps,
121 symbol_hasher: hash::State,
123 reachable: @mut HashSet<ast::node_id>)
126 let llcx = llvm::LLVMContextCreate();
128 let llmod = str::as_c_str(name, |buf| {
129 llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
131 let data_layout: &str = sess.targ_cfg.target_strs.data_layout;
132 let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
133 str::as_c_str(data_layout, |buf| llvm::LLVMSetDataLayout(llmod, buf));
134 str::as_c_str(targ_triple, |buf| llvm::LLVMSetTarget(llmod, buf));
135 let targ_cfg = sess.targ_cfg;
137 let td = mk_target_data(sess.targ_cfg.target_strs.data_layout);
138 let mut tn = TypeNames::new();
140 let mut intrinsics = base::declare_intrinsics(llmod);
141 if sess.opts.extra_debuginfo {
142 base::declare_dbg_intrinsics(llmod, &mut intrinsics);
144 let int_type = Type::int(targ_cfg.arch);
145 let float_type = Type::float(targ_cfg.arch);
146 let tydesc_type = Type::tydesc(targ_cfg.arch);
147 let opaque_vec_type = Type::opaque_vec(targ_cfg.arch);
149 let mut str_slice_ty = Type::named_struct("str_slice");
150 str_slice_ty.set_struct_body([Type::i8p(), int_type], false);
152 tn.associate_type("tydesc", &tydesc_type);
153 tn.associate_type("str_slice", &str_slice_ty);
155 let crate_map = decl_crate_map(sess, link_meta, llmod);
156 let dbg_cx = if sess.opts.debuginfo {
157 Some(debuginfo::DebugContext::new(llmod, name.to_owned()))
162 if sess.count_llvm_insns() {
163 base::init_insn_ctxt()
172 externs: HashMap::new(),
173 intrinsics: intrinsics,
174 item_vals: HashMap::new(),
176 reachable: reachable,
177 item_symbols: HashMap::new(),
178 link_meta: link_meta,
179 enum_sizes: HashMap::new(),
180 discrims: HashMap::new(),
181 discrim_symbols: HashMap::new(),
182 tydescs: HashMap::new(),
183 finished_tydescs: false,
184 external: HashMap::new(),
185 monomorphized: HashMap::new(),
186 monomorphizing: HashMap::new(),
187 type_use_cache: HashMap::new(),
188 vtables: HashMap::new(),
189 const_cstr_cache: HashMap::new(),
190 const_globals: HashMap::new(),
191 const_values: HashMap::new(),
192 extern_const_values: HashMap::new(),
193 impl_method_cache: HashMap::new(),
194 module_data: HashMap::new(),
195 lltypes: HashMap::new(),
196 llsizingtypes: HashMap::new(),
197 adt_reprs: HashMap::new(),
198 symbol_hasher: symbol_hasher,
199 type_hashcodes: HashMap::new(),
200 type_short_names: HashMap::new(),
201 all_llvm_symbols: HashSet::new(),
205 n_static_tydescs: 0u,
215 llvm_insns: HashMap::new(),
218 upcalls: upcall::declare_upcalls(targ_cfg, llmod),
219 tydesc_type: tydesc_type,
221 float_type: float_type,
222 opaque_vec_type: opaque_vec_type,
223 builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)),
224 crate_map: crate_map,
227 do_not_commit_warning_issued: false
232 pub fn builder(@mut self) -> Builder {
238 impl Drop for CrateContext {
244 static task_local_llcx_key: local_data::Key<@ContextRef> = &local_data::Key;
246 pub fn task_llcx() -> ContextRef {
247 let opt = local_data::get(task_local_llcx_key, |k| k.map(|&k| *k));
248 *opt.expect("task-local LLVMContextRef wasn't ever set!")
251 fn set_task_llcx(c: ContextRef) {
252 local_data::set(task_local_llcx_key, @c);
255 fn unset_task_llcx() {
256 local_data::pop(task_local_llcx_key);