@@ -6999,13 +6999,71 @@ BEGIN_CAN_TYPE_WRAPPER(PackExpansionType, Type)
6999
6999
}
7000
7000
END_CAN_TYPE_WRAPPER (PackExpansionType, Type)
7001
7001
7002
-
7003
7002
inline CanTypeWrapper<PackExpansionType>
7004
7003
CanPackType::unwrapSingletonPackExpansion () const {
7005
7004
return CanPackExpansionType (
7006
7005
getPointer ()->unwrapSingletonPackExpansion ());
7007
7006
}
7008
7007
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
+
7009
7067
// / getASTContext - Return the ASTContext that this type belongs to.
7010
7068
inline ASTContext &TypeBase::getASTContext () const {
7011
7069
// If this type is canonical, it has the ASTContext in it.
0 commit comments