Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 381267b

Browse files
committedJun 12, 2015
rustc: --emit=rlibmeta outputs an rlib with only metadata, works with -Z no-trans.
1 parent f6c306d commit 381267b

File tree

9 files changed

+214
-145
lines changed

9 files changed

+214
-145
lines changed
 

‎src/librustc/metadata/encoder.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,8 +251,10 @@ fn encode_symbol(ecx: &EncodeContext,
251251
rbml_w.wr_tagged_str(tag_items_data_item_symbol, x);
252252
}
253253
None => {
254-
ecx.diag.handler().bug(
255-
&format!("encode_symbol: id not found {}", id));
254+
if !ecx.tcx.sess.opts.no_trans {
255+
ecx.diag.handler().bug(
256+
&format!("encode_symbol: id not found {}", id));
257+
}
256258
}
257259
}
258260
}

‎src/librustc/session/config.rs

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ pub enum OutputType {
7070
OutputTypeObject,
7171
OutputTypeExe,
7272
OutputTypeDepInfo,
73+
OutputTypeRlibMeta,
7374
}
7475

7576
#[derive(Clone)]
@@ -183,6 +184,7 @@ impl OutputFilenames {
183184
OutputTypeLlvmAssembly => base.with_extension("ll"),
184185
OutputTypeObject => base.with_extension("o"),
185186
OutputTypeDepInfo => base.with_extension("d"),
187+
OutputTypeRlibMeta => base.with_extension("rmeta"),
186188
OutputTypeExe => base,
187189
}
188190
}
@@ -785,7 +787,7 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
785787
"NAME"),
786788
opt::multi("", "emit", "Comma separated list of types of output for \
787789
the compiler to emit",
788-
"[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
790+
"[asm|llvm-bc|llvm-ir|obj|link|dep-info|rlibmeta]"),
789791
opt::multi("", "print", "Comma separated list of compiler information to \
790792
print on stdout",
791793
"[crate-name|file-names|sysroot]"),
@@ -886,29 +888,33 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
886888
}
887889

