diff options
| author | bors <bors@rust-lang.org> | 2022-01-17 09:40:29 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-01-17 09:40:29 +0000 |
| commit | a34c0797528172ede89480e3033f7a5e71ea4735 (patch) | |
| tree | 2040a76ba69e7102179c469e0cc35a0884e628d7 /compiler/rustc_builtin_macros/src | |
| parent | 128417f40f80ce585414bf5a017540447e6be775 (diff) | |
| parent | b085eb0b107a2dc4f426811d000ca4ac82bb71b6 (diff) | |
| download | rust-a34c0797528172ede89480e3033f7a5e71ea4735.tar.gz rust-a34c0797528172ede89480e3033f7a5e71ea4735.zip | |
Auto merge of #92816 - tmiasko:rm-llvm-asm, r=Amanieu
Remove deprecated LLVM-style inline assembly The `llvm_asm!` was deprecated back in #87590 1.56.0, with intention to remove it once `asm!` was stabilized, which already happened in #91728 1.59.0. Now it is time to remove `llvm_asm!` to avoid continued maintenance cost. Closes #70173. Closes #92794. Closes #87612. Closes #82065. cc `@rust-lang/wg-inline-asm` r? `@Amanieu`
Diffstat (limited to 'compiler/rustc_builtin_macros/src')
| -rw-r--r-- | compiler/rustc_builtin_macros/src/asm.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_builtin_macros/src/llvm_asm.rs | 303 |
3 files changed, 0 insertions, 314 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index caf8ac77df1..1a6e5694791 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -50,15 +50,6 @@ pub fn parse_asm_args<'a>( return Err(diag.struct_span_err(sp, "requires at least a template string argument")); } - // Detect use of the legacy llvm_asm! syntax (which used to be called asm!) - if !is_global_asm && p.look_ahead(1, |t| *t == token::Colon || *t == token::ModSep) { - let mut err = - diag.struct_span_err(sp, "the legacy LLVM-style asm! syntax is no longer supported"); - err.note("consider migrating to the new asm! syntax specified in RFC 2873"); - err.note("alternatively, switch to llvm_asm! to keep your code working as it is"); - return Err(err); - } - let first_template = p.parse_expr()?; let mut args = AsmArgs { templates: vec![first_template], diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 8c3ef2864f4..65f785b9097 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -33,7 +33,6 @@ mod env; mod format; mod format_foreign; mod global_allocator; -mod llvm_asm; mod log_syntax; mod panic; mod source_util; @@ -78,7 +77,6 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { include_str: source_util::expand_include_str, include: source_util::expand_include, line: source_util::expand_line, - llvm_asm: llvm_asm::expand_llvm_asm, log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, option_env: env::expand_option_env, diff --git a/compiler/rustc_builtin_macros/src/llvm_asm.rs b/compiler/rustc_builtin_macros/src/llvm_asm.rs deleted file mode 100644 index d72bfa660e5..00000000000 --- a/compiler/rustc_builtin_macros/src/llvm_asm.rs +++ /dev/null @@ -1,303 +0,0 @@ -// Llvm-style inline assembly support. -// -use State::*; - -use rustc_ast as ast; -use rustc_ast::ptr::P; -use rustc_ast::token::{self, Token}; -use rustc_ast::tokenstream::{self, TokenStream}; -use rustc_ast::LlvmAsmDialect; -use rustc_errors::{struct_span_err, DiagnosticBuilder, PResult}; -use rustc_expand::base::*; -use rustc_parse::parser::Parser; -use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; - -enum State { - Asm, - Outputs, - Inputs, - Clobbers, - Options, - StateNone, -} - -impl State { - fn next(&self) -> State { - match *self { - Asm => Outputs, - Outputs => Inputs, - Inputs => Clobbers, - Clobbers => Options, - Options => StateNone, - StateNone => StateNone, - } - } -} - -const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel]; - -pub fn expand_llvm_asm<'cx>( - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - tts: TokenStream, -) -> Box<dyn MacResult + 'cx> { - let mut inline_asm = match parse_inline_asm(cx, sp, tts) { - Ok(Some(inline_asm)) => inline_asm, - Ok(None) => return DummyResult::any(sp), - Err(mut err) => { - err.emit(); - return DummyResult::any(sp); - } - }; - - // If there are no outputs, the inline assembly is executed just for its side effects, - // so ensure that it is volatile - if inline_asm.outputs.is_empty() { - inline_asm.volatile = true; - } - - MacEager::expr(P(ast::Expr { - id: ast::DUMMY_NODE_ID, - kind: ast::ExprKind::LlvmInlineAsm(P(inline_asm)), - span: cx.with_def_site_ctxt(sp), - attrs: ast::AttrVec::new(), - tokens: None, - })) -} - -fn parse_asm_str<'a>(p: &mut Parser<'a>) -> PResult<'a, Symbol> { - match p.parse_str_lit() { - Ok(str_lit) => Ok(str_lit.symbol_unescaped), - Err(opt_lit) => { - let span = opt_lit.map_or(p.token.span, |lit| lit.span); - let mut err = p.sess.span_diagnostic.struct_span_err(span, "expected string literal"); - err.span_label(span, "not a string literal"); - Err(err) - } - } -} - -fn parse_inline_asm<'a>( - cx: &mut ExtCtxt<'a>, - sp: Span, - tts: TokenStream, -) -> Result<Option<ast::LlvmInlineAsm>, DiagnosticBuilder<'a>> { - // Split the tts before the first colon, to avoid `llvm_asm!("x": y)` being - // parsed as `llvm_asm!(z)` with `z = "x": y` which is type ascription. - let first_colon = tts - .trees() - .position(|tt| { - matches!( - tt, - tokenstream::TokenTree::Token(Token { kind: token::Colon | token::ModSep, .. }) - ) - }) - .unwrap_or(tts.len()); - let mut p = cx.new_parser_from_tts(tts.trees().skip(first_colon).collect()); - let mut asm = kw::Empty; - let mut asm_str_style = None; - let mut outputs = Vec::new(); - let mut inputs = Vec::new(); - let mut clobs = Vec::new(); - let mut volatile = false; - let mut alignstack = false; - let mut dialect = LlvmAsmDialect::Att; - - let mut state = Asm; - - 'statement: loop { - match state { - Asm => { - if asm_str_style.is_some() { - // If we already have a string with instructions, - // ending up in Asm state again is an error. - return Err(struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - sp, - E0660, - "malformed inline assembly" - )); - } - // Nested parser, stop before the first colon (see above). - let mut p2 = cx.new_parser_from_tts(tts.trees().take(first_colon).collect()); - - if p2.token == token::Eof { - let mut err = - cx.struct_span_err(sp, "macro requires a string literal as an argument"); - err.span_label(sp, "string literal required"); - return Err(err); - } - - let expr = p2.parse_expr()?; - let (s, style) = - match expr_to_string(cx, expr, "inline assembly must be a string literal") { - Some((s, st)) => (s, st), - None => return Ok(None), - }; - - // This is most likely malformed. - if p2.token != token::Eof { - let mut extra_tts = p2.parse_all_token_trees()?; - extra_tts.extend(tts.trees().skip(first_colon)); - p = cx.new_parser_from_tts(extra_tts.into_iter().collect()); - } - - asm = s; - asm_str_style = Some(style); - } - Outputs => { - while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !outputs.is_empty() { - p.eat(&token::Comma); - } - - let constraint = parse_asm_str(&mut p)?; - - let span = p.prev_token.span; - - p.expect(&token::OpenDelim(token::Paren))?; - let expr = p.parse_expr()?; - p.expect(&token::CloseDelim(token::Paren))?; - - // Expands a read+write operand into two operands. - // - // Use '+' modifier when you want the same expression - // to be both an input and an output at the same time. - // It's the opposite of '=&' which means that the memory - // cannot be shared with any other operand (usually when - // a register is clobbered early.) - let constraint_str = constraint.as_str(); - let mut ch = constraint_str.chars(); - let output = match ch.next() { - Some('=') => None, - Some('+') => Some(Symbol::intern(&format!("={}", ch.as_str()))), - _ => { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - span, - E0661, - "output operand constraint lacks '=' or '+'" - ) - .emit(); - None - } - }; - - let is_rw = output.is_some(); - let is_indirect = constraint_str.contains('*'); - outputs.push(ast::LlvmInlineAsmOutput { - constraint: output.unwrap_or(constraint), - expr, - is_rw, - is_indirect, - }); - } - } - Inputs => { - while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !inputs.is_empty() { - p.eat(&token::Comma); - } - - let constraint = parse_asm_str(&mut p)?; - - if constraint.as_str().starts_with('=') { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - p.prev_token.span, - E0662, - "input operand constraint contains '='" - ) - .emit(); - } else if constraint.as_str().starts_with('+') { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - p.prev_token.span, - E0663, - "input operand constraint contains '+'" - ) - .emit(); - } - - p.expect(&token::OpenDelim(token::Paren))?; - let input = p.parse_expr()?; - p.expect(&token::CloseDelim(token::Paren))?; - - inputs.push((constraint, input)); - } - } - Clobbers => { - while p.token != token::Eof && p.token != token::Colon && p.token != token::ModSep { - if !clobs.is_empty() { - p.eat(&token::Comma); - } - - let s = parse_asm_str(&mut p)?; - - if OPTIONS.iter().any(|&opt| s == opt) { - cx.span_warn(p.prev_token.span, "expected a clobber, found an option"); - } else if s.as_str().starts_with('{') || s.as_str().ends_with('}') { - struct_span_err!( - cx.sess.parse_sess.span_diagnostic, - p.prev_token.span, - E0664, - "clobber should not be surrounded by braces" - ) - .emit(); - } - - clobs.push(s); - } - } - Options => { - let option = parse_asm_str(&mut p)?; - - if option == sym::volatile { - // Indicates that the inline assembly has side effects - // and must not be optimized out along with its outputs. - volatile = true; - } else if option == sym::alignstack { - alignstack = true; - } else if option == sym::intel { - dialect = LlvmAsmDialect::Intel; - } else { - cx.span_warn(p.prev_token.span, "unrecognized option"); - } - - if p.token == token::Comma { - p.eat(&token::Comma); - } - } - StateNone => (), - } - - loop { - // MOD_SEP is a double colon '::' without space in between. - // When encountered, the state must be advanced twice. - match (&p.token.kind, state.next(), state.next().next()) { - (&token::Colon, StateNone, _) | (&token::ModSep, _, StateNone) => { - p.bump(); - break 'statement; - } - (&token::Colon, st, _) | (&token::ModSep, _, st) => { - p.bump(); - state = st; - } - (&token::Eof, ..) => break 'statement, - _ => break, - } - } - } - - Ok(Some(ast::LlvmInlineAsm { - asm, - asm_str_style: asm_str_style.unwrap(), - outputs, - inputs, - clobbers: clobs, - volatile, - alignstack, - dialect, - })) -} |
