Skip to content

Commit 5af9652

Browse files
committed
extract operand parser
1 parent cd22c1b commit 5af9652

1 file changed

Lines changed: 93 additions & 83 deletions

File tree

  • compiler/rustc_builtin_macros/src

‎compiler/rustc_builtin_macros/src/asm.rs‎

Lines changed: 93 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,76 @@ fn parse_args<'a>(
6969
parse_asm_args(&mut p, sp, asm_macro)
7070
}
7171

72+
fnparse_asm_operand<'a>(
73+
p:&mutParser<'a>,
74+
asm_macro:AsmMacro,
75+
) -> PResult<'a,Option<ast::InlineAsmOperand>>{
76+
let dcx = p.dcx();
77+
78+
Ok(Some(ifeat_operand_keyword(p,exp!(In), asm_macro)? {
79+
let reg = parse_reg(p)?;
80+
if p.eat_keyword(exp!(Underscore)){
81+
let err = dcx.create_err(errors::AsmUnderscoreInput{span: p.token.span});
82+
returnErr(err);
83+
}
84+
let expr = p.parse_expr()?;
85+
ast::InlineAsmOperand::In{ reg, expr }
86+
}elseifeat_operand_keyword(p,exp!(Out), asm_macro)? {
87+
let reg = parse_reg(p)?;
88+
let expr = if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
89+
ast::InlineAsmOperand::Out{ reg, expr,late:false}
90+
}elseifeat_operand_keyword(p,exp!(Lateout), asm_macro)? {
91+
let reg = parse_reg(p)?;
92+
let expr = if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
93+
ast::InlineAsmOperand::Out{ reg, expr,late:true}
94+
}elseifeat_operand_keyword(p,exp!(Inout), asm_macro)? {
95+
let reg = parse_reg(p)?;
96+
if p.eat_keyword(exp!(Underscore)){
97+
let err = dcx.create_err(errors::AsmUnderscoreInput{span: p.token.span});
98+
returnErr(err);
99+
}
100+
let expr = p.parse_expr()?;
101+
if p.eat(exp!(FatArrow)){
102+
let out_expr =
103+
if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
104+
ast::InlineAsmOperand::SplitInOut{ reg,in_expr: expr, out_expr,late:false}
105+
}else{
106+
ast::InlineAsmOperand::InOut{ reg, expr,late:false}
107+
}
108+
}elseifeat_operand_keyword(p,exp!(Inlateout), asm_macro)? {
109+
let reg = parse_reg(p)?;
110+
if p.eat_keyword(exp!(Underscore)){
111+
let err = dcx.create_err(errors::AsmUnderscoreInput{span: p.token.span});
112+
returnErr(err);
113+
}
114+
let expr = p.parse_expr()?;
115+
if p.eat(exp!(FatArrow)){
116+
let out_expr =
117+
if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
118+
ast::InlineAsmOperand::SplitInOut{ reg,in_expr: expr, out_expr,late:true}
119+
}else{
120+
ast::InlineAsmOperand::InOut{ reg, expr,late:true}
121+
}
122+
}elseifeat_operand_keyword(p,exp!(Label), asm_macro)? {
123+
let block = p.parse_block()?;
124+
ast::InlineAsmOperand::Label{ block }
125+
}elseif p.eat_keyword(exp!(Const)){
126+
let anon_const = p.parse_expr_anon_const()?;
127+
ast::InlineAsmOperand::Const{ anon_const }
128+
}elseif p.eat_keyword(exp!(Sym)){
129+
let expr = p.parse_expr()?;
130+
let ast::ExprKind::Path(qself, path) = &expr.kindelse{
131+
let err = dcx.create_err(errors::AsmSymNoPath{span: expr.span});
132+
returnErr(err);
133+
};
134+
let sym =
135+
ast::InlineAsmSym{id: ast::DUMMY_NODE_ID,qself: qself.clone(),path: path.clone()};
136+
ast::InlineAsmOperand::Sym{ sym }
137+
}else{
138+
returnOk(None);
139+
}))
140+
}
141+
72142
// Primarily public for rustfmt consumption.
73143
// Internal consumers should continue to leverage `expand_asm`/`expand__global_asm`
74144
pubfnparse_asm_args<'a>(
@@ -135,91 +205,31 @@ pub fn parse_asm_args<'a>(
135205
None
136206
};
137207

138-
let op = ifeat_operand_keyword(p,exp!(In), asm_macro)? {
139-
let reg = parse_reg(p)?;
140-
if p.eat_keyword(exp!(Underscore)){
141-
let err = dcx.create_err(errors::AsmUnderscoreInput{span: p.token.span});
142-
returnErr(err);
143-
}
144-
let expr = p.parse_expr()?;
145-
ast::InlineAsmOperand::In{ reg, expr }
146-
}elseifeat_operand_keyword(p,exp!(Out), asm_macro)? {
147-
let reg = parse_reg(p)?;
148-
let expr = if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
149-
ast::InlineAsmOperand::Out{ reg, expr,late:false}
150-
}elseifeat_operand_keyword(p,exp!(Lateout), asm_macro)? {
151-
let reg = parse_reg(p)?;
152-
let expr = if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
153-
ast::InlineAsmOperand::Out{ reg, expr,late:true}
154-
}elseifeat_operand_keyword(p,exp!(Inout), asm_macro)? {
155-
let reg = parse_reg(p)?;
156-
if p.eat_keyword(exp!(Underscore)){
157-
let err = dcx.create_err(errors::AsmUnderscoreInput{span: p.token.span});
158-
returnErr(err);
159-
}
160-
let expr = p.parse_expr()?;
161-
if p.eat(exp!(FatArrow)){
162-
let out_expr =
163-
if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
164-
ast::InlineAsmOperand::SplitInOut{ reg,in_expr: expr, out_expr,late:false}
165-
}else{
166-
ast::InlineAsmOperand::InOut{ reg, expr,late:false}
167-
}
168-
}elseifeat_operand_keyword(p,exp!(Inlateout), asm_macro)? {
169-
let reg = parse_reg(p)?;
170-
if p.eat_keyword(exp!(Underscore)){
171-
let err = dcx.create_err(errors::AsmUnderscoreInput{span: p.token.span});
172-
returnErr(err);
173-
}
174-
let expr = p.parse_expr()?;
175-
if p.eat(exp!(FatArrow)){
176-
let out_expr =
177-
if p.eat_keyword(exp!(Underscore)){None}else{Some(p.parse_expr()?)};
178-
ast::InlineAsmOperand::SplitInOut{ reg,in_expr: expr, out_expr,late:true}
179-
}else{
180-
ast::InlineAsmOperand::InOut{ reg, expr,late:true}
181-
}
182-
}elseifeat_operand_keyword(p,exp!(Label), asm_macro)? {
183-
let block = p.parse_block()?;
184-
ast::InlineAsmOperand::Label{ block }
185-
}elseif p.eat_keyword(exp!(Const)){
186-
let anon_const = p.parse_expr_anon_const()?;
187-
ast::InlineAsmOperand::Const{ anon_const }
188-
}elseif p.eat_keyword(exp!(Sym)){
189-
let expr = p.parse_expr()?;
190-
let ast::ExprKind::Path(qself, path) = &expr.kindelse{
191-
let err = dcx.create_err(errors::AsmSymNoPath{span: expr.span});
192-
returnErr(err);
193-
};
194-
let sym = ast::InlineAsmSym{
195-
id: ast::DUMMY_NODE_ID,
196-
qself: qself.clone(),
197-
path: path.clone(),
198-
};
199-
ast::InlineAsmOperand::Sym{ sym }
200-
}elseif allow_templates {
201-
let template = p.parse_expr()?;
202-
// If it can't possibly expand to a string, provide diagnostics here to include other
203-
// things it could have been.
204-
match template.kind{
205-
ast::ExprKind::Lit(token_lit)
206-
ifmatches!(
207-
token_lit.kind,
208-
token::LitKind::Str | token::LitKind::StrRaw(_)
209-
) => {}
210-
ast::ExprKind::MacCall(..) => {}
211-
_ => {
212-
let err = dcx.create_err(errors::AsmExpectedOther{
213-
span: template.span,
214-
is_inline_asm:matches!(asm_macro,AsmMacro::Asm),
215-
});
216-
returnErr(err);
208+
letSome(op) = parse_asm_operand(p, asm_macro)? else{
209+
if allow_templates {
210+
let template = p.parse_expr()?;
211+
// If it can't possibly expand to a string, provide diagnostics here to include other
212+
// things it could have been.
213+
match template.kind{
214+
ast::ExprKind::Lit(token_lit)
215+
ifmatches!(
216+
token_lit.kind,
217+
token::LitKind::Str | token::LitKind::StrRaw(_)
218+
) => {}
219+
ast::ExprKind::MacCall(..) => {}
220+
_ => {
221+
let err = dcx.create_err(errors::AsmExpectedOther{
222+
span: template.span,
223+
is_inline_asm:matches!(asm_macro,AsmMacro::Asm),
224+
});
225+
returnErr(err);
226+
}
217227
}
228+
args.templates.push(template);
229+
continue;
230+
}else{
231+
p.unexpected_any()?
218232
}
219-
args.templates.push(template);
220-
continue;
221-
}else{
222-
p.unexpected_any()?
223233
};
224234

225235
let explicit_reg = matches!(op.reg(),Some(ast::InlineAsmRegOrRegClass::Reg(_)));

0 commit comments

Comments
 (0)