================
@@ -3343,6 +3343,120 @@ class TemplateParamObjectDecl : public ValueDecl,
static bool classofKind(Kind K) { return K == TemplateParamObject; }
};
+/// Represents a C++26 expansion statement declaration.
+///
+/// This is a bit of a hack, since expansion statements shouldn't really be
+/// 'declarations' per se (they don't declare anything). Nevertheless, we *do*
+/// need them to be declaration *contexts*, because the DeclContext is used to
+/// compute the 'template depth' of entities enclosed therein. In particular,
+/// the 'template depth' is used to find instantiations of parameter variables,
+/// and a lambda enclosed within an expansion statement cannot compute its
+/// template depth without a pointer to the enclosing expansion statement.
+///
+/// For the remainder of this comment, let 'expanding' an expansion statement
+/// refer to the process of performing template substitution on its body N
+/// times, where N is the expansion size (how this size is determined depends
on
+/// the kind of expansion statement); by contrast we may sometimes
'instantiate'
+/// an expansion statement (because it happens to be in a template). This is
+/// just regular template instantiation.
+///
+/// Apart from a template parameter list that contains a template parameter
used
+/// as the expansion index, this node contains a 'CXXExpansionStmtPattern' as
+/// well as a 'CXXExpansionStmtInstantiation'. These two members correspond to
+/// distinct representations of the expansion statement: the former is used
+/// prior to expansion and contains all the parts needed to perform expansion;
+/// the latter holds the expanded/desugared AST nodes that result from the
+/// expansion.
+///
+/// After expansion, the 'CXXExpansionStmtPattern' is no longer updated and
left
+/// as-is; this also means that, if an already-expanded expansion statement is
+/// inside a template, and that template is then instantiated, the
+/// 'CXXExpansionStmtPattern' is *not* instantiated; only the
+/// 'CXXExpansionStmtInstantiation' is. The latter is also what's used for
+/// codegen and constant evaluation.
+///
+/// For example, if the user writes the following expansion statement:
+/// \verbatim
+/// std::tuple<int, int, int> a{1, 2, 3};
+/// template for (auto x : a) {
+/// // ...
+/// }
+/// \endverbatim
+///
+/// The 'CXXExpansionStmtPattern' of this particular 'CXXExpansionStmtDecl' is
a
+/// 'CXXDestructuringExpansionStmtPattern', which stores, amongst other things,
+/// the declaration of the variable 'x' as well as the expansion-initializer
+/// 'a'.
+///
+/// After expansion, we end up with a 'CXXExpansionStmtInstantiation' that
----------------
Sirraide wrote:
I should update this comment to indicate that the outer compound statement is
‘not actually there’; I don’t remember why I didn’t explain that here (and
perhaps some of the documentation needs to be deduplicated, and this section
here should just say ‘see the comment on `CXXExpansionStmtInstantiation` for
more information on the AST we produce for the expansions’).
Alternatively, as you (or Corentin, I don’t remember?) suggested, I can move
all of the expansion statement documentation into one big comment here, and
then all the other nodes just have a comment that says ‘see
`CXXExpansionStmtDecl` for documentation on this’, which might be easier to
work w/ than having it all fragmented across 6-odd AST nodes...
https://github.com/llvm/llvm-project/pull/169680
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits