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
|
@ -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!()
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue