Skip to content

Commit 408cfef

Browse files
committed
extract operand parser
1 parent d3157c9 commit 408cfef

File tree

1 file changed

+93
-83
lines changed
  • compiler/rustc_builtin_macros/src

1 file changed

+93
-83
lines changed

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+
fn parse_asm_operand<'a>(
73+
p: &mut Parser<'a>,
74+
asm_macro: AsmMacro,
75+
) -> PResult<'a, Option<ast::InlineAsmOperand>> {
76+
let dcx = p.dcx();
77+
78+
Ok(Some(if eat_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+
return Err(err);
83+
}
84+
let expr = p.parse_expr()?;
85+
ast::InlineAsmOperand::In { reg, expr }
86+
} else if eat_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+
} else if eat_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+
} else if eat_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+
return Err(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+
} else if eat_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+
return Err(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+
} else if eat_operand_keyword(p, exp!(Label), asm_macro)? {
123+
let block = p.parse_block()?;
124+
ast::InlineAsmOperand::Label { block }
125+
} else if p.eat_keyword(exp!(Const)) {
126+
let anon_const = p.parse_expr_anon_const()?;
127+
ast::InlineAsmOperand::Const { anon_const }
128+
} else if p.eat_keyword(exp!(Sym)) {
129+
let expr = p.parse_expr()?;
130+
let ast::ExprKind::Path(qself, path) = &expr.kind else {
131+
let err = dcx.create_err(errors::AsmSymNoPath { span: expr.span });
132+
return Err(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+
return Ok(None);
139+
}))
140+
}
141+
72142
// Primarily public for rustfmt consumption.
73143
// Internal consumers should continue to leverage `expand_asm`/`expand__global_asm`
74144
pub fn parse_asm_args<'a>(
@@ -135,91 +205,31 @@ pub fn parse_asm_args<'a>(
135205
None
136206
};
137207

138-
let op = if eat_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-
return Err(err);
143-
}
144-
let expr = p.parse_expr()?;
145-
ast::InlineAsmOperand::In { reg, expr }
146-
} else if eat_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-
} else if eat_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-
} else if eat_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-
return Err(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-
} else if eat_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-
return Err(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-
} else if eat_operand_keyword(p, exp!(Label), asm_macro)? {
183-
let block = p.parse_block()?;
184-
ast::InlineAsmOperand::Label { block }
185-
} else if p.eat_keyword(exp!(Const)) {
186-
let anon_const = p.parse_expr_anon_const()?;
187-
ast::InlineAsmOperand::Const { anon_const }
188-
} else if p.eat_keyword(exp!(Sym)) {
189-
let expr = p.parse_expr()?;
190-
let ast::ExprKind::Path(qself, path) = &expr.kind else {
191-
let err = dcx.create_err(errors::AsmSymNoPath { span: expr.span });
192-
return Err(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-
} else if 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-
if matches!(
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-
return Err(err);
208+
let Some(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+
if matches!(
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+
return Err(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)