Reimplement lowering of sym operands for asm! so that it also works with global_asm!
This commit is contained in:
parent
f9d4d12b6a
commit
dc345d8bff
28 changed files with 400 additions and 163 deletions
|
@ -2061,6 +2061,20 @@ impl InlineAsmTemplatePiece {
|
|||
}
|
||||
}
|
||||
|
||||
/// Inline assembly symbol operands get their own AST node that is somewhat
|
||||
/// similar to `AnonConst`.
|
||||
///
|
||||
/// The main difference is that we specifically don't assign it `DefId` in
|
||||
/// `DefCollector`. Instead this is deferred until AST lowering where we
|
||||
/// lower it to an `AnonConst` (for functions) or a `Path` (for statics)
|
||||
/// depending on what the path resolves to.
|
||||
#[derive(Clone, Encodable, Decodable, Debug)]
|
||||
pub struct InlineAsmSym {
|
||||
pub id: NodeId,
|
||||
pub qself: Option<QSelf>,
|
||||
pub path: Path,
|
||||
}
|
||||
|
||||
/// Inline assembly operand.
|
||||
///
|
||||
/// E.g., `out("eax") result` as in `asm!("mov eax, 2", out("eax") result)`.
|
||||
|
@ -2090,7 +2104,7 @@ pub enum InlineAsmOperand {
|
|||
anon_const: AnonConst,
|
||||
},
|
||||
Sym {
|
||||
expr: P<Expr>,
|
||||
sym: InlineAsmSym,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -280,6 +280,14 @@ pub trait MutVisitor: Sized {
|
|||
fn flat_map_pat_field(&mut self, fp: PatField) -> SmallVec<[PatField; 1]> {
|
||||
noop_flat_map_pat_field(fp, self)
|
||||
}
|
||||
|
||||
fn visit_inline_asm(&mut self, asm: &mut InlineAsm) {
|
||||
noop_visit_inline_asm(asm, self)
|
||||
}
|
||||
|
||||
fn visit_inline_asm_sym(&mut self, sym: &mut InlineAsmSym) {
|
||||
noop_visit_inline_asm_sym(sym, self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Use a map-style function (`FnOnce(T) -> T`) to overwrite a `&mut T`. Useful
|
||||
|
@ -1019,7 +1027,7 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
|||
}
|
||||
}
|
||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||
ItemKind::GlobalAsm(asm) => noop_visit_inline_asm(asm, vis),
|
||||
ItemKind::GlobalAsm(asm) => vis.visit_inline_asm(asm),
|
||||
ItemKind::TyAlias(box TyAlias {
|
||||
defaultness, generics, where_clauses, bounds, ty, ..
|
||||
}) => {
|
||||
|
@ -1237,13 +1245,12 @@ pub fn noop_visit_anon_const<T: MutVisitor>(AnonConst { id, value }: &mut AnonCo
|
|||
vis.visit_expr(value);
|
||||
}
|
||||
|
||||
fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
|
||||
pub fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
|
||||
for (op, _) in &mut asm.operands {
|
||||
match op {
|
||||
InlineAsmOperand::In { expr, .. }
|
||||
| InlineAsmOperand::Out { expr: Some(expr), .. }
|
||||
| InlineAsmOperand::InOut { expr, .. }
|
||||
| InlineAsmOperand::Sym { expr, .. } => vis.visit_expr(expr),
|
||||
| InlineAsmOperand::InOut { expr, .. } => vis.visit_expr(expr),
|
||||
InlineAsmOperand::Out { expr: None, .. } => {}
|
||||
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
|
||||
vis.visit_expr(in_expr);
|
||||
|
@ -1251,11 +1258,21 @@ fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
|
|||
vis.visit_expr(out_expr);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Const { anon_const, .. } => vis.visit_anon_const(anon_const),
|
||||
InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
|
||||
InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn noop_visit_inline_asm_sym<T: MutVisitor>(
|
||||
InlineAsmSym { id, qself, path }: &mut InlineAsmSym,
|
||||
vis: &mut T,
|
||||
) {
|
||||
vis.visit_id(id);
|
||||
vis.visit_qself(qself);
|
||||
vis.visit_path(path);
|
||||
}
|
||||
|
||||
pub fn noop_visit_expr<T: MutVisitor>(
|
||||
Expr { kind, id, span, attrs, tokens }: &mut Expr,
|
||||
vis: &mut T,
|
||||
|
@ -1374,7 +1391,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
|
|||
ExprKind::Ret(expr) => {
|
||||
visit_opt(expr, |expr| vis.visit_expr(expr));
|
||||
}
|
||||
ExprKind::InlineAsm(asm) => noop_visit_inline_asm(asm, vis),
|
||||
ExprKind::InlineAsm(asm) => vis.visit_inline_asm(asm),
|
||||
ExprKind::MacCall(mac) => vis.visit_mac_call(mac),
|
||||
ExprKind::Struct(se) => {
|
||||
let StructExpr { qself, path, fields, rest } = se.deref_mut();
|
||||
|
|
|
@ -214,6 +214,12 @@ pub trait Visitor<'ast>: Sized {
|
|||
fn visit_crate(&mut self, krate: &'ast Crate) {
|
||||
walk_crate(self, krate)
|
||||
}
|
||||
fn visit_inline_asm(&mut self, asm: &'ast InlineAsm) {
|
||||
walk_inline_asm(self, asm)
|
||||
}
|
||||
fn visit_inline_asm_sym(&mut self, sym: &'ast InlineAsmSym) {
|
||||
walk_inline_asm_sym(self, sym)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
|
@ -717,13 +723,12 @@ pub fn walk_anon_const<'a, V: Visitor<'a>>(visitor: &mut V, constant: &'a AnonCo
|
|||
visitor.visit_expr(&constant.value);
|
||||
}
|
||||
|
||||
fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
|
||||
pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
|
||||
for (op, _) in &asm.operands {
|
||||
match op {
|
||||
InlineAsmOperand::In { expr, .. }
|
||||
| InlineAsmOperand::Out { expr: Some(expr), .. }
|
||||
| InlineAsmOperand::InOut { expr, .. }
|
||||
| InlineAsmOperand::Sym { expr, .. } => visitor.visit_expr(expr),
|
||||
| InlineAsmOperand::InOut { expr, .. } => visitor.visit_expr(expr),
|
||||
InlineAsmOperand::Out { expr: None, .. } => {}
|
||||
InlineAsmOperand::SplitInOut { in_expr, out_expr, .. } => {
|
||||
visitor.visit_expr(in_expr);
|
||||
|
@ -732,10 +737,18 @@ fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm) {
|
|||
}
|
||||
}
|
||||
InlineAsmOperand::Const { anon_const, .. } => visitor.visit_anon_const(anon_const),
|
||||
InlineAsmOperand::Sym { sym } => visitor.visit_inline_asm_sym(sym),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn walk_inline_asm_sym<'a, V: Visitor<'a>>(visitor: &mut V, sym: &'a InlineAsmSym) {
|
||||
if let Some(ref qself) = sym.qself {
|
||||
visitor.visit_ty(&qself.ty);
|
||||
}
|
||||
visitor.visit_path(&sym.path, sym.id);
|
||||
}
|
||||
|
||||
pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
|
||||
walk_list!(visitor, visit_attribute, expression.attrs.iter());
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue