aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjjasmine <tanghocle456@gmail.com>2024-05-08 11:06:00 -0700
committerArthur Cohen <arthur.cohen@embecosm.com>2025-03-17 16:35:35 +0100
commitab988c156f9a1a7eed1684b8bb40d05aa757c0f8 (patch)
tree778fab1b1ab1a4ad74b9648a0a1eccd8517b4872 /gcc
parent9e9be0f396e304e27598405ff26f02f0f0a47c96 (diff)
downloadgcc-ab988c156f9a1a7eed1684b8bb40d05aa757c0f8.zip
gcc-ab988c156f9a1a7eed1684b8bb40d05aa757c0f8.tar.gz
gcc-ab988c156f9a1a7eed1684b8bb40d05aa757c0f8.tar.bz2
gccrs: Almost done with top level parsing
gcc/rust/ChangeLog: * expand/rust-macro-builtins-asm.cc (struct AsmParseError): title. (enum InlineAsmDirSpec): title. (enum InlineAsmOptions): title. (struct AsmArg): title. (parseAsmArg): title. (parse_global_asm): title. (parse_nonglobal_asm): title. (parse_asm): title. (parseDirSpec): title. (parse_format_string): title. (MacroBuiltin::global_asm_handler): title. (MacroBuiltin::nonglobal_asm_handler): title. * expand/rust-macro-builtins.cc: title. * expand/rust-macro-builtins.h: title.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/expand/rust-macro-builtins-asm.cc178
-rw-r--r--gcc/rust/expand/rust-macro-builtins.cc6
-rw-r--r--gcc/rust/expand/rust-macro-builtins.h6
3 files changed, 186 insertions, 4 deletions
diff --git a/gcc/rust/expand/rust-macro-builtins-asm.cc b/gcc/rust/expand/rust-macro-builtins-asm.cc
index e50694d..7958d91 100644
--- a/gcc/rust/expand/rust-macro-builtins-asm.cc
+++ b/gcc/rust/expand/rust-macro-builtins-asm.cc
@@ -18,3 +18,181 @@
#include "rust-macro-builtins.h"
#include "rust-macro-builtins-helpers.h"
+#include "rust-macro-invoc-lexer.h"
+
+namespace Rust {
+
+struct AsmParseError
+{
+};
+
+// This is just an enum to hold some operands right now.
+enum InlineAsmDirSpec
+{
+ In,
+ Out,
+ InOut,
+ SplitInOut,
+ Const,
+ Sym,
+ Label,
+};
+
+enum InlineAsmOptions
+{
+
+};
+
+typedef std::string symbol_name;
+typedef std::vector<AST::Expr> Templates;
+typedef std::vector<InlineAsmDirSpec> Operands;
+typedef std::map<std::string, int> RegisterArgs;
+typedef std::map<symbol_name, int> ClobberAbis;
+typedef std::map<symbol_name, int> NamedValues;
+
+struct AsmArg
+{
+ Templates templates;
+ Operands operands;
+ std::map<symbol_name, int> named_values;
+ RegisterArgs register_arguments;
+ ClobberAbis clobber_abis;
+ InlineAsmOptions options;
+ std::vector<InlineAsmOptions>
+ options_span; // TODO: @badumbatish @jjasmine I have no idea what span do, i
+ // copied it out of rustc_builtin_macros/src/asm.rs
+};
+
+tl::optional<AsmArg>
+parseAsmArg (Parser<MacroInvocLexer> &p, bool is_global_asm);
+static tl::optional<AST::Fragment>
+parse_global_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
+static tl::optional<AST::Fragment>
+parse_nonglobal_asm (location_t invoc_locus, AST::MacroInvocData &invoc);
+static tl::optional<AST::Fragment>
+parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
+ bool is_global_asm);
+
+tl::optional<InlineAsmDirSpec>
+parseDirSpec (Parser<MacroInvocLexer> &p, TokenId last_token_id)
+{
+ return tl::nullopt;
+}
+tl::optional<AsmArg>
+parseAsmArg (Parser<MacroInvocLexer> &p, bool is_global_asm)
+{
+ return tl::nullopt;
+}
+
+tl::optional<std::string>
+parse_format_string (Parser<MacroInvocLexer> &parser, TokenId last_token_id)
+{
+ auto token = parser.peek_current_token ();
+
+ if (token->get_id () != last_token_id && token->get_id () == STRING_LITERAL)
+ {
+ // very nice, we got a supposedly formatted string.
+ std::cout << token->get_token_description () << std::endl;
+ parser.skip_token ();
+ return "formatted string";
+ }
+ else
+ {
+ parser.skip_token ();
+ std::cout << token->get_token_description () << std::endl;
+
+ rust_error_at (token->get_locus (),
+ "asm template must be a string literal");
+ return tl::nullopt;
+ }
+}
+
+tl::optional<AST::Fragment>
+MacroBuiltin::global_asm_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc)
+{
+ // Just to clarify the code
+ bool is_global_asm = true;
+ return parse_asm (invoc_locus, invoc, is_global_asm);
+}
+
+tl::optional<AST::Fragment>
+MacroBuiltin::nonglobal_asm_handler (location_t invoc_locus,
+ AST::MacroInvocData &invoc)
+{
+ // Just to clarify the code
+ bool is_global_asm = false;
+ return parse_asm (invoc_locus, invoc, is_global_asm);
+}
+
+static tl::optional<AST::Fragment>
+parse_asm (location_t invoc_locus, AST::MacroInvocData &invoc,
+ bool is_global_asm)
+{
+ // From the rule of asm.
+ // We first peek and see if it is a format string or not.
+ // If yes, we process the first ever format string, and move on to the
+ // recurrent of format string Else we exit out
+
+ // After that, we peek and see if it is a reoccuring stream of format string
+ // or not. If it is, keep on going to do this format string. Else, move on
+
+ // After that, we peek and see if it is a reoccuring stream of operands or not
+ // If it is, keep on going to do this operand thingy.
+ // Else, move on
+
+ // We check if there is an optional "," at the end, per ABNF spec.
+ // If it is, consume it.
+
+ // Done
+ MacroInvocLexer lex (invoc.get_delim_tok_tree ().to_token_stream ());
+ Parser<MacroInvocLexer> parser (lex);
+ auto last_token_id = macro_end_token (invoc.get_delim_tok_tree (), parser);
+
+ // Parse the first ever formatted string, success or not, will skip 1 token
+ auto fm_string = parse_format_string (parser, last_token_id);
+ if (fm_string == tl::nullopt)
+ return tl::nullopt;
+
+ // formatted string stream
+ auto token = parser.peek_current_token ();
+ while (token->get_id () != last_token_id)
+ {
+ std::cout << token->get_token_description () << std::endl;
+ token = parser.peek_current_token ();
+ if (token->get_id () != COMMA)
+ {
+ break;
+ }
+ parser.skip_token ();
+ // Ok after the comma is good, we better be parsing correctly everything
+ // in here, which is formatted string in ABNF
+
+ fm_string = parse_format_string (parser, last_token_id);
+ }
+
+ // operands stream
+ token = parser.peek_current_token ();
+ while (token->get_id () != last_token_id)
+ {
+ std::cout << token->get_token_description () << std::endl;
+
+ token = parser.peek_current_token ();
+ if (token->get_id () != COMMA)
+ {
+ break;
+ }
+ parser.skip_token ();
+ // Ok after the left paren is good, we better be parsing correctly
+ // everything in here, which is operand in ABNF
+
+ // TODO: Work on parsing operands
+ fm_string = parse_format_string (parser, last_token_id);
+ }
+
+ // TODO: Handle the optional ","
+
+ return tl::nullopt;
+}
+
+} // namespace Rust
diff --git a/gcc/rust/expand/rust-macro-builtins.cc b/gcc/rust/expand/rust-macro-builtins.cc
index 61b677a..e4144d1 100644
--- a/gcc/rust/expand/rust-macro-builtins.cc
+++ b/gcc/rust/expand/rust-macro-builtins.cc
@@ -62,7 +62,6 @@ const BiMap<std::string, BuiltinMacro> MacroBuiltin::builtins = {{
{"concat_idents", BuiltinMacro::ConcatIdents},
{"module_path", BuiltinMacro::ModulePath},
{"asm", BuiltinMacro::Asm},
- {"llvm_asm", BuiltinMacro::LlvmAsm},
{"global_asm", BuiltinMacro::GlobalAsm},
{"log_syntax", BuiltinMacro::LogSyntax},
{"trace_macros", BuiltinMacro::TraceMacros},
@@ -109,13 +108,12 @@ std::unordered_map<std::string, AST::MacroTranscriberFunc>
{"include", MacroBuiltin::include_handler},
{"format_args", format_args_maker (AST::FormatArgs::Newline::No)},
{"format_args_nl", format_args_maker (AST::FormatArgs::Newline::Yes)},
+ {"asm", MacroBuiltin::nonglobal_asm_handler},
+ {"global_asm", MacroBuiltin::global_asm_handler},
/* Unimplemented macro builtins */
{"option_env", MacroBuiltin::sorry},
{"concat_idents", MacroBuiltin::sorry},
{"module_path", MacroBuiltin::sorry},
- {"asm", MacroBuiltin::sorry},
- {"llvm_asm", MacroBuiltin::sorry},
- {"global_asm", MacroBuiltin::sorry},
{"log_syntax", MacroBuiltin::sorry},
{"trace_macros", MacroBuiltin::sorry},
{"test", MacroBuiltin::sorry},
diff --git a/gcc/rust/expand/rust-macro-builtins.h b/gcc/rust/expand/rust-macro-builtins.h
index 6ba43ff..10377e9 100644
--- a/gcc/rust/expand/rust-macro-builtins.h
+++ b/gcc/rust/expand/rust-macro-builtins.h
@@ -160,6 +160,12 @@ public:
AST::MacroInvocData &invoc);
static tl::optional<AST::Fragment>
+ nonglobal_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
+
+ static tl::optional<AST::Fragment>
+ global_asm_handler (location_t invoc_locus, AST::MacroInvocData &invoc);
+
+ static tl::optional<AST::Fragment>
format_args_handler (location_t invoc_locus, AST::MacroInvocData &invoc,
AST::FormatArgs::Newline nl);