@@ -6999,13 +6999,71 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type)
69996999 }
70007000END_CAN_TYPE_WRAPPER (PackExpansionType, Type)
70017001
7002-
70037002inline CanTypeWrapper<PackExpansionType>
70047003CanPackType::unwrapSingletonPackExpansion () const {
70057004 return CanPackExpansionType (
70067005 getPointer ()->unwrapSingletonPackExpansion ());
70077006}
70087007
7008+ // / Represents a reference to a pack from an outer expansion. This comes up
7009+ // / after substitution. For example, given these declarations:
7010+ // /
7011+ // / typealias A<each T, U> = (repeat (each T, U))
7012+ // / typealias B<each X, repeat each Y> = (repeat A<repeat each X, each Y>)
7013+ // /
7014+ // / Naively substituting replacing {T := repeat each X, U := each Y} in the
7015+ // / underlying type of A would give us:
7016+ // /
7017+ // / '(repeat (repeat (each X, each Y)))'
7018+ // /
7019+ // / However, this is wrong; we're not expanding X and Y in parallel (they
7020+ // / might not even have the same shape). Instead, we're expanding X, and
7021+ // / then on each iteration, expanding Y.
7022+ // /
7023+ // / If we annotate each 'repeat' and its corresponding 'each', we instead see
7024+ // / that the above should give us:
7025+ // /
7026+ // / '(repeat[1] (repeat[0] (each[0], each[1] U)))'
7027+ // /
7028+ // / We number PackExpansionTypes from the innermost one outwards, assigning
7029+ // / a level of 0 to the innermost one. Then, a PackElementType represents a
7030+ // / reference to a parameter pack from an expansion with level > 0.
7031+ class PackElementType : public TypeBase , public llvm ::FoldingSetNode {
7032+ friend class ASTContext ;
7033+
7034+ Type packType;
7035+ unsigned level;
7036+
7037+ PackElementType (Type packType, unsigned level,
7038+ RecursiveTypeProperties properties,
7039+ const ASTContext *ctx);
7040+
7041+ public:
7042+ static PackElementType *get (Type packType, unsigned level);
7043+
7044+ Type getPackType () const { return packType; }
7045+
7046+ unsigned getLevel () const { return level; }
7047+
7048+ void Profile (llvm::FoldingSetNodeID &ID) {
7049+ Profile (ID, getPackType (), getLevel ());
7050+ }
7051+
7052+ static void Profile (llvm::FoldingSetNodeID &ID, Type packType, unsigned level);
7053+
7054+ // Implement isa/cast/dyncast/etc.
7055+ static bool classof (const TypeBase *T) {
7056+ return T->getKind () == TypeKind::PackElement;
7057+ }
7058+ };
7059+ BEGIN_CAN_TYPE_WRAPPER (PackElementType, Type)
7060+ static CanPackElementType get (CanType pack);
7061+
7062+ CanType getPackType () const {
7063+ return CanType (getPointer ()->getPackType ());
7064+ }
7065+ END_CAN_TYPE_WRAPPER (PackElementType, Type)
7066+
70097067// / getASTContext - Return the ASTContext that this type belongs to.
70107068inline ASTContext &TypeBase::getASTContext () const {
70117069 // If this type is canonical, it has the ASTContext in it.
0 commit comments