888890
let mut output_types = Vec::new();
889-
if !debugging_opts.parse_only && !no_trans {
890-
let unparsed_output_types = matches.opt_strs("emit");
891-
for unparsed_output_type in &unparsed_output_types {
892-
for part in unparsed_output_type.split(',') {
893-
let output_type = match part {
894-
"asm" => OutputTypeAssembly,
895-
"llvm-ir" => OutputTypeLlvmAssembly,
896-
"llvm-bc" => OutputTypeBitcode,
897-
"obj" => OutputTypeObject,
898-
"link" => OutputTypeExe,
899-
"dep-info" => OutputTypeDepInfo,
900-
_ => {
901-
early_error(&format!("unknown emission type: `{}`",
902-
part))
903-
}
904-
};
905-
output_types.push(output_type)
906-
}
891+
let unparsed_output_types = matches.opt_strs("emit");
892+
for unparsed_output_type in &unparsed_output_types {
893+
for part in unparsed_output_type.split(',') {
894+
let output_type = match part {
895+
"asm" => OutputTypeAssembly,
896+
"llvm-ir" => OutputTypeLlvmAssembly,
897+
"llvm-bc" => OutputTypeBitcode,
898+
"obj" => OutputTypeObject,
899+
"link" => OutputTypeExe,
900+
"dep-info" => OutputTypeDepInfo,
901+
"rlibmeta" => OutputTypeRlibMeta,
902+
_ => {
903+
early_error(&format!("unknown emission type: `{}`",
904+
part))
905+
}
906+
};
907+
output_types.push(output_type)
907908
}
908-
};
909+
}
909910
output_types.sort();
910911
output_types.dedup();
911-
if output_types.is_empty() {
912+
913+
if debugging_opts.parse_only {
914+
output_types = vec![];
915+
} else if no_trans {
916+
output_types.retain(|&x| x == OutputTypeRlibMeta);
917+
} else if output_types.is_empty() {
912918
output_types.push(OutputTypeExe);
913919
}
914920

‎src/librustc_driver/driver.rs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ pub fn compile_input(sess: Session,
101101
CompileState::state_after_expand(input,
102102
&sess,
103103
outdir,
104+
&outputs,
104105
&expanded_crate,
105106
&id[..]));
106107

@@ -115,6 +116,7 @@ pub fn compile_input(sess: Session,
115116
CompileState::state_after_write_deps(input,
116117
&sess,
117118
outdir,
119+
&outputs,
118120
&ast_map,
119121
&ast_map.krate(),
120122
&id[..]));
@@ -130,6 +132,7 @@ pub fn compile_input(sess: Session,
130132
CompileState::state_after_analysis(input,
131133
&analysis.ty_cx.sess,
132134
outdir,
135+
&outputs,
133136
analysis.ty_cx.map.krate(),
134137
&analysis,
135138
&analysis.ty_cx));
@@ -157,6 +160,7 @@ pub fn compile_input(sess: Session,
157160
CompileState::state_after_llvm(input,
158161
&sess,
159162
outdir,
163+
&outputs,
160164
&trans));
161165

162166
phase_6_link_output(&sess, &trans, &outputs);
@@ -280,19 +284,22 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
280284
fn state_after_expand(input: &'a Input,
281285
session: &'a Session,
282286
out_dir: &'a Option<PathBuf>,
287+
outputs: &'a OutputFilenames,
283288
expanded_crate: &'a ast::Crate,
284289
crate_name: &'a str)
285290
-> CompileState<'a, 'ast, 'tcx> {
286291
CompileState {
287292
crate_name: Some(crate_name),
288293
expanded_crate: Some(expanded_crate),
294+
output_filenames: Some(outputs),
289295
.. CompileState::empty(input, session, out_dir)
290296
}
291297
}
292298

293299
fn state_after_write_deps(input: &'a Input,
294300
session: &'a Session,
295301
out_dir: &'a Option<PathBuf>,
302+
outputs: &'a OutputFilenames,
296303
ast_map: &'a ast_map::Map<'ast>,
297304
expanded_crate: &'a ast::Crate,
298305
crate_name: &'a str)
@@ -301,13 +308,15 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
301308
crate_name: Some(crate_name),
302309
ast_map: Some(ast_map),
303310
expanded_crate: Some(expanded_crate),
311+
output_filenames: Some(outputs),
304312
.. CompileState::empty(input, session, out_dir)
305313
}
306314
}
307315

308316
fn state_after_analysis(input: &'a Input,
309317
session: &'a Session,
310318
out_dir: &'a Option<PathBuf>,
319+
outputs: &'a OutputFilenames,
311320
expanded_crate: &'a ast::Crate,
312321
analysis: &'a ty::CrateAnalysis<'tcx>,
313322
tcx: &'a ty::ctxt<'tcx>)
@@ -316,6 +325,7 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
316325
analysis: Some(analysis),
317326
tcx: Some(tcx),
318327
expanded_crate: Some(expanded_crate),
328+
output_filenames: Some(outputs),
319329
.. CompileState::empty(input, session, out_dir)
320330
}
321331
}
@@ -324,10 +334,12 @@ impl<'a, 'ast, 'tcx> CompileState<'a, 'ast, 'tcx> {
324334
fn state_after_llvm(input: &'a Input,
325335
session: &'a Session,
326336
out_dir: &'a Option<PathBuf>,
337+
outputs: &'a OutputFilenames,
327338
trans: &'a trans::CrateTranslation)
328339
-> CompileState<'a, 'ast, 'tcx> {
329340
CompileState {
330341
trans: Some(trans),
342+
output_filenames: Some(outputs),
331343
.. CompileState::empty(input, session, out_dir)
332344
}
333345
}
@@ -788,12 +800,13 @@ fn write_out_deps(sess: &Session,
788800
id: &str) {
789801

790802
let mut out_filenames = Vec::new();
791-
for output_type in &sess.opts.output_types {
792-
let file = outputs.path(*output_type);
793-
match *output_type {
803+
for &output_type in &sess.opts.output_types {
804+
let file = outputs.path(output_type);
805+
match output_type {
794806
config::OutputTypeExe => {
795-
for output in sess.crate_types.borrow().iter() {
796-
let p = link::filename_for_input(sess, *output,
807+
for &output in sess.crate_types.borrow().iter() {
808+
let p = link::filename_for_input(sess, output,
809+
output_type,
797810
id, &file);
798811
out_filenames.push(p);
799812
}

‎src/librustc_driver/lib.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,22 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
368368

369369
if sess.opts.no_trans {
370370
control.after_analysis.stop = Compilation::Stop;
371+
if sess.opts.output_types.contains(&config::OutputTypeRlibMeta) {
372+
control.after_analysis.callback = box |state| {
373+
use rustc_trans::trans;
374+
375+
let tcx = state.tcx.unwrap();
376+
let name = state.analysis.unwrap().name.clone();
377+
let trans = trans::trans_only_metadata(tcx, name);
378+
let outputs = state.output_filenames.unwrap();
379+
driver::phase_6_link_output(&tcx.sess, &trans, outputs);
380+
};
381+
}
371382
}
372383

373-
if !sess.opts.output_types.iter().any(|&i| i == config::OutputTypeExe) {
384+
if !sess.opts.output_types.iter().any(|&i|
385+
i == config::OutputTypeExe ||
386+
i == config::OutputTypeRlibMeta) {
374387
control.after_llvm.stop = Compilation::Stop;
375388
}
376389

@@ -456,6 +469,7 @@ impl RustcDefaultCalls {
456469
for &style in &crate_types {
457470
let fname = link::filename_for_input(sess,
458471
style,
472+
config::OutputTypeExe,
459473
&id,
460474
&t_outputs.with_extension(""));
461475
println!("{}", fname.file_name().unwrap()

‎src/librustc_trans/back/link.rs

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -389,25 +389,39 @@ pub fn link_binary(sess: &Session,
389389
outputs: &OutputFilenames,
390390
crate_name: &str) -> Vec<PathBuf> {
391391
let mut out_filenames = Vec::new();
392-
for &crate_type in sess.crate_types.borrow().iter() {
392+
if sess.opts.output_types.contains(&config::OutputTypeExe) {
393+
for &crate_type in sess.crate_types.borrow().iter() {
394+
if invalid_output_for_target(sess, crate_type) {
395+
sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
396+
crate_type, sess.opts.target_triple));
397+
}
398+
let out_file = link_binary_output(sess, trans, crate_type, outputs,
399+
crate_name, None);
400+
out_filenames.push(out_file);
401+
}
402+
403+
// Remove the temporary object file and metadata if we aren't saving temps
404+
if !sess.opts.cg.save_temps {
405+
let obj_filename = outputs.temp_path(OutputTypeObject);
406+
if !sess.opts.output_types.contains(&OutputTypeObject) {
407+
remove(sess, &obj_filename);
408+
}
409+
remove(sess, &obj_filename.with_extension("metadata.o"));
410+
}
411+
}
412+
413+
// Attempt to output an rlib with just metadata, if that was requested.
414+
if sess.opts.output_types.contains(&config::OutputTypeRlibMeta) {
415+
let crate_type = config::CrateTypeRlib;
393416
if invalid_output_for_target(sess, crate_type) {
394417
sess.bug(&format!("invalid output type `{:?}` for target os `{}`",
395-
crate_type, sess.opts.target_triple));
418+
crate_type, sess.opts.target_triple));
396419
}
397420
let out_file = link_binary_output(sess, trans, crate_type, outputs,
398-
crate_name);
421+
crate_name, Some(config::OutputTypeRlibMeta));
399422
out_filenames.push(out_file);
400423
}
401424

402-
// Remove the temporary object file and metadata if we aren't saving temps
403-
if !sess.opts.cg.save_temps {
404-
let obj_filename = outputs.temp_path(OutputTypeObject);
405-
if !sess.opts.output_types.contains(&OutputTypeObject) {
406-
remove(sess, &obj_filename);
407-
}
408-
remove(sess, &obj_filename.with_extension("metadata.o"));
409-
}
410-
411425
out_filenames
412426
}
413427

@@ -449,12 +463,18 @@ fn is_writeable(p: &Path) -> bool {
449463

450464
pub fn filename_for_input(sess: &Session,
451465
crate_type: config::CrateType,
466+
output_type: config::OutputType,
452467
name: &str,
453468
out_filename: &Path) -> PathBuf {
454469
let libname = format!("{}{}", name, sess.opts.cg.extra_filename);
455470
match crate_type {
456471
config::CrateTypeRlib => {
457-
out_filename.with_file_name(&format!("lib{}.rlib", libname))
472+
let suffix = if output_type == config::OutputTypeRlibMeta {
473+
".rmeta"
474+
} else {
475+
""
476+
};
477+
out_filename.with_file_name(&format!("lib{}{}.rlib", libname, suffix))
458478
}
459479
config::CrateTypeDylib => {
460480
let (prefix, suffix) = (&sess.target.target.options.dll_prefix,
@@ -482,13 +502,16 @@ fn link_binary_output(sess: &Session,
482502
trans: &CrateTranslation,
483503
crate_type: config::CrateType,
484504
outputs: &OutputFilenames,
485-
crate_name: &str) -> PathBuf {
505+
crate_name: &str,
506+
custom_rlib_emission: Option<config::OutputType>)
507+
-> PathBuf {
486508
let obj_filename = outputs.temp_path(OutputTypeObject);
487509
let out_filename = match outputs.single_output_file {
488510
Some(ref file) => file.clone(),
489511
None => {
490-
let out_filename = outputs.path(OutputTypeExe);
491-
filename_for_input(sess, crate_type, crate_name, &out_filename)
512+
let output_type = custom_rlib_emission.unwrap_or(OutputTypeExe);
513+
let out_filename = outputs.path(output_type);
514+
filename_for_input(sess, crate_type, output_type, crate_name, &out_filename)
492515
}
493516
};
494517

@@ -511,7 +534,12 @@ fn link_binary_output(sess: &Session,
511534

512535
match crate_type {
513536
config::CrateTypeRlib => {
514-
link_rlib(sess, Some(trans), &obj_filename, &out_filename).build();
537+
let obj_filename = if custom_rlib_emission.is_some() {
538+
None
539+
} else {
540+
Some(&*obj_filename)
541+
};
542+
link_rlib(sess, Some(trans), obj_filename, &out_filename).build();
515543
}
516544
config::CrateTypeStaticlib => {
517545
link_staticlib(sess, &obj_filename, &out_filename);
@@ -544,7 +572,7 @@ fn archive_search_paths(sess: &Session) -> Vec<PathBuf> {
544572
// native libraries and inserting all of the contents into this archive.
545573
fn link_rlib<'a>(sess: &'a Session,
546574
trans: Option<&CrateTranslation>, // None == no metadata/bytecode
547-
obj_filename: &Path,
575+
obj_filename: Option<&Path>,
548576
out_filename: &Path) -> ArchiveBuilder<'a> {
549577
info!("preparing rlib from {:?} to {:?}", obj_filename, out_filename);
550578
let handler = &sess.diagnostic().handler;
@@ -557,7 +585,7 @@ fn link_rlib<'a>(sess: &'a Session,
557585
ar_prog: get_ar_prog(sess),
558586
};
559587
let mut ab = ArchiveBuilder::create(config);
560-
ab.add_file(obj_filename).unwrap();
588+
obj_filename.map(|file| ab.add_file(file).unwrap());
561589

562590
for &(ref l, kind) in sess.cstore.get_used_libraries().borrow().iter() {
563591
match kind {
@@ -619,6 +647,13 @@ fn link_rlib<'a>(sess: &'a Session,
619647
ab.add_file(&metadata).unwrap();
620648
remove(sess, &metadata);
621649

650+
// Nothing else to add if we have no code.
651+
let obj_filename = if let Some(file) = obj_filename {
652+
file
653+
} else {
654+
return ab;
655+
};
656+
622657
// For LTO purposes, the bytecode of this library is also inserted
623658
// into the archive. If codegen_units > 1, we insert each of the
624659
// bitcode files.
@@ -734,7 +769,7 @@ fn write_rlib_bytecode_object_v1(writer: &mut Write,
734769
// link in the metadata object file (and also don't prepare the archive with a
735770
// metadata file).
736771
fn link_staticlib(sess: &Session, obj_filename: &Path, out_filename: &Path) {
737-
let ab = link_rlib(sess, None, obj_filename, out_filename);
772+
let ab = link_rlib(sess, None, Some(obj_filename), out_filename);
738773
let mut ab = match sess.target.target.options.is_like_osx {
739774
true => ab.build().extend(),
740775
false => ab,

‎src/librustc_trans/back/write.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,8 @@ pub fn run_passes(sess: &Session,
620620
modules_config.emit_obj = true;
621621
metadata_config.emit_obj = true;
622622
},
623-
config::OutputTypeDepInfo => {}
623+
config::OutputTypeDepInfo |
624+
config::OutputTypeRlibMeta => {}
624625
}
625626
}
626627

@@ -793,7 +794,8 @@ pub fn run_passes(sess: &Session,
793794
link_obj(&crate_output.temp_path(config::OutputTypeObject));
794795
}
795796
}
796-
config::OutputTypeDepInfo => {}
797+
config::OutputTypeDepInfo |
798+
config::OutputTypeRlibMeta => {}
797799
}
798800
}
799801
let user_wants_bitcode = user_wants_bitcode;

‎src/librustc_trans/trans/base.rs

Lines changed: 76 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use lint;
3535
use llvm::{BasicBlockRef, Linkage, ValueRef, Vector, get_param};
3636
use llvm;
3737
use metadata::{csearch, encoder, loader};
38+
use metadata::common::LinkMeta;
3839
use middle::astencode;
3940
use middle::cfg;
4041
use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
@@ -61,7 +62,7 @@ use trans::common::{node_id_type, return_type_is_void};
6162
use trans::common::{type_is_immediate, type_is_zero_size, val_ty};
6263
use trans::common;
6364
use trans::consts;
64-
use trans::context::SharedCrateContext;
65+
use trans::context::{self, SharedCrateContext};
6566
use trans::controlflow;
6667
use trans::datum;
6768
use trans::debuginfo::{self, DebugLoc, ToDebugLoc};
@@ -82,7 +83,7 @@ use trans::value::Value;
8283
use util::common::indenter;
8384
use util::ppaux::{Repr, ty_to_string};
8485
use util::sha2::Sha256;
85-
use util::nodemap::NodeMap;
86+
use util::nodemap::{NodeMap, NodeSet, FnvHashMap};
8687

8788
use arena::TypedArena;
8889
use libc::c_uint;
@@ -2477,55 +2478,57 @@ fn register_method(ccx: &CrateContext, id: ast::NodeId,
24772478
}
24782479
}
24792480

2480-
pub fn crate_ctxt_to_encode_parms<'a, 'tcx>(cx: &'a SharedCrateContext<'tcx>,
2481-
ie: encoder::EncodeInlinedItem<'a>)
2482-
-> encoder::EncodeParams<'a, 'tcx> {
2483-
encoder::EncodeParams {
2484-
diag: cx.sess().diagnostic(),
2485-
tcx: cx.tcx(),
2486-
reexports: cx.export_map(),
2487-
item_symbols: cx.item_symbols(),
2488-
link_meta: cx.link_meta(),
2489-
cstore: &cx.sess().cstore,
2490-
encode_inlined_item: ie,
2491-
reachable: cx.reachable(),
2492-
}
2493-
}
2494-
2495-
pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
2481+
pub fn write_metadata(tcx: &ty::ctxt, link_meta: &LinkMeta,
2482+
ccx: Option<&SharedCrateContext>)
2483+
-> (Vec<u8>, ModuleTranslation) {
24962484
use flate;
24972485

2498-
let any_library = cx.sess().crate_types.borrow().iter().any(|ty| {
2486+
let any_library = tcx.sess.crate_types.borrow().iter().any(|ty| {
24992487
*ty != config::CrateTypeExecutable
25002488
});
2501-
if !any_library {
2502-
return Vec::new()
2503-
}
2504-
2505-
let encode_inlined_item: encoder::EncodeInlinedItem =
2506-
Box::new(|ecx, rbml_w, ii| astencode::encode_inlined_item(ecx, rbml_w, ii));
25072489

2508-
let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
2509-
let metadata = encoder::encode_metadata(encode_parms, krate);
2490+
let (llcx, llmod) = context::create_context_and_module(&tcx.sess, "metadata");
2491+
let module = ModuleTranslation {
2492+
llcx: llcx,
2493+
llmod: llmod
2494+
};
2495+
if !any_library {
2496+
return (vec![], module);
2497+
}
2498+
2499+
let empty_reexports = FnvHashMap();
2500+
let empty_item_symbols = RefCell::new(NodeMap());
2501+
let empty_reachable = NodeSet();
2502+
let encode_parms = encoder::EncodeParams {
2503+
diag: tcx.sess.diagnostic(),
2504+
tcx: tcx,
2505+
reexports: ccx.map_or(&empty_reexports, |cx| cx.export_map()),
2506+
item_symbols: ccx.map_or(&empty_item_symbols, |cx| cx.item_symbols()),
2507+
link_meta: link_meta,
2508+
cstore: &tcx.sess.cstore,
2509+
encode_inlined_item: box astencode::encode_inlined_item,
2510+
reachable: ccx.map_or(&empty_reachable, |cx| cx.reachable()),
2511+
};
2512+
let metadata = encoder::encode_metadata(encode_parms, tcx.map.krate());
25102513
let mut compressed = encoder::metadata_encoding_version.to_vec();
25112514
compressed.push_all(&flate::deflate_bytes(&metadata));
2512-
let llmeta = C_bytes_in_context(cx.metadata_llcx(), &compressed[..]);
2513-
let llconst = C_struct_in_context(cx.metadata_llcx(), &[llmeta], false);
2515+
2516+
let llmeta = C_bytes_in_context(llcx, &compressed[..]);
2517+
let llconst = C_struct_in_context(llcx, &[llmeta], false);
25142518
let name = format!("rust_metadata_{}_{}",
2515-
cx.link_meta().crate_name,
2516-
cx.link_meta().crate_hash);
2519+
link_meta.crate_name,
2520+
link_meta.crate_hash);
25172521
let buf = CString::new(name).unwrap();
25182522
let llglobal = unsafe {
2519-
llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(),
2520-
buf.as_ptr())
2523+
llvm::LLVMAddGlobal(llmod, val_ty(llconst).to_ref(), buf.as_ptr())
25212524
};
25222525
unsafe {
25232526
llvm::LLVMSetInitializer(llglobal, llconst);
2524-
let name = loader::meta_section_name(&cx.sess().target.target);
2527+
let name = loader::meta_section_name(&tcx.sess.target.target);
25252528
let name = CString::new(name).unwrap();
25262529
llvm::LLVMSetSection(llglobal, name.as_ptr())
25272530
}
2528-
return metadata;
2531+
(metadata, module)
25292532
}
25302533

25312534
/// Find any symbols that are defined in one compilation unit, but not declared
@@ -2613,23 +2616,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
26132616
}
26142617
}
26152618

2616-
pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
2617-
-> (ty::ctxt<'tcx>, CrateTranslation) {
2618-
let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
2619-
let krate = tcx.map.krate();
2620-
2621-
let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
2622-
v
2623-
} else {
2624-
tcx.sess.opts.debug_assertions
2625-
};
2626-
2627-
let check_dropflag = if let Some(v) = tcx.sess.opts.debugging_opts.force_dropflag_checks {
2628-
v
2629-
} else {
2630-
tcx.sess.opts.debug_assertions
2631-
};
2632-
2619+
fn initialize_llvm(sess: &Session) {
26332620
// Before we touch LLVM, make sure that multithreading is enabled.
26342621
unsafe {
26352622
use std::sync::Once;
@@ -2644,10 +2631,29 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
26442631
});
26452632

26462633
if POISONED {
2647-
tcx.sess.bug("couldn't enable multi-threaded LLVM");
2634+
sess.bug("couldn't enable multi-threaded LLVM");
26482635
}
26492636
}
2637+
}
2638+
2639+
pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
2640+
-> (ty::ctxt<'tcx>, CrateTranslation) {
2641+
let ty::CrateAnalysis { ty_cx: tcx, export_map, reachable, name, .. } = analysis;
2642+
let krate = tcx.map.krate();
2643+
2644+
let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
2645+
v
2646+
} else {
2647+
tcx.sess.opts.debug_assertions
2648+
};
26502649

2650+
let check_dropflag = if let Some(v) = tcx.sess.opts.debugging_opts.force_dropflag_checks {
2651+
v
2652+
} else {
2653+
tcx.sess.opts.debug_assertions
2654+
};
2655+
2656+
initialize_llvm(&tcx.sess);
26512657
let link_meta = link::build_link_meta(&tcx.sess, krate, name);
26522658

26532659
let codegen_units = tcx.sess.opts.cg.codegen_units;
@@ -2681,7 +2687,8 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
26812687
}
26822688

26832689
// Translate the metadata.
2684-
let metadata = write_metadata(&shared_ccx, krate);
2690+
let (metadata, metadata_module) = write_metadata(shared_ccx.tcx(), &link_meta,
2691+
Some(&shared_ccx));
26852692

26862693
if shared_ccx.sess().trans_stats() {
26872694
let stats = shared_ccx.stats();
@@ -2748,10 +2755,6 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
27482755
internalize_symbols(&shared_ccx, &reachable.iter().cloned().collect());
27492756
}
27502757

2751-
let metadata_module = ModuleTranslation {
2752-
llcx: shared_ccx.metadata_llcx(),
2753-
llmod: shared_ccx.metadata_llmod(),
2754-
};
27552758
let formats = shared_ccx.tcx().dependency_formats.borrow().clone();
27562759
let no_builtins = attr::contains_name(&krate.attrs, "no_builtins");
27572760

@@ -2767,3 +2770,18 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
27672770

27682771
(shared_ccx.take_tcx(), translation)
27692772
}
2773+
2774+
pub fn trans_only_metadata(tcx: &ty::ctxt, name: String) -> CrateTranslation {
2775+
initialize_llvm(&tcx.sess);
2776+
let link_meta = link::build_link_meta(&tcx.sess, tcx.map.krate(), name);
2777+
let (metadata, metadata_module) = write_metadata(tcx, &link_meta, None);
2778+
CrateTranslation {
2779+
modules: vec![],
2780+
metadata_module: metadata_module,
2781+
link: link_meta,
2782+
metadata: metadata,
2783+
reachable: vec![],
2784+
crate_formats: tcx.dependency_formats.borrow().clone(),
2785+
no_builtins: true
2786+
}
2787+
}

‎src/librustc_trans/trans/context.rs

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,6 @@ pub struct Stats {
6060
pub struct SharedCrateContext<'tcx> {
6161
local_ccxs: Vec<LocalCrateContext<'tcx>>,
6262

63-
metadata_llmod: ModuleRef,
64-
metadata_llcx: ContextRef,
65-
6663
export_map: ExportMap,
6764
reachable: NodeSet,
6865
item_symbols: RefCell<NodeMap<String>>,
@@ -221,20 +218,21 @@ impl<'a, 'tcx> Iterator for CrateContextMaybeIterator<'a, 'tcx> {
221218
}
222219
}
223220

221+
pub fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
222+
unsafe {
223+
let llcx = llvm::LLVMContextCreate();
224+
let mod_name = CString::new(mod_name).unwrap();
225+
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
224226

225-
unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
226-
let llcx = llvm::LLVMContextCreate();
227-
let mod_name = CString::new(mod_name).unwrap();
228-
let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
229-
230-
let data_layout = sess.target.target.data_layout.as_bytes();
231-
let data_layout = CString::new(data_layout).unwrap();
232-
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
227+
let data_layout = sess.target.target.data_layout.as_bytes();
228+
let data_layout = CString::new(data_layout).unwrap();
229+
llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
233230

234-
let llvm_target = sess.target.target.llvm_target.as_bytes();
235-
let llvm_target = CString::new(llvm_target).unwrap();
236-
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
237-
(llcx, llmod)
231+
let llvm_target = sess.target.target.llvm_target.as_bytes();
232+
let llvm_target = CString::new(llvm_target).unwrap();
233+
llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
234+
(llcx, llmod)
235+
}
238236
}
239237

240238
impl<'tcx> SharedCrateContext<'tcx> {
@@ -248,10 +246,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
248246
check_overflow: bool,
249247
check_drop_flag_for_sanity: bool)
250248
-> SharedCrateContext<'tcx> {
251-
let (metadata_llcx, metadata_llmod) = unsafe {
252-
create_context_and_module(&tcx.sess, "metadata")
253-
};
254-
255249
// An interesting part of Windows which MSVC forces our hand on (and
256250
// apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
257251
// attributes in LLVM IR as well as native dependencies (in C these
@@ -299,8 +293,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
299293

300294
let mut shared_ccx = SharedCrateContext {
301295
local_ccxs: Vec::with_capacity(local_count),
302-
metadata_llmod: metadata_llmod,
303-
metadata_llcx: metadata_llcx,
304296
export_map: export_map,
305297
reachable: reachable,
306298
item_symbols: RefCell::new(NodeMap()),
@@ -372,14 +364,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
372364
}
373365

374366

375-
pub fn metadata_llmod(&self) -> ModuleRef {
376-
self.metadata_llmod
377-
}
378-
379-
pub fn metadata_llcx(&self) -> ContextRef {
380-
self.metadata_llcx
381-
}
382-
383367
pub fn export_map<'a>(&'a self) -> &'a ExportMap {
384368
&self.export_map
385369
}
@@ -392,10 +376,6 @@ impl<'tcx> SharedCrateContext<'tcx> {
392376
&self.item_symbols
393377
}
394378

395-
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
396-
&self.link_meta
397-
}
398-
399379
pub fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx> {
400380
&self.tcx
401381
}
@@ -421,9 +401,8 @@ impl<'tcx> LocalCrateContext<'tcx> {
421401
fn new(shared: &SharedCrateContext<'tcx>,
422402
name: &str)
423403
-> LocalCrateContext<'tcx> {
404+
let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, name);
424405
unsafe {
425-
let (llcx, llmod) = create_context_and_module(&shared.tcx.sess, name);
426-
427406
let td = mk_target_data(&shared.tcx
428407
.sess
429408
.target

‎src/librustc_trans/trans/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use llvm::{ContextRef, ModuleRef};
1212
use metadata::common::LinkMeta;
1313
use middle::dependency_format;
1414

15-
pub use self::base::trans_crate;
15+
pub use self::base::{trans_crate, trans_only_metadata};
1616
pub use self::context::CrateContext;
1717
pub use self::common::gensym_name;
1818

0 commit comments

Comments
 (0)
Please sign in to comment.