use rustc_expand::base::{self, *};
use rustc_parse::parser::Parser;
use rustc_parse_format as parse;
-use rustc_span::{
- symbol::{kw, sym, Symbol},
- BytePos,
-};
+use rustc_session::lint;
+use rustc_span::symbol::{kw, sym, Symbol};
use rustc_span::{InnerSpan, Span};
+use rustc_target::asm::InlineAsmArch;
struct AsmArgs {
templates: Vec<P<ast::Expr>>,
ast::InlineAsmOperand::InOut { reg, expr, late: true }
}
} else if p.eat_keyword(kw::Const) {
- let expr = p.parse_expr()?;
- ast::InlineAsmOperand::Const { expr }
+ let anon_const = p.parse_anon_const_expr()?;
+ ast::InlineAsmOperand::Const { anon_const }
} else if p.eat_keyword(sym::sym) {
let expr = p.parse_expr()?;
match expr.kind {
let mut line_spans = Vec::with_capacity(args.templates.len());
let mut curarg = 0;
- let default_dialect = ecx.sess.inline_asm_dialect();
-
for template_expr in args.templates.into_iter() {
if !template.is_empty() {
template.push(ast::InlineAsmTemplatePiece::String("\n".to_string()));
let template_str = &template_str.as_str();
let template_snippet = ecx.source_map().span_to_snippet(template_sp).ok();
- if let Some(snippet) = &template_snippet {
- let snippet = snippet.trim_matches('"');
- match default_dialect {
- ast::LlvmAsmDialect::Intel => {
- if let Some(span) = check_syntax_directive(snippet, ".intel_syntax") {
- let span = template_span.from_inner(span);
- let mut err = ecx.struct_span_err(span, "intel syntax is the default syntax on this target, and trying to use this directive may cause issues");
- err.span_suggestion(
- span,
- "remove this assembler directive",
- "".to_string(),
- Applicability::MachineApplicable,
- );
- err.emit();
- }
-
- if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
- let span = template_span.from_inner(span);
- let mut err = ecx.struct_span_err(span, "using the .att_syntax directive may cause issues, use the att_syntax option instead");
- let asm_end = sp.hi() - BytePos(2);
- let suggestions = vec![
- (span, "".to_string()),
- (
- Span::new(asm_end, asm_end, sp.ctxt()),
- ", options(att_syntax)".to_string(),
- ),
- ];
- err.multipart_suggestion(
- "remove the assembler directive and replace it with options(att_syntax)",
- suggestions,
- Applicability::MachineApplicable,
- );
- err.emit();
+ if let Some(InlineAsmArch::X86 | InlineAsmArch::X86_64) = ecx.sess.asm_arch {
+ let find_span = |needle: &str| -> Span {
+ if let Some(snippet) = &template_snippet {
+ if let Some(pos) = snippet.find(needle) {
+ let end = pos
+ + &snippet[pos..]
+ .find(|c| matches!(c, '\n' | ';' | '\\' | '"'))
+ .unwrap_or(snippet[pos..].len() - 1);
+ let inner = InnerSpan::new(pos, end);
+ return template_sp.from_inner(inner);
}
}
- ast::LlvmAsmDialect::Att => {
- if let Some(span) = check_syntax_directive(snippet, ".att_syntax") {
- let span = template_span.from_inner(span);
- let mut err = ecx.struct_span_err(span, "att syntax is the default syntax on this target, and trying to use this directive may cause issues");
- err.span_suggestion(
- span,
- "remove this assembler directive",
- "".to_string(),
- Applicability::MachineApplicable,
- );
- err.emit();
- }
+ template_sp
+ };
- // Use of .intel_syntax is ignored
- }
+ if template_str.contains(".intel_syntax") {
+ ecx.parse_sess().buffer_lint(
+ lint::builtin::BAD_ASM_STYLE,
+ find_span(".intel_syntax"),
+ ecx.resolver.lint_node_id(ecx.current_expansion.id),
+ "avoid using `.intel_syntax`, Intel syntax is the default",
+ );
+ }
+ if template_str.contains(".att_syntax") {
+ ecx.parse_sess().buffer_lint(
+ lint::builtin::BAD_ASM_STYLE,
+ find_span(".att_syntax"),
+ ecx.resolver.lint_node_id(ecx.current_expansion.id),
+ "avoid using `.att_syntax`, prefer using `options(att_syntax)` instead",
+ );
}
}
}
}
}
-
-fn check_syntax_directive<S: AsRef<str>>(piece: S, syntax: &str) -> Option<InnerSpan> {
- let piece = piece.as_ref();
- if let Some(idx) = piece.find(syntax) {
- let end =
- idx + &piece[idx..].find(|c| matches!(c, '\n' | ';')).unwrap_or(piece[idx..].len());
- // Offset by one because these represent the span with the " removed
- Some(InnerSpan::new(idx + 1, end + 1))
- } else {
- None
- }
-}