1
Fork 0

Reimplement lowering of sym operands for asm! so that it also works with global_asm!

This commit is contained in:
Amanieu d'Antras 2022-03-01 00:50:56 +00:00
parent f9d4d12b6a
commit dc345d8bff
28 changed files with 400 additions and 163 deletions

View file

@ -1,12 +1,17 @@
use crate::{ImplTraitContext, ImplTraitPosition, ParamMode};
use super::LoweringContext;
use rustc_ast::ptr::P;
use rustc_ast::*;
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_set::FxHashSet;
use rustc_errors::struct_span_err;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::definitions::DefPathData;
use rustc_session::parse::feature_err;
use rustc_span::{sym, Span};
use rustc_span::{sym, ExpnId, Span};
use rustc_target::asm;
use std::collections::hash_map::Entry;
use std::fmt::Write;
@ -188,7 +193,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
anon_const: self.lower_anon_const(anon_const),
}
}
InlineAsmOperand::Sym { ref expr } => {
InlineAsmOperand::Sym { ref sym } => {
if !self.sess.features_untracked().asm_sym {
feature_err(
&self.sess.parse_sess,
@ -198,7 +203,54 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
)
.emit();
}
hir::InlineAsmOperand::Sym { expr: self.lower_expr_mut(expr) }
let static_def_id = self
.resolver
.get_partial_res(sym.id)
.filter(|res| res.unresolved_segments() == 0)
.and_then(|res| {
if let Res::Def(DefKind::Static(_), def_id) = res.base_res() {
Some(def_id)
} else {
None
}
});
if let Some(def_id) = static_def_id {
let path = self.lower_qpath(
sym.id,
&sym.qself,
&sym.path,
ParamMode::Optional,
ImplTraitContext::Disallowed(ImplTraitPosition::Path),
);
hir::InlineAsmOperand::SymStatic { path, def_id }
} else {
// Replace the InlineAsmSym AST node with an
// Expr using the name node id.
let expr = Expr {
id: sym.id,
kind: ExprKind::Path(sym.qself.clone(), sym.path.clone()),
span: *op_sp,
attrs: AttrVec::new(),
tokens: None,
};
// Wrap the expression in an AnonConst.
let parent_def_id = self.current_hir_id_owner;
let node_id = self.resolver.next_node_id();
self.resolver.create_def(
parent_def_id,
node_id,
DefPathData::AnonConst,
ExpnId::root(),
*op_sp,
);
let anon_const = AnonConst { id: node_id, value: P(expr) };
hir::InlineAsmOperand::SymFn {
anon_const: self.lower_anon_const(&anon_const),
}
}
}
};
(op, self.lower_span(*op_sp))
@ -260,7 +312,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
err.span_label(op_sp, "argument");
err.emit();
}
hir::InlineAsmOperand::Sym { .. } => {
hir::InlineAsmOperand::SymFn { .. }
| hir::InlineAsmOperand::SymStatic { .. } => {
let mut err = sess.struct_span_err(
placeholder_span,
"asm template modifiers are not allowed for `sym` arguments",
@ -308,7 +361,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::InlineAsmOperand::InOut { .. }
| hir::InlineAsmOperand::SplitInOut { .. } => (true, true),
hir::InlineAsmOperand::Const { .. } | hir::InlineAsmOperand::Sym { .. } => {
hir::InlineAsmOperand::Const { .. }
| hir::InlineAsmOperand::SymFn { .. }
| hir::InlineAsmOperand::SymStatic { .. } => {
unreachable!()
}
};