From 2257e231a7e0c455b61c60414a65e89f01cbf509 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 24 Sep 2014 10:58:53 -0700 Subject: librustc: Eliminate the `ref` syntax for unboxed closure capture clauses in favor of `move`. This breaks code that used `move` as an identifier, because it is now a keyword. Change such identifiers to not use the keyword `move`. Additionally, this breaks code that was counting on by-value or by-reference capture semantics for unboxed closures (behind the feature gate). Change `ref |:|` to `|:|` and `|:|` to `move |:|`. Part of RFC #63; part of issue #12831. [breaking-change] --- src/libsyntax/parse/parser.rs | 6 ++--- src/libsyntax/parse/token.rs | 57 ++++++++++++++++++++++--------------------- src/libsyntax/print/pprust.rs | 4 +-- 3 files changed, 34 insertions(+), 33 deletions(-) (limited to 'src/libsyntax') diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index cbc710821f9..415ff6a4097 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2084,7 +2084,7 @@ impl<'a> Parser<'a> { ExprBlock(blk)); }, token::BINOP(token::OR) | token::OROR => { - return self.parse_lambda_expr(CaptureByValue); + return self.parse_lambda_expr(CaptureByRef); }, // FIXME #13626: Should be able to stick in // token::SELF_KEYWORD_NAME @@ -2135,8 +2135,8 @@ impl<'a> Parser<'a> { hi = self.last_span.hi; } _ => { - if self.eat_keyword(keywords::Ref) { - return self.parse_lambda_expr(CaptureByRef); + if self.eat_keyword(keywords::Move) { + return self.parse_lambda_expr(CaptureByValue); } if self.eat_keyword(keywords::Proc) { let decl = self.parse_proc_decl(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index f71190da430..a486ac40a97 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -482,40 +482,41 @@ declare_special_idents_and_keywords! { (25, Loop, "loop"); (26, Match, "match"); (27, Mod, "mod"); - (28, Mut, "mut"); - (29, Once, "once"); - (30, Pub, "pub"); - (31, Ref, "ref"); - (32, Return, "return"); + (28, Move, "move"); + (29, Mut, "mut"); + (30, Once, "once"); + (31, Pub, "pub"); + (32, Ref, "ref"); + (33, Return, "return"); // Static and Self are also special idents (prefill de-dupes) (super::STATIC_KEYWORD_NAME_NUM, Static, "static"); (super::SELF_KEYWORD_NAME_NUM, Self, "self"); - (33, Struct, "struct"); + (34, Struct, "struct"); (super::SUPER_KEYWORD_NAME_NUM, Super, "super"); - (34, True, "true"); - (35, Trait, "trait"); - (36, Type, "type"); - (37, Unsafe, "unsafe"); - (38, Use, "use"); - (39, Virtual, "virtual"); - (40, While, "while"); - (41, Continue, "continue"); - (42, Proc, "proc"); - (43, Box, "box"); - (44, Const, "const"); - (45, Where, "where"); + (35, True, "true"); + (36, Trait, "trait"); + (37, Type, "type"); + (38, Unsafe, "unsafe"); + (39, Use, "use"); + (40, Virtual, "virtual"); + (41, While, "while"); + (42, Continue, "continue"); + (43, Proc, "proc"); + (44, Box, "box"); + (45, Const, "const"); + (46, Where, "where"); 'reserved: - (46, Alignof, "alignof"); - (47, Be, "be"); - (48, Offsetof, "offsetof"); - (49, Priv, "priv"); - (50, Pure, "pure"); - (51, Sizeof, "sizeof"); - (52, Typeof, "typeof"); - (53, Unsized, "unsized"); - (54, Yield, "yield"); - (55, Do, "do"); + (47, Alignof, "alignof"); + (48, Be, "be"); + (49, Offsetof, "offsetof"); + (50, Priv, "priv"); + (51, Pure, "pure"); + (52, Sizeof, "sizeof"); + (53, Typeof, "typeof"); + (54, Unsized, "unsized"); + (55, Yield, "yield"); + (56, Do, "do"); } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 1fbd4af8627..ae4ba611bab 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2176,8 +2176,8 @@ impl<'a> State<'a> { pub fn print_capture_clause(&mut self, capture_clause: ast::CaptureClause) -> IoResult<()> { match capture_clause { - ast::CaptureByValue => Ok(()), - ast::CaptureByRef => self.word_space("ref"), + ast::CaptureByValue => self.word_space("move"), + ast::CaptureByRef => Ok(()), } } -- cgit 1.4.1-3-g733a5 From fc1b908322a5a2ebf8aa599d7178accdd3cbaed9 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Fri, 26 Sep 2014 17:14:23 -0700 Subject: Hide the quote_*! macros when the feature gate is off This makes it easier to experiment with improved quasiquoting as an ordinary plugin library. The list of quote macros in feature_gate.rs was already out of sync; this commit also prevents that problem in the future. --- src/librustc/driver/driver.rs | 3 +- src/libsyntax/ext/base.rs | 57 +++++++++++++++++---------------- src/libsyntax/ext/expand.rs | 43 ++++++++++++------------- src/libsyntax/feature_gate.rs | 17 ++-------- src/libsyntax/test.rs | 5 +-- src/test/run-pass/non-built-in-quote.rs | 17 ++++++++++ 6 files changed, 74 insertions(+), 68 deletions(-) create mode 100644 src/test/run-pass/non-built-in-quote.rs (limited to 'src/libsyntax') diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 33e6579fb87..05d83e5fc0f 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -288,8 +288,9 @@ pub fn phase_2_configure_and_expand(sess: &Session, os::setenv("PATH", os::join_paths(new_path.as_slice()).unwrap()); } let cfg = syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: sess.features.borrow().default_type_params, crate_name: crate_name.to_string(), + deriving_hash_type_parameter: sess.features.borrow().default_type_params, + enable_quotes: sess.features.borrow().quote, }; let ret = syntax::ext::expand::expand_crate(&sess.parse_sess, cfg, diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b35a9456757..f340849759e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -344,7 +344,7 @@ impl BlockInfo { /// The base map of methods for expanding syntax extension /// AST nodes into full ASTs -fn initial_syntax_expander_table() -> SyntaxEnv { +fn initial_syntax_expander_table(ecfg: &expand::ExpansionConfig) -> SyntaxEnv { // utility function to simplify creating NormalTT syntax extensions fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension { NormalTT(box f, None) @@ -383,31 +383,33 @@ fn initial_syntax_expander_table() -> SyntaxEnv { syntax_expanders.insert(intern("deriving"), Decorator(box ext::deriving::expand_meta_deriving)); - // Quasi-quoting expanders - syntax_expanders.insert(intern("quote_tokens"), - builtin_normal_expander( - ext::quote::expand_quote_tokens)); - syntax_expanders.insert(intern("quote_expr"), - builtin_normal_expander( - ext::quote::expand_quote_expr)); - syntax_expanders.insert(intern("quote_ty"), - builtin_normal_expander( - ext::quote::expand_quote_ty)); - syntax_expanders.insert(intern("quote_method"), - builtin_normal_expander( - ext::quote::expand_quote_method)); - syntax_expanders.insert(intern("quote_item"), - builtin_normal_expander( - ext::quote::expand_quote_item)); - syntax_expanders.insert(intern("quote_pat"), - builtin_normal_expander( - ext::quote::expand_quote_pat)); - syntax_expanders.insert(intern("quote_arm"), - builtin_normal_expander( - ext::quote::expand_quote_arm)); - syntax_expanders.insert(intern("quote_stmt"), - builtin_normal_expander( - ext::quote::expand_quote_stmt)); + if ecfg.enable_quotes { + // Quasi-quoting expanders + syntax_expanders.insert(intern("quote_tokens"), + builtin_normal_expander( + ext::quote::expand_quote_tokens)); + syntax_expanders.insert(intern("quote_expr"), + builtin_normal_expander( + ext::quote::expand_quote_expr)); + syntax_expanders.insert(intern("quote_ty"), + builtin_normal_expander( + ext::quote::expand_quote_ty)); + syntax_expanders.insert(intern("quote_method"), + builtin_normal_expander( + ext::quote::expand_quote_method)); + syntax_expanders.insert(intern("quote_item"), + builtin_normal_expander( + ext::quote::expand_quote_item)); + syntax_expanders.insert(intern("quote_pat"), + builtin_normal_expander( + ext::quote::expand_quote_pat)); + syntax_expanders.insert(intern("quote_arm"), + builtin_normal_expander( + ext::quote::expand_quote_arm)); + syntax_expanders.insert(intern("quote_stmt"), + builtin_normal_expander( + ext::quote::expand_quote_stmt)); + } syntax_expanders.insert(intern("line"), builtin_normal_expander( @@ -464,6 +466,7 @@ pub struct ExtCtxt<'a> { impl<'a> ExtCtxt<'a> { pub fn new<'a>(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig, ecfg: expand::ExpansionConfig) -> ExtCtxt<'a> { + let env = initial_syntax_expander_table(&ecfg); ExtCtxt { parse_sess: parse_sess, cfg: cfg, @@ -472,7 +475,7 @@ impl<'a> ExtCtxt<'a> { ecfg: ecfg, trace_mac: false, exported_macros: Vec::new(), - syntax_env: initial_syntax_expander_table(), + syntax_env: env, } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 70cf41d5e17..9f3df1a7623 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -975,8 +975,19 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span { } pub struct ExpansionConfig { - pub deriving_hash_type_parameter: bool, pub crate_name: String, + pub deriving_hash_type_parameter: bool, + pub enable_quotes: bool, +} + +impl ExpansionConfig { + pub fn default(crate_name: String) -> ExpansionConfig { + ExpansionConfig { + crate_name: crate_name, + deriving_hash_type_parameter: false, + enable_quotes: false, + } + } } pub struct ExportedMacros { @@ -1106,7 +1117,7 @@ impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> { #[cfg(test)] mod test { use super::{pattern_bindings, expand_crate, contains_macro_escape}; - use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer}; + use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig}; use ast; use ast::{Attribute_, AttrOuter, MetaWord, Name}; use attr; @@ -1171,6 +1182,10 @@ mod test { // these following tests are quite fragile, in that they don't test what // *kind* of failure occurs. + fn test_ecfg() -> ExpansionConfig { + ExpansionConfig::default("test".to_string()) + } + // make sure that macros can't escape fns #[should_fail] #[test] fn macros_cant_escape_fns_test () { @@ -1182,11 +1197,7 @@ mod test { src, Vec::new(), &sess); // should fail: - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&sess,cfg,vec!(),vec!(),crate_ast); + expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast); } // make sure that macros can't escape modules @@ -1199,11 +1210,7 @@ mod test { "".to_string(), src, Vec::new(), &sess); - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&sess,cfg,vec!(),vec!(),crate_ast); + expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast); } // macro_escape modules should allow macros to escape @@ -1215,11 +1222,7 @@ mod test { "".to_string(), src, Vec::new(), &sess); - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&sess, cfg, vec!(), vec!(), crate_ast); + expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast); } #[test] fn test_contains_flatten (){ @@ -1252,11 +1255,7 @@ mod test { let ps = parse::new_parse_sess(); let crate_ast = string_to_parser(&ps, crate_str).parse_crate_mod(); // the cfg argument actually does matter, here... - let cfg = ::syntax::ext::expand::ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }; - expand_crate(&ps,cfg,vec!(),vec!(),crate_ast) + expand_crate(&ps,test_ecfg(),vec!(),vec!(),crate_ast) } // find the pat_ident paths in a crate diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index cd0fa184a09..1c6ee8acc94 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -102,6 +102,7 @@ pub struct Features { pub rustc_diagnostic_macros: bool, pub import_shadowing: bool, pub visible_private_types: bool, + pub quote: bool, } impl Features { @@ -112,6 +113,7 @@ impl Features { rustc_diagnostic_macros: false, import_shadowing: false, visible_private_types: false, + quote: false, } } } @@ -282,10 +284,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { fn visit_mac(&mut self, macro: &ast::Mac) { let ast::MacInvocTT(ref path, _, _) = macro.node; let id = path.segments.last().unwrap().identifier; - let quotes = ["quote_tokens", "quote_expr", "quote_ty", - "quote_item", "quote_pat", "quote_stmt"]; - let msg = " is not stable enough for use and are subject to change"; - if id == token::str_to_ident("macro_rules") { self.gate_feature("macro_rules", path.span, "macro definitions are \ @@ -311,16 +309,6 @@ impl<'a, 'v> Visitor<'v> for Context<'a> { self.gate_feature("concat_idents", path.span, "`concat_idents` is not \ stable enough for use and is subject to change"); } - - else { - for "e in quotes.iter() { - if id == token::str_to_ident(quote) { - self.gate_feature("quote", - path.span, - format!("{}{}", quote, msg).as_slice()); - } - } - } } fn visit_foreign_item(&mut self, i: &ast::ForeignItem) { @@ -483,6 +471,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features, rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"), import_shadowing: cx.has_feature("import_shadowing"), visible_private_types: cx.has_feature("visible_private_types"), + quote: cx.has_feature("quote"), }, unknown_features) } diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs index f0e69712714..fdaf9df0150 100644 --- a/src/libsyntax/test.rs +++ b/src/libsyntax/test.rs @@ -235,10 +235,7 @@ fn generate_test_harness(sess: &ParseSess, sess: sess, span_diagnostic: sd, ext_cx: ExtCtxt::new(sess, cfg.clone(), - ExpansionConfig { - deriving_hash_type_parameter: false, - crate_name: "test".to_string(), - }), + ExpansionConfig::default("test".to_string())), path: Vec::new(), testfns: Vec::new(), reexport_test_harness_main: reexport_test_harness_main, diff --git a/src/test/run-pass/non-built-in-quote.rs b/src/test/run-pass/non-built-in-quote.rs new file mode 100644 index 00000000000..c6dd3736857 --- /dev/null +++ b/src/test/run-pass/non-built-in-quote.rs @@ -0,0 +1,17 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(macro_rules)] + +macro_rules! quote_tokens ( () => (()) ) + +pub fn main() { + quote_tokens!(); +} -- cgit 1.4.1-3-g733a5 From 9d60de93e2c5af1b69201b5e3bcf8943ae5df664 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Sat, 27 Sep 2014 01:33:36 -0700 Subject: Translate inline assembly errors back to source locations Fixes #17552. --- src/librustc/back/write.rs | 43 ++++++++++++++++++---- src/librustc/driver/driver.rs | 2 + src/librustc/middle/trans/asm.rs | 14 +++++++ src/librustc_llvm/lib.rs | 9 +++++ src/libsyntax/ast.rs | 3 +- src/libsyntax/codemap.rs | 2 +- src/libsyntax/ext/asm.rs | 13 ++++++- src/libsyntax/fold.rs | 6 ++- src/rustllvm/RustWrapper.cpp | 15 ++++++++ src/rustllvm/rustllvm.h | 1 + src/test/compile-fail/asm-src-loc-codegen-units.rs | 20 ++++++++++ src/test/compile-fail/asm-src-loc.rs | 17 +++++++++ 12 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 src/test/compile-fail/asm-src-loc-codegen-units.rs create mode 100644 src/test/compile-fail/asm-src-loc.rs (limited to 'src/libsyntax') diff --git a/src/librustc/back/write.rs b/src/librustc/back/write.rs index 7242c12ae0c..8e703d954f3 100644 --- a/src/librustc/back/write.rs +++ b/src/librustc/back/write.rs @@ -16,6 +16,7 @@ use driver::session::Session; use driver::config; use llvm; use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef, ContextRef}; +use llvm::SMDiagnosticRef; use util::common::time; use syntax::abi; use syntax::codemap; @@ -326,14 +327,40 @@ impl<'a> CodegenContext<'a> { } } -struct DiagHandlerFreeVars<'a> { +struct HandlerFreeVars<'a> { llcx: ContextRef, cgcx: &'a CodegenContext<'a>, } +unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, + user: *const c_void, + cookie: c_uint) { + use syntax::codemap::ExpnId; + + let HandlerFreeVars { cgcx, .. } + = *mem::transmute::<_, *const HandlerFreeVars>(user); + + let msg = llvm::build_string(|s| llvm::LLVMWriteSMDiagnosticToString(diag, s)) + .expect("non-UTF8 SMDiagnostic"); + + match cgcx.lto_ctxt { + Some((sess, _)) => { + sess.codemap().with_expn_info(ExpnId(cookie as u32), |info| match info { + Some(ei) => sess.span_err(ei.call_site, msg.as_slice()), + None => sess.err(msg.as_slice()), + }); + } + + None => { + cgcx.handler.err(msg.as_slice()); + cgcx.handler.note("build without -C codegen-units for more exact errors"); + } + } +} + unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_void) { - let DiagHandlerFreeVars { llcx, cgcx } - = *mem::transmute::<_, *const DiagHandlerFreeVars>(user); + let HandlerFreeVars { llcx, cgcx } + = *mem::transmute::<_, *const HandlerFreeVars>(user); match llvm::diagnostic::Diagnostic::unpack(info) { llvm::diagnostic::Optimization(opt) => { @@ -368,14 +395,16 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext, let tm = config.tm; // llcx doesn't outlive this function, so we can put this on the stack. - let fv = DiagHandlerFreeVars { + let fv = HandlerFreeVars { llcx: llcx, cgcx: cgcx, }; + let fv = &fv as *const HandlerFreeVars as *mut c_void; + + llvm::LLVMSetInlineAsmDiagnosticHandler(llcx, inline_asm_handler, fv); + if !cgcx.remark.is_empty() { - llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, - &fv as *const DiagHandlerFreeVars - as *mut c_void); + llvm::LLVMContextSetDiagnosticHandler(llcx, diagnostic_handler, fv); } if config.emit_no_opt_bc { diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 33e6579fb87..b0b445b590c 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -556,6 +556,8 @@ pub fn phase_5_run_llvm_passes(sess: &Session, sess.opts.output_types.as_slice(), outputs)); } + + sess.abort_if_errors(); } /// Run the linker on any artifacts that resulted from the LLVM run. diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index a5e6d606d7b..b4c10c78db8 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -25,6 +25,7 @@ use middle::trans::type_::Type; use std::c_str::ToCStr; use std::string::String; use syntax::ast; +use libc::{c_uint, c_char}; // Take an inline assembly expression and splat it out via LLVM pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) @@ -141,6 +142,19 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) } } + // Store expn_id in a metadata node so we can map LLVM errors + // back to source locations. See #17552. + unsafe { + let key = "srcloc"; + let kind = llvm::LLVMGetMDKindIDInContext(bcx.ccx().llcx(), + key.as_ptr() as *const c_char, key.len() as c_uint); + + let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id as i32); + + llvm::LLVMSetMetadata(r, kind, + llvm::LLVMMDNodeInContext(bcx.ccx().llcx(), &val, 1)); + } + return bcx; } diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs index c25ef2ca63a..401933d7058 100644 --- a/src/librustc_llvm/lib.rs +++ b/src/librustc_llvm/lib.rs @@ -424,8 +424,11 @@ pub enum DiagnosticInfo_opaque {} pub type DiagnosticInfoRef = *mut DiagnosticInfo_opaque; pub enum DebugLoc_opaque {} pub type DebugLocRef = *mut DebugLoc_opaque; +pub enum SMDiagnostic_opaque {} +pub type SMDiagnosticRef = *mut SMDiagnostic_opaque; pub type DiagnosticHandler = unsafe extern "C" fn(DiagnosticInfoRef, *mut c_void); +pub type InlineAsmDiagHandler = unsafe extern "C" fn(SMDiagnosticRef, *const c_void, c_uint); pub mod debuginfo { use super::{ValueRef}; @@ -1967,6 +1970,12 @@ extern { pub fn LLVMGetDiagInfoKind(DI: DiagnosticInfoRef) -> DiagnosticKind; pub fn LLVMWriteDebugLocToString(C: ContextRef, DL: DebugLocRef, s: RustStringRef); + + pub fn LLVMSetInlineAsmDiagnosticHandler(C: ContextRef, + H: InlineAsmDiagHandler, + CX: *mut c_void); + + pub fn LLVMWriteSMDiagnosticToString(d: SMDiagnosticRef, s: RustStringRef); } pub fn SetInstructionCallConv(instr: ValueRef, cc: CallConv) { diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 38d8136c1a1..43d6b9b9e90 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -983,7 +983,8 @@ pub struct InlineAsm { pub clobbers: InternedString, pub volatile: bool, pub alignstack: bool, - pub dialect: AsmDialect + pub dialect: AsmDialect, + pub expn_id: u32, } /// represents an argument in a function header diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 9072889463c..d44de7862a3 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -224,7 +224,7 @@ pub struct ExpnInfo { } #[deriving(PartialEq, Eq, Clone, Show, Hash)] -pub struct ExpnId(u32); +pub struct ExpnId(pub u32); pub static NO_EXPANSION: ExpnId = ExpnId(-1); diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 4b8c3376cad..f82fe4b13a2 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -13,6 +13,7 @@ */ use ast; +use codemap; use codemap::Span; use ext::base; use ext::base::*; @@ -198,6 +199,15 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } + let codemap::ExpnId(expn_id) = cx.codemap().record_expansion(codemap::ExpnInfo { + call_site: sp, + callee: codemap::NameAndSpan { + name: "asm".to_string(), + format: codemap::MacroBang, + span: None, + }, + }); + MacExpr::new(P(ast::Expr { id: ast::DUMMY_NODE_ID, node: ast::ExprInlineAsm(ast::InlineAsm { @@ -208,7 +218,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) clobbers: token::intern_and_get_ident(cons.as_slice()), volatile: volatile, alignstack: alignstack, - dialect: dialect + dialect: dialect, + expn_id: expn_id, }), span: sp })) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 91a339a73f7..53be7f2c20c 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1279,7 +1279,8 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> clobbers, volatile, alignstack, - dialect + dialect, + expn_id, }) => ExprInlineAsm(InlineAsm { inputs: inputs.move_map(|(c, input)| { (c, folder.fold_expr(input)) @@ -1292,7 +1293,8 @@ pub fn noop_fold_expr(Expr {id, node, span}: Expr, folder: &mut T) -> clobbers: clobbers, volatile: volatile, alignstack: alignstack, - dialect: dialect + dialect: dialect, + expn_id: expn_id, }), ExprMac(mac) => ExprMac(folder.fold_mac(mac)), ExprStruct(path, fields, maybe_expr) => { diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 7896ce2ba76..1fdaa548ebe 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -871,3 +871,18 @@ extern "C" void LLVMWriteDebugLocToString( raw_rust_string_ostream os(str); unwrap(dl)->print(*unwrap(C), os); } + +DEFINE_SIMPLE_CONVERSION_FUNCTIONS(SMDiagnostic, LLVMSMDiagnosticRef) + +extern "C" void LLVMSetInlineAsmDiagnosticHandler( + LLVMContextRef C, + LLVMContext::InlineAsmDiagHandlerTy H, + void *CX) +{ + unwrap(C)->setInlineAsmDiagnosticHandler(H, CX); +} + +extern "C" void LLVMWriteSMDiagnosticToString(LLVMSMDiagnosticRef d, RustStringRef str) { + raw_rust_string_ostream os(str); + unwrap(d)->print("", os); +} diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index 54b0c2506c7..5469531c541 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -73,6 +73,7 @@ void LLVMRustSetLastError(const char*); typedef struct OpaqueRustString *RustStringRef; typedef struct LLVMOpaqueTwine *LLVMTwineRef; typedef struct LLVMOpaqueDebugLoc *LLVMDebugLocRef; +typedef struct LLVMOpaqueSMDiagnostic *LLVMSMDiagnosticRef; extern "C" void rust_llvm_string_write_impl(RustStringRef str, const char *ptr, size_t size); diff --git a/src/test/compile-fail/asm-src-loc-codegen-units.rs b/src/test/compile-fail/asm-src-loc-codegen-units.rs new file mode 100644 index 00000000000..1b8fb32a808 --- /dev/null +++ b/src/test/compile-fail/asm-src-loc-codegen-units.rs @@ -0,0 +1,20 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +// +// compile-flags: -C codegen-units=2 +// error-pattern: build without -C codegen-units for more exact errors + +#![feature(asm)] + +fn main() { + unsafe { + asm!("nowayisthisavalidinstruction"); + } +} diff --git a/src/test/compile-fail/asm-src-loc.rs b/src/test/compile-fail/asm-src-loc.rs new file mode 100644 index 00000000000..8da6cca77cc --- /dev/null +++ b/src/test/compile-fail/asm-src-loc.rs @@ -0,0 +1,17 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(asm)] + +fn main() { + unsafe { + asm!("nowayisthisavalidinstruction"); //~ ERROR invalid instruction mnemonic + } +} -- cgit 1.4.1-3-g733a5 From 8826fdfe37a7cbf901ddced1d7e2b4320e117461 Mon Sep 17 00:00:00 2001 From: Keegan McAllister Date: Sun, 28 Sep 2014 09:25:48 -0700 Subject: Keep ExpnId abstract by providing conversions --- mk/crates.mk | 2 +- src/librustc/back/write.rs | 2 +- src/librustc/middle/trans/asm.rs | 2 +- src/libsyntax/ast.rs | 4 ++-- src/libsyntax/codemap.rs | 16 ++++++++++++++-- src/libsyntax/ext/asm.rs | 2 +- src/libsyntax/lib.rs | 1 + 7 files changed, 21 insertions(+), 8 deletions(-) (limited to 'src/libsyntax') diff --git a/mk/crates.mk b/mk/crates.mk index ed3fce775f3..9f01ff23c7f 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -71,7 +71,7 @@ DEPS_graphviz := std DEPS_green := std native:context_switch DEPS_rustuv := std native:uv native:uv_support DEPS_native := std -DEPS_syntax := std term serialize log fmt_macros debug arena +DEPS_syntax := std term serialize log fmt_macros debug arena libc DEPS_rustc := syntax flate arena serialize getopts rbml \ time log graphviz debug rustc_llvm rustc_back DEPS_rustc_llvm := native:rustllvm libc std diff --git a/src/librustc/back/write.rs b/src/librustc/back/write.rs index 8e703d954f3..7b4d1780ccd 100644 --- a/src/librustc/back/write.rs +++ b/src/librustc/back/write.rs @@ -345,7 +345,7 @@ unsafe extern "C" fn inline_asm_handler(diag: SMDiagnosticRef, match cgcx.lto_ctxt { Some((sess, _)) => { - sess.codemap().with_expn_info(ExpnId(cookie as u32), |info| match info { + sess.codemap().with_expn_info(ExpnId::from_llvm_cookie(cookie), |info| match info { Some(ei) => sess.span_err(ei.call_site, msg.as_slice()), None => sess.err(msg.as_slice()), }); diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index b4c10c78db8..c51e2420262 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -149,7 +149,7 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm) let kind = llvm::LLVMGetMDKindIDInContext(bcx.ccx().llcx(), key.as_ptr() as *const c_char, key.len() as c_uint); - let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id as i32); + let val: llvm::ValueRef = C_i32(bcx.ccx(), ia.expn_id.to_llvm_cookie()); llvm::LLVMSetMetadata(r, kind, llvm::LLVMMDNodeInContext(bcx.ccx().llcx(), &val, 1)); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 43d6b9b9e90..0fee3ff3218 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -10,7 +10,7 @@ // The Rust abstract syntax tree. -use codemap::{Span, Spanned, DUMMY_SP}; +use codemap::{Span, Spanned, DUMMY_SP, ExpnId}; use abi::Abi; use ast_util; use owned_slice::OwnedSlice; @@ -984,7 +984,7 @@ pub struct InlineAsm { pub volatile: bool, pub alignstack: bool, pub dialect: AsmDialect, - pub expn_id: u32, + pub expn_id: ExpnId, } /// represents an argument in a function header diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index d44de7862a3..e9b2556c53e 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -26,6 +26,7 @@ source code snippets, etc. use serialize::{Encodable, Decodable, Encoder, Decoder}; use std::cell::RefCell; use std::rc::Rc; +use libc::c_uint; pub trait Pos { fn from_uint(n: uint) -> Self; @@ -223,11 +224,22 @@ pub struct ExpnInfo { pub callee: NameAndSpan } -#[deriving(PartialEq, Eq, Clone, Show, Hash)] -pub struct ExpnId(pub u32); +#[deriving(PartialEq, Eq, Clone, Show, Hash, Encodable, Decodable)] +pub struct ExpnId(u32); pub static NO_EXPANSION: ExpnId = ExpnId(-1); +impl ExpnId { + pub fn from_llvm_cookie(cookie: c_uint) -> ExpnId { + ExpnId(cookie as u32) + } + + pub fn to_llvm_cookie(self) -> i32 { + let ExpnId(cookie) = self; + cookie as i32 + } +} + pub type FileName = String; pub struct FileLines { diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index f82fe4b13a2..702be0c0eee 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -199,7 +199,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree]) } } - let codemap::ExpnId(expn_id) = cx.codemap().record_expansion(codemap::ExpnInfo { + let expn_id = cx.codemap().record_expansion(codemap::ExpnInfo { call_site: sp, callee: codemap::NameAndSpan { name: "asm".to_string(), diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 7a504d22c1e..a4271544146 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -33,6 +33,7 @@ extern crate debug; #[phase(plugin, link)] extern crate log; extern crate serialize; extern crate term; +extern crate libc; pub mod util { pub mod interner; -- cgit 1.4.1-3-g733a5