@@ -310,6 +310,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
310
310
p. dcx ( ) . emit_err ( errors:: AsmOptAlreadyprovided { span, symbol, full_span } ) ;
311
311
}
312
312
313
+ /// Report an invalid option error.
314
+ ///
315
+ /// This function must be called immediately after the option token is parsed.
316
+ /// Otherwise, the suggestion will be incorrect.
317
+ fn err_unsupported_option ( p : & Parser < ' _ > , symbol : Symbol , span : Span ) {
318
+ // Tool-only output
319
+ let full_span = if p. token . kind == token:: Comma { span. to ( p. token . span ) } else { span } ;
320
+ p. dcx ( ) . emit_err ( errors:: GlobalAsmUnsupportedOption { span, symbol, full_span } ) ;
321
+ }
322
+
313
323
/// Try to set the provided option in the provided `AsmArgs`.
314
324
/// If it is already set, report a duplicate option error.
315
325
///
@@ -318,13 +328,16 @@ fn err_duplicate_option(p: &Parser<'_>, symbol: Symbol, span: Span) {
318
328
fn try_set_option < ' a > (
319
329
p : & Parser < ' a > ,
320
330
args : & mut AsmArgs ,
331
+ is_global_asm : bool ,
321
332
symbol : Symbol ,
322
333
option : ast:: InlineAsmOptions ,
323
334
) {
324
- if !args . options . contains ( option) {
325
- args . options |= option ;
326
- } else {
335
+ if is_global_asm && !ast :: InlineAsmOptions :: GLOBAL_OPTIONS . contains ( option) {
336
+ err_unsupported_option ( p , symbol , p . prev_token . span ) ;
337
+ } else if args . options . contains ( option ) {
327
338
err_duplicate_option ( p, symbol, p. prev_token . span ) ;
339
+ } else {
340
+ args. options |= option;
328
341
}
329
342
}
330
343
@@ -338,25 +351,33 @@ fn parse_options<'a>(
338
351
p. expect ( & token:: OpenDelim ( Delimiter :: Parenthesis ) ) ?;
339
352
340
353
while !p. eat ( & token:: CloseDelim ( Delimiter :: Parenthesis ) ) {
341
- if !is_global_asm && p. eat_keyword ( sym:: pure) {
342
- try_set_option ( p, args, sym:: pure, ast:: InlineAsmOptions :: PURE ) ;
343
- } else if !is_global_asm && p. eat_keyword ( sym:: nomem) {
344
- try_set_option ( p, args, sym:: nomem, ast:: InlineAsmOptions :: NOMEM ) ;
345
- } else if !is_global_asm && p. eat_keyword ( sym:: readonly) {
346
- try_set_option ( p, args, sym:: readonly, ast:: InlineAsmOptions :: READONLY ) ;
347
- } else if !is_global_asm && p. eat_keyword ( sym:: preserves_flags) {
348
- try_set_option ( p, args, sym:: preserves_flags, ast:: InlineAsmOptions :: PRESERVES_FLAGS ) ;
349
- } else if !is_global_asm && p. eat_keyword ( sym:: noreturn) {
350
- try_set_option ( p, args, sym:: noreturn, ast:: InlineAsmOptions :: NORETURN ) ;
351
- } else if !is_global_asm && p. eat_keyword ( sym:: nostack) {
352
- try_set_option ( p, args, sym:: nostack, ast:: InlineAsmOptions :: NOSTACK ) ;
353
- } else if !is_global_asm && p. eat_keyword ( sym:: may_unwind) {
354
- try_set_option ( p, args, kw:: Raw , ast:: InlineAsmOptions :: MAY_UNWIND ) ;
355
- } else if p. eat_keyword ( sym:: att_syntax) {
356
- try_set_option ( p, args, sym:: att_syntax, ast:: InlineAsmOptions :: ATT_SYNTAX ) ;
357
- } else if p. eat_keyword ( kw:: Raw ) {
358
- try_set_option ( p, args, kw:: Raw , ast:: InlineAsmOptions :: RAW ) ;
359
- } else {
354
+ const OPTIONS : [ ( Symbol , ast:: InlineAsmOptions ) ; ast:: InlineAsmOptions :: COUNT ] = [
355
+ ( sym:: pure, ast:: InlineAsmOptions :: PURE ) ,
356
+ ( sym:: nomem, ast:: InlineAsmOptions :: NOMEM ) ,
357
+ ( sym:: readonly, ast:: InlineAsmOptions :: READONLY ) ,
358
+ ( sym:: preserves_flags, ast:: InlineAsmOptions :: PRESERVES_FLAGS ) ,
359
+ ( sym:: noreturn, ast:: InlineAsmOptions :: NORETURN ) ,
360
+ ( sym:: nostack, ast:: InlineAsmOptions :: NOSTACK ) ,
361
+ ( sym:: may_unwind, ast:: InlineAsmOptions :: MAY_UNWIND ) ,
362
+ ( sym:: att_syntax, ast:: InlineAsmOptions :: ATT_SYNTAX ) ,
363
+ ( kw:: Raw , ast:: InlineAsmOptions :: RAW ) ,
364
+ ] ;
365
+
366
+ ' blk: {
367
+ for ( symbol, option) in OPTIONS {
368
+ let kw_matched =
369
+ if !is_global_asm || ast:: InlineAsmOptions :: GLOBAL_OPTIONS . contains ( option) {
370
+ p. eat_keyword ( symbol)
371
+ } else {
372
+ p. eat_keyword_noexpect ( symbol)
373
+ } ;
374
+
375
+ if kw_matched {
376
+ try_set_option ( p, args, is_global_asm, symbol, option) ;
377
+ break ' blk;
378
+ }
379
+ }
380
+
360
381
return p. unexpected ( ) ;
361
382
}
362
383
0 commit comments