diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h --- a/clang/include/clang/AST/DependenceFlags.h +++ b/clang/include/clang/AST/DependenceFlags.h @@ -106,6 +106,32 @@ // type dependency. return D & ~ExprDependence::Type; } +inline ExprDependence turnValueToTypeDependence(ExprDependence D) { + // Type-dependent expressions are always be value-dependent. + if (D & ExprDependence::Value) + D |= ExprDependence::Type; + return D; +} + +// Returned type-dependence will never have VariablyModified set. +inline TypeDependence toTypeDependence(ExprDependence D) { + // Supported bits all have the same representation. + return static_cast(D & (ExprDependence::UnexpandedPack | + ExprDependence::Instantiation | + ExprDependence::Type)); +} +inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) { + // Supported bits all have the same representation. + return static_cast(D); +} +inline TypeDependence toTypeDependence(TemplateNameDependence D) { + // Supported bits all have the same representation. + return static_cast(D); +} +inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { + // Supported bits all have the same representation. + return static_cast(D); +} inline NestedNameSpecifierDependence toNestedNameSpecifierDependendence(TypeDependence D) { diff --git a/clang/include/clang/AST/LocInfoType.h b/clang/include/clang/AST/LocInfoType.h --- a/clang/include/clang/AST/LocInfoType.h +++ b/clang/include/clang/AST/LocInfoType.h @@ -35,10 +35,7 @@ TypeSourceInfo *DeclInfo; LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isInstantiationDependentType(), ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { + : Type((TypeClass)LocInfo, ty, ty->getDependence()), DeclInfo(TInfo) { assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); } friend class Sema; diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1818,23 +1818,11 @@ protected: friend class ASTContext; - Type(TypeClass tc, QualType canon, bool Dependent, - bool InstantiationDependent, bool VariablyModified, - bool ContainsUnexpandedParameterPack) + Type(TypeClass tc, QualType canon, TypeDependence Dependence) : ExtQualsTypeCommonBase(this, canon.isNull() ? QualType(this_(), 0) : canon) { - auto Deps = TypeDependence::None; - if (Dependent) - Deps |= TypeDependence::Dependent | TypeDependence::Instantiation; - if (InstantiationDependent) - Deps |= TypeDependence::Instantiation; - if (ContainsUnexpandedParameterPack) - Deps |= TypeDependence::UnexpandedPack; - if (VariablyModified) - Deps |= TypeDependence::VariablyModified; - TypeBits.TC = tc; - TypeBits.Dependence = static_cast(Deps); + TypeBits.Dependence = static_cast(Dependence); TypeBits.CacheValid = false; TypeBits.CachedLocalOrUnnamed = false; TypeBits.CachedLinkage = NoLinkage; @@ -1844,41 +1832,11 @@ // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } - void setDependent(bool D = true) { - if (!D) { - TypeBits.Dependence &= ~static_cast(TypeDependence::Dependent); - return; - } - TypeBits.Dependence |= static_cast(TypeDependence::Dependent | - TypeDependence::Instantiation); - } - - void setInstantiationDependent(bool D = true) { - if (D) - TypeBits.Dependence |= - static_cast(TypeDependence::Instantiation); - else - TypeBits.Dependence &= - ~static_cast(TypeDependence::Instantiation); - } - - void setVariablyModified(bool VM = true) { - if (VM) - TypeBits.Dependence |= - static_cast(TypeDependence::VariablyModified); - else - TypeBits.Dependence &= - ~static_cast(TypeDependence::VariablyModified); + void setDependence(TypeDependence D) { + TypeBits.Dependence = static_cast(D); } - void setContainsUnexpandedParameterPack(bool PP = true) { - if (PP) - TypeBits.Dependence |= - static_cast(TypeDependence::UnexpandedPack); - else - TypeBits.Dependence &= - ~static_cast(TypeDependence::UnexpandedPack); - } + void addDependence(TypeDependence D) { setDependence(getDependence() | D); } public: friend class ASTReader; @@ -2519,10 +2477,9 @@ friend class ASTContext; // ASTContext creates these. BuiltinType(Kind K) - : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), - /*InstantiationDependent=*/(K == Dependent), - /*VariablyModified=*/false, - /*Unexpanded parameter pack=*/false) { + : Type(Builtin, QualType(), + K == Dependent ? TypeDependence::DependentInstantiation + : TypeDependence::None) { BuiltinTypeBits.Kind = K; } @@ -2592,10 +2549,7 @@ QualType ElementType; ComplexType(QualType Element, QualType CanonicalPtr) - : Type(Complex, CanonicalPtr, Element->isDependentType(), - Element->isInstantiationDependentType(), - Element->isVariablyModifiedType(), - Element->containsUnexpandedParameterPack()), + : Type(Complex, CanonicalPtr, Element->getDependence()), ElementType(Element) {} public: @@ -2622,11 +2576,7 @@ QualType Inner; ParenType(QualType InnerType, QualType CanonType) - : Type(Paren, CanonType, InnerType->isDependentType(), - InnerType->isInstantiationDependentType(), - InnerType->isVariablyModifiedType(), - InnerType->containsUnexpandedParameterPack()), - Inner(InnerType) {} + : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} public: QualType getInnerType() const { return Inner; } @@ -2652,10 +2602,7 @@ QualType PointeeType; PointerType(QualType Pointee, QualType CanonicalPtr) - : Type(Pointer, CanonicalPtr, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(Pointer, CanonicalPtr, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -2703,10 +2650,7 @@ AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, QualType CanonicalPtr) - : Type(TC, CanonicalPtr, OriginalTy->isDependentType(), - OriginalTy->isInstantiationDependentType(), - OriginalTy->isVariablyModifiedType(), - OriginalTy->containsUnexpandedParameterPack()), + : Type(TC, CanonicalPtr, OriginalTy->getDependence()), OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} public: @@ -2755,10 +2699,7 @@ QualType PointeeType; BlockPointerType(QualType Pointee, QualType CanonicalCls) - : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -2788,10 +2729,7 @@ protected: ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, bool SpelledAsLValue) - : Type(tc, CanonicalRef, Referencee->isDependentType(), - Referencee->isInstantiationDependentType(), - Referencee->isVariablyModifiedType(), - Referencee->containsUnexpandedParameterPack()), + : Type(tc, CanonicalRef, Referencee->getDependence()), PointeeType(Referencee) { ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); @@ -2876,13 +2814,9 @@ MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : Type(MemberPointer, CanonicalPtr, - Cls->isDependentType() || Pointee->isDependentType(), - (Cls->isInstantiationDependentType() || - Pointee->isInstantiationDependentType()), - Pointee->isVariablyModifiedType(), - (Cls->containsUnexpandedParameterPack() || - Pointee->containsUnexpandedParameterPack())), - PointeeType(Pointee), Class(Cls) {} + (Cls->getDependence() & ~TypeDependence::VariablyModified) | + Pointee->getDependence()), + PointeeType(Pointee), Class(Cls) {} public: QualType getPointeeType() const { return PointeeType; } @@ -3696,14 +3630,9 @@ }; protected: - FunctionType(TypeClass tc, QualType res, - QualType Canonical, bool Dependent, - bool InstantiationDependent, - bool VariablyModified, bool ContainsUnexpandedParameterPack, - ExtInfo Info) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack), - ResultType(res) { + FunctionType(TypeClass tc, QualType res, QualType Canonical, + TypeDependence Dependence, ExtInfo Info) + : Type(tc, Canonical, Dependence), ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; } @@ -3754,9 +3683,10 @@ FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) : FunctionType(FunctionNoProto, Result, Canonical, - /*Dependent=*/false, /*InstantiationDependent=*/false, - Result->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false, Info) {} + Result->getDependence() & + ~(TypeDependence::DependentInstantiation | + TypeDependence::UnexpandedPack), + Info) {} public: // No additional state past what FunctionType provides. @@ -4248,9 +4178,9 @@ UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) - : Type(UnresolvedUsing, QualType(), true, true, false, - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast(D)) {} + : Type(UnresolvedUsing, QualType(), + TypeDependence::DependentInstantiation), + Decl(const_cast(D)) {} public: UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } @@ -4279,11 +4209,8 @@ friend class ASTContext; // ASTContext creates these. TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) - : Type(tc, can, can->isDependentType(), - can->isInstantiationDependentType(), - can->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast(D)) { + : Type(tc, can, can->getDependence() & ~TypeDependence::UnexpandedPack), + Decl(const_cast(D)) { assert(!isa(can) && "Invalid canonical type"); } @@ -4306,10 +4233,7 @@ MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, const IdentifierInfo *MacroII) - : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(), - UnderlyingTy->isInstantiationDependentType(), - UnderlyingTy->isVariablyModifiedType(), - UnderlyingTy->containsUnexpandedParameterPack()), + : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), UnderlyingTy(UnderlyingTy), MacroII(MacroII) { assert(isa(UnderlyingTy) && "Expected a macro qualified type to only wrap attributed types."); @@ -4381,11 +4305,7 @@ QualType TOType; TypeOfType(QualType T, QualType can) - : Type(TypeOf, can, T->isDependentType(), - T->isInstantiationDependentType(), - T->isVariablyModifiedType(), - T->containsUnexpandedParameterPack()), - TOType(T) { + : Type(TypeOf, can, T->getDependence()), TOType(T) { assert(!isa(can) && "Invalid canonical type"); } @@ -4594,10 +4514,7 @@ AttributedType(QualType canon, attr::Kind attrKind, QualType modified, QualType equivalent) - : Type(Attributed, canon, equivalent->isDependentType(), - equivalent->isInstantiationDependentType(), - equivalent->isVariablyModifiedType(), - equivalent->containsUnexpandedParameterPack()), + : Type(Attributed, canon, equivalent->getDependence()), ModifiedType(modified), EquivalentType(equivalent) { AttributedTypeBits.AttrKind = attrKind; } @@ -4699,18 +4616,16 @@ /// Build a non-canonical type. TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) - : Type(TemplateTypeParm, Canon, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - Canon->containsUnexpandedParameterPack()), + : Type(TemplateTypeParm, Canon, + TypeDependence::DependentInstantiation | + (Canon->getDependence() & TypeDependence::UnexpandedPack)), TTPDecl(TTPDecl) {} /// Build the canonical type. TemplateTypeParmType(unsigned D, unsigned I, bool PP) : Type(TemplateTypeParm, QualType(this, 0), - /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, PP) { + TypeDependence::DependentInstantiation | + (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) { CanTTPTInfo.Depth = D; CanTTPTInfo.Index = I; CanTTPTInfo.ParameterPack = PP; @@ -4767,10 +4682,7 @@ const TemplateTypeParmType *Replaced; SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) - : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), - Canon->isInstantiationDependentType(), - Canon->isVariablyModifiedType(), - Canon->containsUnexpandedParameterPack()), + : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()), Replaced(Param) {} public: @@ -4867,23 +4779,16 @@ /// the latter case, it is also a dependent type. class DeducedType : public Type { protected: - DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent, - bool IsInstantiationDependent, bool ContainsParameterPack) + DeducedType(TypeClass TC, QualType DeducedAsType, + TypeDependence ExtraDependence) : Type(TC, // FIXME: Retain the sugared deduced type? DeducedAsType.isNull() ? QualType(this, 0) : DeducedAsType.getCanonicalType(), - IsDependent, IsInstantiationDependent, - /*VariablyModified=*/false, ContainsParameterPack) { - if (!DeducedAsType.isNull()) { - if (DeducedAsType->isDependentType()) - setDependent(); - if (DeducedAsType->isInstantiationDependentType()) - setInstantiationDependent(); - if (DeducedAsType->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); - } - } + ExtraDependence | (DeducedAsType.isNull() + ? TypeDependence::None + : DeducedAsType->getDependence() & + ~TypeDependence::VariablyModified)) {} public: bool isSugared() const { return !isCanonicalUnqualified(); } @@ -4912,7 +4817,7 @@ ConceptDecl *TypeConstraintConcept; AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent, bool IsDeducedAsPack, ConceptDecl *CD, + TypeDependence ExtraDependence, ConceptDecl *CD, ArrayRef TypeConstraintArgs); const TemplateArgument *getArgBuffer() const { @@ -4983,9 +4888,10 @@ QualType DeducedAsType, bool IsDeducedAsDependent) : DeducedType(DeducedTemplateSpecialization, DeducedAsType, - IsDeducedAsDependent || Template.isDependent(), - IsDeducedAsDependent || Template.isInstantiationDependent(), - Template.containsUnexpandedParameterPack()), + toTypeDependence(Template.getDependence()) | + (IsDeducedAsDependent + ? TypeDependence::DependentInstantiation + : TypeDependence::None)), Template(Template) {} public: @@ -5187,10 +5093,8 @@ QualType InjectedType; InjectedClassNameType(CXXRecordDecl *D, QualType TST) - : Type(InjectedClassName, QualType(), /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - /*ContainsUnexpandedParameterPack=*/false), + : Type(InjectedClassName, QualType(), + TypeDependence::DependentInstantiation), Decl(D), InjectedType(TST) { assert(isa(TST)); assert(!TST.hasQualifiers()); @@ -5269,11 +5173,8 @@ class TypeWithKeyword : public Type { protected: TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, - QualType Canonical, bool Dependent, - bool InstantiationDependent, bool VariablyModified, - bool ContainsUnexpandedParameterPack) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack) { + QualType Canonical, TypeDependence Dependence) + : Type(tc, Canonical, Dependence) { TypeWithKeywordBits.Keyword = Keyword; } @@ -5337,10 +5238,7 @@ ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) : TypeWithKeyword(Keyword, Elaborated, CanonType, - NamedType->isDependentType(), - NamedType->isInstantiationDependentType(), - NamedType->isVariablyModifiedType(), - NamedType->containsUnexpandedParameterPack()), + NamedType->getDependence()), NNS(NNS), NamedType(NamedType) { ElaboratedTypeBits.HasOwnedTagDecl = false; if (OwnedTagDecl) { @@ -5411,10 +5309,9 @@ DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) - : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - NNS->containsUnexpandedParameterPack()), + : TypeWithKeyword(Keyword, DependentName, CanonType, + TypeDependence::DependentInstantiation | + toTypeDependence(NNS->getDependence())), NNS(NNS), Name(Name) {} public: @@ -5551,10 +5448,9 @@ PackExpansionType(QualType Pattern, QualType Canon, Optional NumExpansions) - : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), - /*InstantiationDependent=*/true, - /*VariablyModified=*/Pattern->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), + : Type(PackExpansion, Canon, + (Pattern->getDependence() | TypeDependence::Instantiation) & + ~TypeDependence::UnexpandedPack), Pattern(Pattern) { PackExpansionTypeBits.NumExpansions = NumExpansions ? *NumExpansions + 1 : 0; @@ -5773,8 +5669,8 @@ bool isKindOf); ObjCObjectType(enum Nonce_ObjCInterface) - : Type(ObjCInterface, QualType(), false, false, false, false), - BaseType(QualType(this_(), 0)) { + : Type(ObjCInterface, QualType(), TypeDependence::None), + BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; ObjCObjectTypeBits.NumTypeArgs = 0; ObjCObjectTypeBits.IsKindOf = 0; @@ -5989,11 +5885,7 @@ QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, - Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -6163,11 +6055,7 @@ QualType ValueType; AtomicType(QualType ValTy, QualType Canonical) - : Type(Atomic, Canonical, ValTy->isDependentType(), - ValTy->isInstantiationDependentType(), - ValTy->isVariablyModifiedType(), - ValTy->containsUnexpandedParameterPack()), - ValueType(ValTy) {} + : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {} public: /// Gets the type contained by this atomic type, i.e. @@ -6198,10 +6086,7 @@ bool isRead; PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) - : Type(Pipe, CanonicalPtr, elemType->isDependentType(), - elemType->isInstantiationDependentType(), - elemType->isVariablyModifiedType(), - elemType->containsUnexpandedParameterPack()), + : Type(Pipe, CanonicalPtr, elemType->getDependence()), ElementType(elemType), isRead(isRead) {} public: diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -453,7 +453,9 @@ let Class = EnumType in { def : Creator<[{ QualType result = ctx.getEnumType(cast(declaration)); - const_cast(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -462,7 +464,9 @@ def : Creator<[{ auto record = cast(declaration); QualType result = ctx.getRecordType(record); - const_cast(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -605,7 +609,9 @@ templateArguments, *underlyingType); } - const_cast(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -29,6 +29,7 @@ #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprConcepts.h" @@ -5122,8 +5123,12 @@ void *Mem = Allocate(sizeof(AutoType) + sizeof(TemplateArgument) * TypeConstraintArgs.size(), TypeAlignment); - auto *AT = new (Mem) AutoType(DeducedType, Keyword, IsDependent, IsPack, - TypeConstraintConcept, TypeConstraintArgs); + auto *AT = new (Mem) AutoType( + DeducedType, Keyword, + (IsDependent ? TypeDependence::DependentInstantiation + : TypeDependence::None) | + (IsPack ? TypeDependence::UnexpandedPack : TypeDependence::None), + TypeConstraintConcept, TypeConstraintArgs); Types.push_back(AT); if (InsertPos) AutoTypes.InsertNode(AT, InsertPos); @@ -5183,11 +5188,11 @@ /// getAutoDeductType - Get type pattern for deducing against 'auto'. QualType ASTContext::getAutoDeductType() const { if (AutoDeductTy.isNull()) - AutoDeductTy = QualType( - new (*this, TypeAlignment) AutoType(QualType(), AutoTypeKeyword::Auto, - /*dependent*/false, /*pack*/false, - /*concept*/nullptr, /*args*/{}), - 0); + AutoDeductTy = QualType(new (*this, TypeAlignment) + AutoType(QualType(), AutoTypeKeyword::Auto, + TypeDependence::None, + /*concept*/ nullptr, /*args*/ {}), + 0); return AutoDeductTy; } diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -20,6 +20,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/NonTrivialTypeVisitor.h" @@ -123,14 +124,15 @@ // // template int arr[] = {N...}; : Type(tc, can, - et->isDependentType() || (sz && sz->isValueDependent()) || - tc == DependentSizedArray, - et->isInstantiationDependentType() || - (sz && sz->isInstantiationDependent()) || - tc == DependentSizedArray, - (tc == VariableArray || et->isVariablyModifiedType()), - et->containsUnexpandedParameterPack() || - (sz && sz->containsUnexpandedParameterPack())), + et->getDependence() | + (sz ? toTypeDependence( + turnValueToTypeDependence(sz->getDependence())) + : TypeDependence::None) | + (tc == VariableArray ? TypeDependence::VariablyModified + : TypeDependence::None) | + (tc == DependentSizedArray + ? TypeDependence::DependentInstantiation + : TypeDependence::None)), ElementType(et) { ArrayTypeBits.IndexTypeQuals = tq; ArrayTypeBits.SizeModifier = sm; @@ -217,14 +219,16 @@ E->Profile(ID, Context, true); } -DependentVectorType::DependentVectorType( - const ASTContext &Context, QualType ElementType, QualType CanonType, - Expr *SizeExpr, SourceLocation Loc, VectorType::VectorKind VecKind) - : Type(DependentVector, CanonType, /*Dependent=*/true, - /*InstantiationDependent=*/true, - ElementType->isVariablyModifiedType(), - ElementType->containsUnexpandedParameterPack() || - (SizeExpr && SizeExpr->containsUnexpandedParameterPack())), +DependentVectorType::DependentVectorType(const ASTContext &Context, + QualType ElementType, + QualType CanonType, Expr *SizeExpr, + SourceLocation Loc, + VectorType::VectorKind VecKind) + : Type(DependentVector, CanonType, + TypeDependence::DependentInstantiation | + ElementType->getDependence() | + (SizeExpr ? toTypeDependence(SizeExpr->getDependence()) + : TypeDependence::None)), Context(Context), ElementType(ElementType), SizeExpr(SizeExpr), Loc(Loc) { VectorTypeBits.VecKind = VecKind; } @@ -238,19 +242,16 @@ SizeExpr->Profile(ID, Context, true); } -DependentSizedExtVectorType::DependentSizedExtVectorType(const - ASTContext &Context, - QualType ElementType, - QualType can, - Expr *SizeExpr, - SourceLocation loc) - : Type(DependentSizedExtVector, can, /*Dependent=*/true, - /*InstantiationDependent=*/true, - ElementType->isVariablyModifiedType(), - (ElementType->containsUnexpandedParameterPack() || - (SizeExpr && SizeExpr->containsUnexpandedParameterPack()))), - Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), - loc(loc) {} +DependentSizedExtVectorType::DependentSizedExtVectorType( + const ASTContext &Context, QualType ElementType, QualType can, + Expr *SizeExpr, SourceLocation loc) + : Type(DependentSizedExtVector, can, + TypeDependence::DependentInstantiation | + ElementType->getDependence() | + (SizeExpr ? toTypeDependence(SizeExpr->getDependence()) + : TypeDependence::None)), + Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), loc(loc) { +} void DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, @@ -260,15 +261,16 @@ SizeExpr->Profile(ID, Context, true); } -DependentAddressSpaceType::DependentAddressSpaceType( - const ASTContext &Context, QualType PointeeType, QualType can, - Expr *AddrSpaceExpr, SourceLocation loc) - : Type(DependentAddressSpace, can, /*Dependent=*/true, - /*InstantiationDependent=*/true, - PointeeType->isVariablyModifiedType(), - (PointeeType->containsUnexpandedParameterPack() || - (AddrSpaceExpr && - AddrSpaceExpr->containsUnexpandedParameterPack()))), +DependentAddressSpaceType::DependentAddressSpaceType(const ASTContext &Context, + QualType PointeeType, + QualType can, + Expr *AddrSpaceExpr, + SourceLocation loc) + : Type(DependentAddressSpace, can, + TypeDependence::DependentInstantiation | + PointeeType->getDependence() | + (AddrSpaceExpr ? toTypeDependence(AddrSpaceExpr->getDependence()) + : TypeDependence::None)), Context(Context), AddrSpaceExpr(AddrSpaceExpr), PointeeType(PointeeType), loc(loc) {} @@ -286,11 +288,7 @@ VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind) - : Type(tc, canonType, vecType->isDependentType(), - vecType->isInstantiationDependentType(), - vecType->isVariablyModifiedType(), - vecType->containsUnexpandedParameterPack()), - ElementType(vecType) { + : Type(tc, canonType, vecType->getDependence()), ElementType(vecType) { VectorTypeBits.VecKind = vecKind; VectorTypeBits.NumElements = nElements; } @@ -652,14 +650,11 @@ return OPT->isObjCClassType() || OPT->isObjCQualifiedClassType(); } -ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D, - QualType can, +ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D, QualType can, ArrayRef protocols) - : Type(ObjCTypeParam, can, can->isDependentType(), - can->isInstantiationDependentType(), - can->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), - OTPDecl(const_cast(D)) { + : Type(ObjCTypeParam, can, + can->getDependence() & ~TypeDependence::UnexpandedPack), + OTPDecl(const_cast(D)) { initialize(protocols); } @@ -667,11 +662,7 @@ ArrayRef typeArgs, ArrayRef protocols, bool isKindOf) - : Type(ObjCObject, Canonical, Base->isDependentType(), - Base->isInstantiationDependentType(), - Base->isVariablyModifiedType(), - Base->containsUnexpandedParameterPack()), - BaseType(Base) { + : Type(ObjCObject, Canonical, Base->getDependence()), BaseType(Base) { ObjCObjectTypeBits.IsKindOf = isKindOf; ObjCObjectTypeBits.NumTypeArgs = typeArgs.size(); @@ -682,13 +673,7 @@ typeArgs.size() * sizeof(QualType)); for (auto typeArg : typeArgs) { - if (typeArg->isDependentType()) - setDependent(); - else if (typeArg->isInstantiationDependentType()) - setInstantiationDependent(); - - if (typeArg->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); + addDependence(typeArg->getDependence() & ~TypeDependence::VariablyModified); } // Initialize the protocol qualifiers. The protocol storage is known // after we set number of type arguments. @@ -2715,21 +2700,20 @@ } DependentTemplateSpecializationType::DependentTemplateSpecializationType( - ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, const IdentifierInfo *Name, - ArrayRef Args, - QualType Canon) - : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true, - /*VariablyModified=*/false, - NNS && NNS->containsUnexpandedParameterPack()), - NNS(NNS), Name(Name) { + ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, + const IdentifierInfo *Name, ArrayRef Args, QualType Canon) + : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, + TypeDependence::DependentInstantiation | + (NNS ? toTypeDependence(NNS->getDependence()) + : TypeDependence::None)), + NNS(NNS), Name(Name) { DependentTemplateSpecializationTypeBits.NumArgs = Args.size(); assert((!NNS || NNS->isDependent()) && "DependentTemplateSpecializatonType requires dependent qualifier"); TemplateArgument *ArgBuffer = getArgBuffer(); for (const TemplateArgument &Arg : Args) { - if (Arg.containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); + addDependence(toTypeDependence(Arg.getDependence() & + TemplateArgumentDependence::UnexpandedPack)); new (ArgBuffer++) TemplateArgument(Arg); } @@ -2972,10 +2956,8 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef params, QualType canonical, const ExtProtoInfo &epi) - : FunctionType(FunctionProto, result, canonical, result->isDependentType(), - result->isInstantiationDependentType(), - result->isVariablyModifiedType(), - result->containsUnexpandedParameterPack(), epi.ExtInfo) { + : FunctionType(FunctionProto, result, canonical, result->getDependence(), + epi.ExtInfo) { FunctionTypeBits.FastTypeQuals = epi.TypeQuals.getFastQualifiers(); FunctionTypeBits.RefQualifier = epi.RefQualifier; FunctionTypeBits.NumParams = params.size(); @@ -2994,14 +2976,8 @@ // Fill in the trailing argument array. auto *argSlot = getTrailingObjects(); for (unsigned i = 0; i != getNumParams(); ++i) { - if (params[i]->isDependentType()) - setDependent(); - else if (params[i]->isInstantiationDependentType()) - setInstantiationDependent(); - - if (params[i]->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); - + addDependence(params[i]->getDependence() & + ~TypeDependence::VariablyModified); argSlot[i] = params[i]; } @@ -3015,11 +2991,9 @@ // Note that, before C++17, a dependent exception specification does // *not* make a type dependent; it's not even part of the C++ type // system. - if (ExceptionType->isInstantiationDependentType()) - setInstantiationDependent(); - - if (ExceptionType->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); + addDependence( + ExceptionType->getDependence() & + (TypeDependence::Instantiation | TypeDependence::UnexpandedPack)); exnSlot[I++] = ExceptionType; } @@ -3033,12 +3007,9 @@ // Store the noexcept expression and context. *getTrailingObjects() = epi.ExceptionSpec.NoexceptExpr; - if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() || - epi.ExceptionSpec.NoexceptExpr->isInstantiationDependent()) - setInstantiationDependent(); - - if (epi.ExceptionSpec.NoexceptExpr->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); + addDependence( + toTypeDependence(epi.ExceptionSpec.NoexceptExpr->getDependence()) & + (TypeDependence::Instantiation | TypeDependence::UnexpandedPack)); } // Fill in the FunctionDecl * in the exception specification if present. else if (getExceptionSpecType() == EST_Uninstantiated) { @@ -3062,11 +3033,11 @@ if (getExceptionSpecType() == EST_Dynamic || getExceptionSpecType() == EST_DependentNoexcept) { assert(hasDependentExceptionSpec() && "type should not be canonical"); - setDependent(); + addDependence(TypeDependence::DependentInstantiation); } } else if (getCanonicalTypeInternal()->isDependentType()) { // Ask our canonical type whether our exception specification was dependent. - setDependent(); + addDependence(TypeDependence::DependentInstantiation); } // Fill in the extra parameter info if present. @@ -3229,10 +3200,10 @@ } TypeOfExprType::TypeOfExprType(Expr *E, QualType can) - : Type(TypeOfExpr, can, E->isTypeDependent(), - E->isInstantiationDependent(), - E->getType()->isVariablyModifiedType(), - E->containsUnexpandedParameterPack()), + : Type(TypeOfExpr, can, + toTypeDependence(E->getDependence()) | + (E->getType()->getDependence() & + TypeDependence::VariablyModified)), TOExpr(E) {} bool TypeOfExprType::isSugared() const { @@ -3252,13 +3223,15 @@ } DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) - // C++11 [temp.type]p2: "If an expression e involves a template parameter, - // decltype(e) denotes a unique dependent type." Hence a decltype type is - // type-dependent even if its expression is only instantiation-dependent. - : Type(Decltype, can, E->isInstantiationDependent(), - E->isInstantiationDependent(), - E->getType()->isVariablyModifiedType(), - E->containsUnexpandedParameterPack()), + // C++11 [temp.type]p2: "If an expression e involves a template parameter, + // decltype(e) denotes a unique dependent type." Hence a decltype type is + // type-dependent even if its expression is only instantiation-dependent. + : Type(Decltype, can, + toTypeDependence(E->getDependence()) | + (E->isInstantiationDependent() ? TypeDependence::Dependent + : TypeDependence::None) | + (E->getType()->getDependence() & + TypeDependence::VariablyModified)), E(E), UnderlyingType(underlyingType) {} bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); } @@ -3279,13 +3252,9 @@ } UnaryTransformType::UnaryTransformType(QualType BaseType, - QualType UnderlyingType, - UTTKind UKind, + QualType UnderlyingType, UTTKind UKind, QualType CanonicalType) - : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(), - BaseType->isInstantiationDependentType(), - BaseType->isVariablyModifiedType(), - BaseType->containsUnexpandedParameterPack()), + : Type(UnaryTransform, CanonicalType, BaseType->getDependence()), BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {} DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C, @@ -3294,11 +3263,10 @@ : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) {} TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) - : Type(TC, can, D->isDependentType(), - /*InstantiationDependent=*/D->isDependentType(), - /*VariablyModified=*/false, - /*ContainsUnexpandedParameterPack=*/false), - decl(const_cast(D)) {} + : Type(TC, can, + D->isDependentType() ? TypeDependence::DependentInstantiation + : TypeDependence::None), + decl(const_cast(D)) {} static TagDecl *getInterestingTagDecl(TagDecl *decl) { for (auto I : decl->redecls()) { @@ -3407,11 +3375,12 @@ return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier(); } -SubstTemplateTypeParmPackType:: -SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, - QualType Canon, - const TemplateArgument &ArgPack) - : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), +SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType( + const TemplateTypeParmType *Param, QualType Canon, + const TemplateArgument &ArgPack) + : Type(SubstTemplateTypeParmPack, Canon, + TypeDependence::DependentInstantiation | + TypeDependence::UnexpandedPack), Replaced(Param), Arguments(ArgPack.pack_begin()) { SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); } @@ -3455,16 +3424,17 @@ return false; } -TemplateSpecializationType:: -TemplateSpecializationType(TemplateName T, - ArrayRef Args, - QualType Canon, QualType AliasedType) - : Type(TemplateSpecialization, - Canon.isNull()? QualType(this, 0) : Canon, - Canon.isNull()? true : Canon->isDependentType(), - Canon.isNull()? true : Canon->isInstantiationDependentType(), - false, - T.containsUnexpandedParameterPack()), Template(T) { +TemplateSpecializationType::TemplateSpecializationType( + TemplateName T, ArrayRef Args, QualType Canon, + QualType AliasedType) + : Type(TemplateSpecialization, Canon.isNull() ? QualType(this, 0) : Canon, + (Canon.isNull() + ? TypeDependence::DependentInstantiation + : Canon->getDependence() & ~(TypeDependence::VariablyModified | + TypeDependence::UnexpandedPack)) | + (toTypeDependence(T.getDependence()) & + TypeDependence::UnexpandedPack)), + Template(T) { TemplateSpecializationTypeBits.NumArgs = Args.size(); TemplateSpecializationTypeBits.TypeAlias = !AliasedType.isNull(); @@ -3485,13 +3455,11 @@ // U is always non-dependent, irrespective of the type T. // However, U contains an unexpanded parameter pack, even though // its expansion (and thus its desugared type) doesn't. - if (Arg.isInstantiationDependent()) - setInstantiationDependent(); - if (Arg.getKind() == TemplateArgument::Type && - Arg.getAsType()->isVariablyModifiedType()) - setVariablyModified(); - if (Arg.containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); + addDependence(toTypeDependence(Arg.getDependence()) & + ~TypeDependence::Dependent); + if (Arg.getKind() == TemplateArgument::Type) + addDependence(Arg.getAsType()->getDependence() & + TypeDependence::VariablyModified); new (TemplateArgs++) TemplateArgument(Arg); } @@ -4178,19 +4146,18 @@ } AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent, bool IsDeducedAsPack, + TypeDependence ExtraDependence, ConceptDecl *TypeConstraintConcept, ArrayRef TypeConstraintArgs) - : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, - IsDeducedAsDependent, IsDeducedAsPack) { + : DeducedType(Auto, DeducedAsType, ExtraDependence) { AutoTypeBits.Keyword = (unsigned)Keyword; AutoTypeBits.NumArgs = TypeConstraintArgs.size(); this->TypeConstraintConcept = TypeConstraintConcept; if (TypeConstraintConcept) { TemplateArgument *ArgBuffer = getArgBuffer(); for (const TemplateArgument &Arg : TypeConstraintArgs) { - if (Arg.containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); + addDependence(toTypeDependence( + Arg.getDependence() & TemplateArgumentDependence::UnexpandedPack)); new (ArgBuffer++) TemplateArgument(Arg); }