diff options
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-asm.cc | 84 | ||||
-rw-r--r-- | gcc/rust/expand/rust-macro-builtins-asm.h | 8 |
2 files changed, 85 insertions, 7 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc index 74b81d2..971dd7b 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.cc +++ b/gcc/rust/expand/rust-macro-builtins-asm.cc @@ -79,6 +79,8 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId last_token_id, // illegal, pleaes emit the correct error. return -1; } + + token = parser.peek_current_token (); } // Done processing the local clobber abis, push that to the main Args in @@ -92,12 +94,26 @@ parse_clobber_abi (Parser<MacroInvocLexer> &parser, TokenId last_token_id, return 0; } +void +check_and_set (Parser<MacroInvocLexer> &p, AsmArg &args, std::string option) +{ + if (args.options.count (option) == 1) + { + // TODO: report an error of duplication + + return; + } + else + { + args.options.insert (option); + } +} int parse_options (Parser<MacroInvocLexer> &parser, TokenId last_token_id, AsmArg &args, bool is_global_asm) { // Parse everything commitedly - if (!p.skip_token (LEFT_PAREN)) + if (!parser.skip_token (LEFT_PAREN)) { // We have shifted `options` to search for the left parenthesis next, we // should error out if this is not possible. @@ -108,9 +124,73 @@ parse_options (Parser<MacroInvocLexer> &parser, TokenId last_token_id, auto token = parser.peek_current_token (); while (token->get_id () != last_token_id && token->get_id () != RIGHT_PAREN) { - parser.skip_token (); + if (!is_global_asm && check_identifier (parser, "pure")) + { + check_and_set (parser, args, "pure"); + } + else if (!is_global_asm && check_identifier (parser, "nomem")) + { + check_and_set (parser, args, "nomem"); + } + else if (!is_global_asm && check_identifier (parser, "readonly")) + { + check_and_set (parser, args, "readonly"); + } + else if (!is_global_asm && check_identifier (parser, "preserves_flags")) + { + check_and_set (parser, args, "preserves_flags"); + } + else if (!is_global_asm && check_identifier (parser, "noreturn")) + { + check_and_set (parser, args, "noreturn"); + } + else if (!is_global_asm && check_identifier (parser, "noreturn")) + { + check_and_set (parser, args, "noreturn"); + } + else if (!is_global_asm && check_identifier (parser, "nostack")) + { + check_and_set (parser, args, "nostack"); + } + else if (!is_global_asm && check_identifier (parser, "may_unwind")) + { + check_and_set (parser, args, "may_unwind"); + } + else if (check_identifier (parser, "att_syntax")) + { + check_and_set (parser, args, "att_syntax"); + } + else if (check_identifier (parser, "raw")) + { + check_and_set (parser, args, "raw"); + } + else + { + // TODO: Unexpected error, please return the correct error + rust_error_at (token->get_locus (), + "Unexpected token encountered in parse_options"); + } + if (!parser.skip_token (RIGHT_PAREN)) + { + break; + } + + if (!parser.skip_token (COMMA)) + { + // TODO: If the skip of comma is unsuccessful, which should be + // illegal, pleaes emit the correct error. + return -1; + } + token = parser.peek_current_token (); } + + // TODO: Per rust asm.rs regarding options_spans + // I'm guessing this has to do with some error reporting. + // let new_span = span_start.to(p.prev_token.span); + // args.options_spans.push(new_span); + + return 0; } bool check_identifier (Parser<MacroInvocLexer> &p, std::string ident) diff --git a/gcc/rust/expand/rust-macro-builtins-asm.h b/gcc/rust/expand/rust-macro-builtins-asm.h index ebb939a..fd86c309 100644 --- a/gcc/rust/expand/rust-macro-builtins-asm.h +++ b/gcc/rust/expand/rust-macro-builtins-asm.h @@ -21,11 +21,6 @@ enum InlineAsmDirSpec Label, // TODO: This is not present in ABNF }; -enum InlineAsmOptions -{ - -}; - // Place holder for classes enum InlineAsmRegOrRegClass { @@ -39,6 +34,7 @@ typedef std::vector<InlineAsmDirSpec> Operands; typedef std::map<std::string, int> RegisterArgs; typedef std::vector<symbol_name> ClobberAbis; typedef std::map<symbol_name, int> NamedValues; +typedef std::set<std::string> InlineAsmOptions; struct AsmArg { @@ -70,6 +66,8 @@ parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc, bool check_identifier (Parser<MacroInvocLexer> &p, std::string ident); +void +check_and_set (Parser<MacroInvocLexer> &p, AsmArg &args, std::string option); // From rustc int parse_operand (Parser<MacroInvocLexer> &parser, TokenId last_token_id, |