]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
macro: Allow builtin `MacroInvocation`s within the AST
authorArthur Cohen <arthur.cohen@embecosm.com>
Wed, 18 Jan 2023 11:23:03 +0000 (12:23 +0100)
committerArthur Cohen <arthur.cohen@embecosm.com>
Wed, 8 Feb 2023 11:02:41 +0000 (12:02 +0100)
This commit turns AST::MacroInvocation into a sum type.
The class can now represent a regular macro invocation (lazily expanded)
or a builtin one (eagerly expanded)

gcc/rust/ChangeLog:

* expand/rust-macro-builtins.cc (make_macro_invocation): Add short hand
function for returning fragments containing macro invocations.
(MacroBuiltin::compile_error_handler): Add explanation for eager
invocation

gcc/rust/expand/rust-macro-builtins.cc

index f6ddb1a803ef2f0833e7a96ea5a39d17cfdc5f5f..11b5d5fbc9dd06a128bb82aa6778cdf6438e714b 100644 (file)
@@ -37,8 +37,39 @@ make_string (Location locus, std::string value)
                          PrimitiveCoreType::CORETYPE_STR, {}, locus));
 }
 
-/* Match the end token of a macro given the start delimiter of the macro */
+// TODO: Is this correct?
+static std::unique_ptr<AST::Expr>
+make_macro_invocation (AST::BuiltinMacro kind, AST::DelimTokenTree arguments)
+{
+  std::string path_str;
+
+  switch (kind)
+    {
+    case AST::BuiltinMacro::Assert:
+    case AST::BuiltinMacro::File:
+    case AST::BuiltinMacro::Line:
+    case AST::BuiltinMacro::Column:
+    case AST::BuiltinMacro::IncludeBytes:
+    case AST::BuiltinMacro::IncludeStr:
+    case AST::BuiltinMacro::CompileError:
+    case AST::BuiltinMacro::Concat:
+      path_str = "concat";
+      break;
+    case AST::BuiltinMacro::Env:
+    case AST::BuiltinMacro::Cfg:
+    case AST::BuiltinMacro::Include:
+      break;
+    }
 
+  return AST::MacroInvocation::builtin (
+    kind,
+    AST::MacroInvocData (AST::SimplePath (
+                          {AST::SimplePathSegment (path_str, Location ())}),
+                        std::move (arguments)),
+    {}, Location ());
+}
+
+/* Match the end token of a macro given the start delimiter of the macro */
 static inline TokenId
 macro_end_token (AST::DelimTokenTree &invoc_token_tree,
                 Parser<MacroInvocLexer> &parser)
@@ -386,6 +417,45 @@ MacroBuiltin::compile_error_handler (Location invoc_locus,
 /* Expand builtin macro concat!(), which joins all the literal parameters
    into a string with no delimiter. */
 
+// This is a weird one. We want to do something where, if something cannot be
+// expanded yet (i.e. macro invocation?) we return the whole MacroInvocation
+// node again but expanded as much as possible.
+// Is that possible? How do we do that?
+//
+// Let's take a few examples:
+//
+// 1. concat!(1, 2, true);
+// 2. concat!(a!(), 2, true);
+// 3. concat!(concat!(1, false), 2, true);
+// 4. concat!(concat!(1, a!()), 2, true);
+//
+// 1. We simply want to return the new fragment: "12true"
+// 2. We want to return `concat!(a_expanded, 2, true)` as a fragment
+// 3. We want to return `concat!(1, false, 2, true)`
+// 4. We want to return `concat!(concat!(1, a_expanded), 2, true);
+//
+// How do we do that?
+//
+// For each (un)expanded fragment: we check if it is expanded fully
+//
+// 1. What is expanded fully?
+// 2. How to check?
+//
+// If it is expanded fully and not a literal, then we error out.
+// Otherwise we simply emplace it back and keep going.
+//
+// In the second case, we must mark that this concat invocation still has some
+// expansion to do: This allows us to return a `MacroInvocation { ... }` as an
+// AST fragment, instead of a completed string.
+//
+// This means that we must change all the `try_expand_many_*` APIs and so on to
+// return some sort of index or way to signify that we might want to reuse some
+// bits and pieces of the original token tree.
+//
+// Now, before that: How do we resolve the names used in a builtin macro
+// invocation?
+// Do we split the two passes of parsing the token tree and then expanding it?
+// Can we do that easily?
 AST::Fragment
 MacroBuiltin::concat_handler (Location invoc_locus, AST::MacroInvocData &invoc)
 {