@@ -526,6 +526,17 @@ class CoreturnStmt : public Stmt {
526526};
527527
528528// / CXXExpansionStmt - Base class for an unexpanded C++ expansion statement.
529+ // /
530+ // / The main purpose for this class is to store the AST nodes common to all
531+ // / variants of expansion statements; it also provides storage for additional
532+ // / subexpressions required by its derived classes. This is to simplify the
533+ // / implementation of 'children()' and friends.
534+ // /
535+ // / \see ExpansionStmtDecl
536+ // / \see CXXEnumeratingExpansionStmt
537+ // / \see CXXIteratingExpansionStmt
538+ // / \see CXXDestructuringExpansionStmt
539+ // / \see CXXDependentExpansionStmt
529540class CXXExpansionStmt : public Stmt {
530541 friend class ASTStmtReader ;
531542
@@ -622,7 +633,35 @@ class CXXExpansionStmt : public Stmt {
622633
623634// / Represents an unexpanded enumerating expansion statement.
624635// /
625- // / The expansion initializer of this is always a CXXExpansionInitListExpr.
636+ // / An 'enumerating' expansion statement is one whose expansion-initializer
637+ // / is a brace-enclosed expression-list; this list is syntactically similar to
638+ // / an initializer list, but it isn't actually an expression in and of itself
639+ // / (in that it is never evaluated or emitted) and instead is just treated as
640+ // / a group of expressions. The expansion initializer of this is always a
641+ // / 'CXXExpansionInitListExpr'.
642+ // /
643+ // / Example:
644+ // / \verbatim
645+ // / template for (auto x : { 1, 2, 3 }) {
646+ // / // ...
647+ // / }
648+ // / \endverbatim
649+ // /
650+ // / Note that the expression-list may also contain pack expansions, e.g.
651+ // / '{ 1, xs... }', in which case the expansion size is dependent.
652+ // /
653+ // / Here, the '{ 1, 2, 3 }' is parsed as a 'CXXExpansionInitListExpr'. This node
654+ // / handles storing (and pack-expanding) the individual expressions.
655+ // /
656+ // / Sema then wraps this with a 'CXXExpansionInitListSelectExpr', which also
657+ // / contains a reference to an integral NTTP that is used as the expansion
658+ // / index; this index is either dependent (if the expansion-size is dependent),
659+ // / or set to a value of I in the I-th expansion during the expansion process.
660+ // /
661+ // / The actual expansion is done by 'BuildCXXExpansionInitListSelectExpr()': for
662+ // / example, during the 2nd expansion of '{ a, b, c }', I is equal to 1, and
663+ // / BuildCXXExpansionInitListSelectExpr(), when called via TreeTransform,
664+ // / 'instantiates' the expression '{ a, b, c }' to just 'b'.
626665class CXXEnumeratingExpansionStmt : public CXXExpansionStmt {
627666 friend class ASTStmtReader ;
628667
@@ -638,7 +677,24 @@ class CXXEnumeratingExpansionStmt : public CXXExpansionStmt {
638677 }
639678};
640679
641- // / Represents an expansion statement whose expansion-initializer is dependent.
680+ // / Represents an expansion statement whose expansion-initializer is
681+ // / type-dependent.
682+ // /
683+ // / This will be instantiated as either a 'CXXIteratingExpansionStmt' or a
684+ // / 'CXXDestructuringExpansionStmt'. Dependent expansion statements can never
685+ // / be enumerating; those are always stored as a 'CXXEnumeratingExpansionStmt',
686+ // / even if the expansion size is dependent because the expression-list contains
687+ // / a pack.
688+ // /
689+ // / Example:
690+ // / \verbatim
691+ // / template <typename T>
692+ // / void f() {
693+ // / template for (auto x : T()) {
694+ // / // ...
695+ // / }
696+ // / }
697+ // / \endverbatim
642698class CXXDependentExpansionStmt : public CXXExpansionStmt {
643699 friend class ASTStmtReader ;
644700
@@ -673,8 +729,20 @@ class CXXDependentExpansionStmt : public CXXExpansionStmt {
673729
674730// / Represents an unexpanded iterating expansion statement.
675731// /
676- // / The expression used to compute the size of the expansion is not stored in
677- // / this as it is only created at the moment of expansion.
732+ // / An 'iterating' expansion statement is one whose expansion-initializer is a
733+ // / a range (i.e. it has a corresponding 'begin()'/'end()' pair that is
734+ // / determined based on a number of conditions as stated in [stmt.expand] and
735+ // / [stmt.ranged]).
736+ // /
737+ // / The expression used to compute the size of the expansion is not stored and
738+ // / is only created at the moment of expansion.
739+ // /
740+ // / \verbatim
741+ // / static constexpr std::string_view foo = "1234";
742+ // / template for (auto x : foo) {
743+ // / // ...
744+ // / }
745+ // / \endverbatim
678746class CXXIteratingExpansionStmt : public CXXExpansionStmt {
679747 friend class ASTStmtReader ;
680748
@@ -742,7 +810,29 @@ class CXXIteratingExpansionStmt : public CXXExpansionStmt {
742810 }
743811};
744812
745- // / Represents an expansion statement whose expansion-initializer is dependent.
813+ // / Represents an unexpanded destructuring expansion statement.
814+ // /
815+ // / A 'destructuring' expansion statement is any expansion statement that is
816+ // / not enumerating or iterating (i.e. destructuring is the last thing we try,
817+ // / and if it doesn't work, the program is ill-formed).
818+ // /
819+ // / This essentially involves treating the expansion-initializer as the
820+ // / initializer of a structured-binding declarations, with the number of
821+ // / bindings and expansion size determined by the usual means (array size,
822+ // / std::tuple_size, etc.).
823+ // /
824+ // / Example:
825+ // / \verbatim
826+ // / std::array<int, 3> a {1, 2, 3};
827+ // / template for (auto x : a) {
828+ // / // ...
829+ // / }
830+ // / \endverbatim
831+ // /
832+ // / Sema wraps the initializer with a CXXDestructuringExpansionSelectExpr, which
833+ // / selects a binding based on the current expansion index; this is analogous to
834+ // / how 'CXXExpansionInitListSelectExpr' is used; see the documentation of
835+ // / 'CXXEnumeratingExpansionStmt' for more details on this.
746836class CXXDestructuringExpansionStmt : public CXXExpansionStmt {
747837 friend class ASTStmtReader ;
748838
@@ -780,7 +870,7 @@ class CXXDestructuringExpansionStmt : public CXXExpansionStmt {
780870 }
781871};
782872
783- // / Represents the code generated for an instantiated expansion statement.
873+ // / Represents the code generated for an expanded expansion statement.
784874// /
785875// / This holds 'shared statements' and 'instantiations'; these encode the
786876// / general underlying pattern that all expansion statements desugar to:
@@ -797,6 +887,40 @@ class CXXDestructuringExpansionStmt : public CXXExpansionStmt {
797887// / }
798888// / }
799889// / \endverbatim
890+ // /
891+ // / Here, the only thing that is stored in the AST are the 'shared statements'
892+ // / and the 'CompoundStmt's that wrap the 'instantiations'. The outer braces
893+ // / shown above are implicit.
894+ // /
895+ // / For example, the CXXExpansionInstantiationStmt that corresponds to the
896+ // / following expansion statement
897+ // /
898+ // / \verbatim
899+ // / std::array<int, 3> a {1, 2, 3};
900+ // / template for (auto x : a) {
901+ // / // ...
902+ // / }
903+ // / \endverbatim
904+ // /
905+ // / would be
906+ // /
907+ // / \verbatim
908+ // / {
909+ // / auto [__u0, __u1, __u2] = a;
910+ // / {
911+ // / auto x = __u0;
912+ // / // ...
913+ // / }
914+ // / {
915+ // / auto x = __u1;
916+ // / // ...
917+ // / }
918+ // / {
919+ // / auto x = __u2;
920+ // / // ...
921+ // / }
922+ // / }
923+ // / \endverbatim
800924class CXXExpansionInstantiationStmt final
801925 : public Stmt,
802926 llvm::TrailingObjects<CXXExpansionInstantiationStmt, Stmt *> {
0 commit comments