@@ -2063,6 +2063,7 @@ class Type : public ExtQualsTypeCommonBase {
20632063 bool isNtCheckedArrayType () const ;
20642064 bool isUncheckedArrayType () const ;
20652065 bool isRecordType () const ;
2066+ bool isExistentialType () const ; // Checked C existential type
20662067 bool isClassType () const ;
20672068 bool isStructureType () const ;
20682069 bool isObjCBoxableRecordType () const ;
@@ -4403,7 +4404,7 @@ class TypeVariableType : public Type, public llvm::FoldingSetNode {
44034404 return isBoundsInterfaceType;
44044405 }
44054406
4406- void Profile (llvm::FoldingSetNodeID &ID) {
4407+ void Profile (llvm::FoldingSetNodeID &ID) const {
44074408 Profile (ID, depth, index, isBoundsInterfaceType);
44084409 }
44094410 static void Profile (llvm::FoldingSetNodeID &ID, unsigned int inDepth, unsigned int inIndex,
@@ -4416,7 +4417,6 @@ class TypeVariableType : public Type, public llvm::FoldingSetNode {
44164417 static bool classof (const Type *T) { return T->getTypeClass () == TypeVariable; }
44174418};
44184419
4419-
44204420class TypedefType : public Type {
44214421 TypedefNameDecl *Decl;
44224422
@@ -4441,6 +4441,57 @@ class TypedefType : public Type {
44414441 static bool classof (const Type *T) { return T->getTypeClass () == Typedef; }
44424442};
44434443
4444+ // / (Checked C extension)
4445+ // / Represents the type '_Exists(T, InnerType)', where 'T' is a type variable and
4446+ // / 'InnerType' is some type that potentially uses 'T'.
4447+ // / There are some restrictions on what 'InnerType' can be. These restrictions are enforced
4448+ // / via checks in the 'pack' and 'unpack' operations, but they amount to requiring that
4449+ // / 'InnerType' is one of:
4450+ // / 1) another existential type: e.g. '_Exists(T, _Exists(U, struct Foo<T, U>))'
4451+ // / 2) a type application 'C<T>', where 'C' is a generic struct: e.g. '_Exists(T, struct List<T>)'
4452+ // / 3) a pointer that satisfies one of 1) - 3)
4453+ class ExistentialType : public Type , public llvm ::FoldingSetNode {
4454+ // / The type variable that is bound by the existential.
4455+ // / This is of type 'Type' to allow for some polymorphism:
4456+ // / non-canonical existential types will contain a 'TypedefType' here,
4457+ // / while canonical ones will contain the underlying 'TypeVariableType'.
4458+ // / This isn't a 'QualType' because the variable bound by an existential cannot be
4459+ // / qualified.
4460+ const Type *TypeVar = nullptr ;
4461+ // / The type wrapped by the existential that potentially uses the bound type variable.
4462+ QualType InnerType;
4463+
4464+ public:
4465+ ExistentialType (const Type *TypeVar, QualType InnerType, QualType Canon) :
4466+ Type (Existential, Canon, false /* Dependent */ , false /* InstantiationDependent */ ,
4467+ false /* VariablyModified */ , false /* ContainsUnexpandedParameterPack */ ),
4468+ TypeVar (TypeVar), InnerType(InnerType) {
4469+ if (!TypedefType::classof (TypeVar) && !TypeVariableType::classof (TypeVar)) {
4470+ llvm_unreachable (" Type variable should be a 'TypedefType' or 'TypeVariableType'" );
4471+ }
4472+ }
4473+
4474+ const Type *typeVar () const { return TypeVar; }
4475+ QualType innerType () const { return InnerType; }
4476+
4477+ bool isSugared (void ) const { return false ; }
4478+ QualType desugar (void ) const { return QualType (this , 0 ); }
4479+
4480+ // TODO: can't implement 'Profile' because TypedefType doesn't have a 'Profile' method (checkedc issue #661).
4481+ /*
4482+ void Profile(llvm::FoldingSetNodeID &ID) {
4483+ Profile(ID, TypeVar, InnerType);
4484+ }
4485+ static void Profile(llvm::FoldingSetNodeID &ID, const Type *TypeVar, QualType InnerType) {
4486+ if (const auto *TV = TypeVar->getAs<TypedefType>()) TV->Profile(ID);
4487+ else if (const auto *TV = TypeVar->getAs<TypeVariableType>()) TV->Profile(ID);
4488+ InnerType.Profile(ID);
4489+ }
4490+ */
4491+
4492+ static bool classof (const Type *T) { return T->getTypeClass () == Existential; }
4493+ };
4494+
44444495// / Represents a `typeof` (or __typeof__) expression (a GCC extension).
44454496class TypeOfExprType : public Type {
44464497 Expr *TOExpr;
@@ -6713,6 +6764,10 @@ inline bool Type::isRecordType() const {
67136764 return isa<RecordType>(CanonicalType);
67146765}
67156766
6767+ inline bool Type::isExistentialType () const {
6768+ return isa<ExistentialType>(CanonicalType);
6769+ }
6770+
67166771inline bool Type::isEnumeralType () const {
67176772 return isa<EnumType>(CanonicalType);
67186773}
0 commit comments