From fd70e5de3918395052fca08fdc3572ed533a2165 Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Fri, 17 Nov 2017 23:43:46 +0000 Subject: [PATCH] [AST] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC). llvm-svn: 318570 --- clang/include/clang/AST/Type.h | 1017 ++++++++++++++++++++++++---------------- clang/lib/AST/Type.cpp | 205 ++++---- 2 files changed, 733 insertions(+), 489 deletions(-) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index e195647..9a23637 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1,4 +1,4 @@ -//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===// +//===- Type.h - C Language Family Type Representation -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,12 +6,13 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// +// /// \file /// \brief C Language Family Type Representation /// /// This file defines the clang::Type interface and subclasses, used to /// represent types for languages in the C family. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_TYPE_H @@ -25,83 +26,118 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/Linkage.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/Visibility.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" +#include +#include +#include +#include +#include +#include +#include namespace clang { - enum { - TypeAlignmentInBits = 4, - TypeAlignment = 1 << TypeAlignmentInBits - }; - class Type; - class ExtQuals; - class QualType; -} + +class ExtQuals; +class QualType; +class Type; + +enum { + TypeAlignmentInBits = 4, + TypeAlignment = 1 << TypeAlignmentInBits +}; + +} // namespace clang namespace llvm { + template struct PointerLikeTypeTraits; template<> struct PointerLikeTypeTraits< ::clang::Type*> { static inline void *getAsVoidPointer(::clang::Type *P) { return P; } + static inline ::clang::Type *getFromVoidPointer(void *P) { return static_cast< ::clang::Type*>(P); } + enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; }; + template<> struct PointerLikeTypeTraits< ::clang::ExtQuals*> { static inline void *getAsVoidPointer(::clang::ExtQuals *P) { return P; } + static inline ::clang::ExtQuals *getFromVoidPointer(void *P) { return static_cast< ::clang::ExtQuals*>(P); } + enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; }; template <> struct isPodLike { static const bool value = true; }; -} + +} // namespace llvm namespace clang { - class ASTContext; - class TypedefNameDecl; - class TemplateDecl; - class TemplateTypeParmDecl; - class NonTypeTemplateParmDecl; - class TemplateTemplateParmDecl; - class TagDecl; - class RecordDecl; - class CXXRecordDecl; - class EnumDecl; - class FieldDecl; - class FunctionDecl; - class ObjCInterfaceDecl; - class ObjCProtocolDecl; - class ObjCMethodDecl; - class ObjCTypeParamDecl; - class UnresolvedUsingTypenameDecl; - class Expr; - class Stmt; - class SourceLocation; - class StmtIteratorBase; - class TemplateArgument; - class TemplateArgumentLoc; - class TemplateArgumentListInfo; - class ElaboratedType; - class ExtQuals; - class ExtQualsTypeCommonBase; - struct PrintingPolicy; - - template class CanQual; - typedef CanQual CanQualType; + +class ArrayType; +class ASTContext; +class AttributedType; +class AutoType; +class BuiltinType; +template class CanQual; +class ComplexType; +class CXXRecordDecl; +class DeclContext; +class DeducedType; +class EnumDecl; +class Expr; +class ExtQualsTypeCommonBase; +class FunctionDecl; +class FunctionNoProtoType; +class FunctionProtoType; +class IdentifierInfo; +class InjectedClassNameType; +class NamedDecl; +class ObjCInterfaceDecl; +class ObjCObjectPointerType; +class ObjCObjectType; +class ObjCProtocolDecl; +class ObjCTypeParamDecl; +class ParenType; +struct PrintingPolicy; +class RecordDecl; +class RecordType; +class Stmt; +class TagDecl; +class TemplateArgument; +class TemplateArgumentListInfo; +class TemplateArgumentLoc; +class TemplateSpecializationType; +class TemplateTypeParmDecl; +class TypedefNameDecl; +class TypedefType; +class UnresolvedUsingTypenameDecl; + +using CanQualType = CanQual; // Provide forward declarations for all of the *Type classes #define TYPE(Class, Base) class Class##Type; @@ -536,7 +572,6 @@ public: } private: - // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| // |C R V|U|GCAttr|Lifetime|AddressSpace| uint32_t Mask = 0; @@ -556,12 +591,12 @@ private: /// into its local qualifiers and its locally-unqualified type. struct SplitQualType { /// The locally-unqualified type. - const Type *Ty; + const Type *Ty = nullptr; /// The local qualifiers. Qualifiers Quals; - SplitQualType() : Ty(nullptr), Quals() {} + SplitQualType() = default; SplitQualType(const Type *ty, Qualifiers qs) : Ty(ty), Quals(qs) {} SplitQualType getSingleStepDesugaredType() const; // end of this file @@ -587,12 +622,16 @@ struct SplitQualType { enum class ObjCSubstitutionContext { /// An ordinary type. Ordinary, + /// The result type of a method or function. Result, + /// The parameter type of a method or function. Parameter, + /// The type of a property. Property, + /// The superclass of a type. Superclass, }; @@ -612,8 +651,10 @@ enum class ObjCSubstitutionContext { /// indicates whether there are extended qualifiers present, in which /// case the pointer points to a special structure. class QualType { + friend class QualifierCollector; + // Thankfully, these are efficiently composable. - llvm::PointerIntPair, + llvm::PointerIntPair, Qualifiers::FastWidth> Value; const ExtQuals *getExtQualsUnsafe() const { @@ -632,14 +673,10 @@ class QualType { return reinterpret_cast(CommonPtrVal); } - friend class QualifierCollector; public: QualType() = default; - - QualType(const Type *Ptr, unsigned Quals) - : Value(Ptr, Quals) {} - QualType(const ExtQuals *Ptr, unsigned Quals) - : Value(Ptr, Quals) {} + QualType(const Type *Ptr, unsigned Quals) : Value(Ptr, Quals) {} + QualType(const ExtQuals *Ptr, unsigned Quals) : Value(Ptr, Quals) {} unsigned getLocalFastQualifiers() const { return Value.getInt(); } void setLocalFastQualifiers(unsigned Quals) { Value.setInt(Quals); } @@ -660,6 +697,7 @@ public: SplitQualType split() const; void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + static QualType getFromOpaquePtr(const void *Ptr) { QualType T; T.Value.setFromOpaqueValue(const_cast(Ptr)); @@ -941,12 +979,15 @@ public: friend bool operator!=(const QualType &LHS, const QualType &RHS) { return LHS.Value != RHS.Value; } + std::string getAsString() const { return getAsString(split()); } + static std::string getAsString(SplitQualType split) { return getAsString(split.Ty, split.Quals); } + static std::string getAsString(const Type *ty, Qualifiers qs); std::string getAsString(const PrintingPolicy &Policy) const; @@ -956,11 +997,13 @@ public: unsigned Indentation = 0) const { print(split(), OS, Policy, PlaceHolder, Indentation); } + static void print(SplitQualType split, raw_ostream &OS, const PrintingPolicy &policy, const Twine &PlaceHolder, unsigned Indentation = 0) { return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); } + static void print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, const Twine &PlaceHolder, @@ -970,10 +1013,12 @@ public: const PrintingPolicy &Policy) const { return getAsStringInternal(split(), Str, Policy); } + static void getAsStringInternal(SplitQualType split, std::string &out, const PrintingPolicy &policy) { return getAsStringInternal(split.Ty, split.Quals, out, policy); } + static void getAsStringInternal(const Type *ty, Qualifiers qs, std::string &out, const PrintingPolicy &policy); @@ -983,11 +1028,12 @@ public: const PrintingPolicy &Policy; const Twine &PlaceHolder; unsigned Indentation; + public: StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, const Twine &PlaceHolder, unsigned Indentation) - : T(T), Policy(Policy), PlaceHolder(PlaceHolder), - Indentation(Indentation) { } + : T(T), Policy(Policy), PlaceHolder(PlaceHolder), + Indentation(Indentation) {} friend raw_ostream &operator<<(raw_ostream &OS, const StreamedQualTypeHelper &SQT) { @@ -1120,6 +1166,7 @@ public: private: bool unionHasUniqueObjectRepresentations(const ASTContext& Context) const; bool structHasUniqueObjectRepresentations(const ASTContext& Context) const; + // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the // caller. @@ -1133,13 +1180,15 @@ private: static DestructionKind isDestructedTypeImpl(QualType type); }; -} // end clang. +} // namespace clang namespace llvm { + /// Implement simplify_type for QualType, so that we can dyn_cast from QualType /// to a specific Type class. template<> struct simplify_type< ::clang::QualType> { - typedef const ::clang::Type *SimpleType; + using SimpleType = const ::clang::Type *; + static SimpleType getSimplifiedValue(::clang::QualType Val) { return Val.getTypePtr(); } @@ -1151,24 +1200,26 @@ struct PointerLikeTypeTraits { static inline void *getAsVoidPointer(clang::QualType P) { return P.getAsOpaquePtr(); } + static inline clang::QualType getFromVoidPointer(void *P) { return clang::QualType::getFromOpaquePtr(P); } + // Various qualifiers go in low bits. enum { NumLowBitsAvailable = 0 }; }; -} // end namespace llvm +} // namespace llvm namespace clang { /// \brief Base class that is common to both the \c ExtQuals and \c Type /// classes, which allows \c QualType to access the common fields between the /// two. -/// class ExtQualsTypeCommonBase { - ExtQualsTypeCommonBase(const Type *baseType, QualType canon) - : BaseType(baseType), CanonicalType(canon) {} + friend class ExtQuals; + friend class QualType; + friend class Type; /// \brief The "base" type of an extended qualifiers type (\c ExtQuals) or /// a self-referential pointer (for \c Type). @@ -1180,9 +1231,8 @@ class ExtQualsTypeCommonBase { /// \brief The canonical type of this type. A QualType. QualType CanonicalType; - friend class QualType; - friend class Type; - friend class ExtQuals; + ExtQualsTypeCommonBase(const Type *baseType, QualType canon) + : BaseType(baseType), CanonicalType(canon) {} }; /// We can encode up to four bits in the low bits of a @@ -1217,10 +1267,9 @@ class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { public: ExtQuals(const Type *baseType, QualType canon, Qualifiers quals) - : ExtQualsTypeCommonBase(baseType, - canon.isNull() ? QualType(this_(), 0) : canon), - Quals(quals) - { + : ExtQualsTypeCommonBase(baseType, + canon.isNull() ? QualType(this_(), 0) : canon), + Quals(quals) { assert(Quals.hasNonFastQualifiers() && "ExtQuals created with no fast qualifiers"); assert(!Quals.hasFastQualifiers() @@ -1246,6 +1295,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, getBaseType(), Quals); } + static void Profile(llvm::FoldingSetNodeID &ID, const Type *BaseType, Qualifiers Quals) { @@ -1261,8 +1311,10 @@ public: enum RefQualifierKind { /// \brief No ref-qualifier was provided. RQ_None = 0, + /// \brief An lvalue ref-qualifier was provided (\c &). RQ_LValue, + /// \brief An rvalue ref-qualifier was provided (\c &&). RQ_RValue }; @@ -1271,8 +1323,10 @@ enum RefQualifierKind { enum class AutoTypeKeyword { /// \brief auto Auto, + /// \brief decltype(auto) DecltypeAuto, + /// \brief __auto_type (GNU extension) GNUAutoType }; @@ -1314,9 +1368,6 @@ public: }; private: - Type(const Type &) = delete; - void operator=(const Type &) = delete; - /// Bitfields required by the Type class. class TypeBitfields { friend class Type; @@ -1355,10 +1406,12 @@ private: bool isCacheValid() const { return CacheValid; } + Linkage getLinkage() const { assert(isCacheValid() && "getting linkage from invalid cache"); return static_cast(CachedLinkage); } + bool hasLocalOrUnnamedType() const { assert(isCacheValid() && "getting linkage from invalid cache"); return CachedLocalOrUnnamed; @@ -1395,8 +1448,8 @@ protected: }; class FunctionTypeBitfields { - friend class FunctionType; friend class FunctionProtoType; + friend class FunctionType; unsigned : NumTypeBits; @@ -1432,6 +1485,7 @@ protected: /// Whether this is a "kindof" type. unsigned IsKindOf : 1; }; + static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned"); class ReferenceTypeBitfields { @@ -1514,21 +1568,21 @@ protected: }; private: + template friend class TypePropertyCache; + /// \brief Set whether this type comes from an AST file. void setFromAST(bool V = true) const { TypeBits.FromAST = V; } - template friend class TypePropertyCache; - protected: - // silence VC++ warning C4355: 'this' : used in base member initializer list - Type *this_() { return this; } + friend class ASTContext; + Type(TypeClass tc, QualType canon, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack) - : ExtQualsTypeCommonBase(this, - canon.isNull() ? QualType(this_(), 0) : canon) { + : ExtQualsTypeCommonBase(this, + canon.isNull() ? QualType(this_(), 0) : canon) { TypeBits.TC = tc; TypeBits.Dependent = Dependent; TypeBits.InstantiationDependent = Dependent || InstantiationDependent; @@ -1539,22 +1593,32 @@ protected: TypeBits.CachedLinkage = NoLinkage; TypeBits.FromAST = false; } - friend class ASTContext; + + // silence VC++ warning C4355: 'this' : used in base member initializer list + Type *this_() { return this; } void setDependent(bool D = true) { TypeBits.Dependent = D; if (D) TypeBits.InstantiationDependent = true; } + void setInstantiationDependent(bool D = true) { TypeBits.InstantiationDependent = D; } - void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; - } + + void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } + void setContainsUnexpandedParameterPack(bool PP = true) { TypeBits.ContainsUnexpandedParameterPack = PP; } public: + friend class ASTReader; + friend class ASTWriter; + + Type(const Type &) = delete; + Type &operator=(const Type &) = delete; + TypeClass getTypeClass() const { return static_cast(TypeBits.TC); } /// \brief Whether this type comes from an AST file. @@ -1661,6 +1725,7 @@ public: /// Determine whether this type is an integral or enumeration type. bool isIntegralOrEnumerationType() const; + /// Determine whether this type is an integral or unscoped enumeration type. bool isIntegralOrUnscopedEnumerationType() const; @@ -1793,6 +1858,7 @@ public: STK_IntegralComplex, STK_FloatingComplex }; + /// Given that this is a scalar type, classify it. ScalarTypeKind getScalarTypeKind() const; @@ -1863,6 +1929,7 @@ public: const RecordType *getAsUnionType() const; const ComplexType *getAsComplexIntegerType() const; // GCC complex int type. const ObjCObjectType *getAsObjCInterfaceType() const; + // The following is a convenience method that returns an ObjCObjectPointerType // for object declared using an interface. const ObjCObjectPointerType *getAsObjCInterfacePointerType() const; @@ -2049,12 +2116,10 @@ public: QualType getCanonicalTypeInternal() const { return CanonicalType; } + CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h void dump() const; void dump(llvm::raw_ostream &OS) const; - - friend class ASTReader; - friend class ASTWriter; }; /// \brief This will check for a TypedefType by removing any existing sugar @@ -2082,7 +2147,6 @@ template <> inline const Class##Type *Type::castAs() const { \ } #include "clang/AST/TypeNodes.def" - /// This class is used for builtin types like 'int'. Builtin /// types are always canonical and have a literal name field. class BuiltinType : public Type { @@ -2099,15 +2163,16 @@ public: public: BuiltinType(Kind K) - : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), - /*InstantiationDependent=*/(K == Dependent), - /*VariablyModified=*/false, - /*Unexpanded parameter pack=*/false) { + : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), + /*InstantiationDependent=*/(K == Dependent), + /*VariablyModified=*/false, + /*Unexpanded parameter pack=*/false) { BuiltinTypeBits.Kind = K; } Kind getKind() const { return static_cast(BuiltinTypeBits.Kind); } StringRef getName(const PrintingPolicy &Policy) const; + const char *getNameAsCString(const PrintingPolicy &Policy) const { // The StringRef is null-terminated. StringRef str = getName(Policy); @@ -2164,17 +2229,17 @@ public: /// Complex values, per C99 6.2.5p11. This supports the C99 complex /// types (_Complex float etc) as well as the GCC integer complex extensions. -/// class ComplexType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType ElementType; - ComplexType(QualType Element, QualType CanonicalPtr) : - Type(Complex, CanonicalPtr, Element->isDependentType(), - Element->isInstantiationDependentType(), - Element->isVariablyModifiedType(), - Element->containsUnexpandedParameterPack()), - ElementType(Element) { - } - friend class ASTContext; // ASTContext creates these. + + ComplexType(QualType Element, QualType CanonicalPtr) + : Type(Complex, CanonicalPtr, Element->isDependentType(), + Element->isInstantiationDependentType(), + Element->isVariablyModifiedType(), + Element->containsUnexpandedParameterPack()), + ElementType(Element) {} public: QualType getElementType() const { return ElementType; } @@ -2185,6 +2250,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { ID.AddPointer(Element.getAsOpaquePtr()); } @@ -2193,21 +2259,19 @@ public: }; /// Sugar for parentheses used when specifying types. -/// class ParenType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType Inner; - ParenType(QualType InnerType, QualType CanonType) : - Type(Paren, CanonType, InnerType->isDependentType(), - InnerType->isInstantiationDependentType(), - InnerType->isVariablyModifiedType(), - InnerType->containsUnexpandedParameterPack()), - Inner(InnerType) { - } - friend class ASTContext; // ASTContext creates these. + ParenType(QualType InnerType, QualType CanonType) + : Type(Paren, CanonType, InnerType->isDependentType(), + InnerType->isInstantiationDependentType(), + InnerType->isVariablyModifiedType(), + InnerType->containsUnexpandedParameterPack()), + Inner(InnerType) {} public: - QualType getInnerType() const { return Inner; } bool isSugared() const { return true; } @@ -2216,6 +2280,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getInnerType()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Inner) { Inner.Profile(ID); } @@ -2224,21 +2289,19 @@ public: }; /// PointerType - C99 6.7.5.1 - Pointer Declarators. -/// class PointerType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType PointeeType; - PointerType(QualType Pointee, QualType CanonicalPtr) : - Type(Pointer, CanonicalPtr, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), - PointeeType(Pointee) { - } - friend class ASTContext; // ASTContext creates these. + PointerType(QualType Pointee, QualType CanonicalPtr) + : Type(Pointer, CanonicalPtr, Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), + Pointee->isVariablyModifiedType(), + Pointee->containsUnexpandedParameterPack()), + PointeeType(Pointee) {} public: - QualType getPointeeType() const { return PointeeType; } /// Returns true if address spaces of pointers overlap. @@ -2263,6 +2326,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { ID.AddPointer(Pointee.getAsOpaquePtr()); } @@ -2278,6 +2342,8 @@ class AdjustedType : public Type, public llvm::FoldingSetNode { QualType AdjustedTy; protected: + friend class ASTContext; // ASTContext creates these. + AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, QualType CanonicalPtr) : Type(TC, CanonicalPtr, OriginalTy->isDependentType(), @@ -2286,8 +2352,6 @@ protected: OriginalTy->containsUnexpandedParameterPack()), OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} - friend class ASTContext; // ASTContext creates these. - public: QualType getOriginalType() const { return OriginalTy; } QualType getAdjustedType() const { return AdjustedTy; } @@ -2298,6 +2362,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, OriginalTy, AdjustedTy); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Orig, QualType New) { ID.AddPointer(Orig.getAsOpaquePtr()); ID.AddPointer(New.getAsOpaquePtr()); @@ -2310,12 +2375,11 @@ public: /// Represents a pointer type decayed from an array or function type. class DecayedType : public AdjustedType { + friend class ASTContext; // ASTContext creates these. inline DecayedType(QualType OriginalType, QualType Decayed, QualType Canonical); - friend class ASTContext; // ASTContext creates these. - public: QualType getDecayedType() const { return getAdjustedType(); } @@ -2327,20 +2391,20 @@ public: /// Pointer to a block type. /// This type is to represent types syntactically represented as /// "void (^)(int)", etc. Pointee is required to always be a function type. -/// class BlockPointerType : public Type, public llvm::FoldingSetNode { - QualType PointeeType; // Block is some kind of pointer type - BlockPointerType(QualType Pointee, QualType CanonicalCls) : - Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), - PointeeType(Pointee) { - } - friend class ASTContext; // ASTContext creates these. + friend class ASTContext; // ASTContext creates these. -public: + // Block is some kind of pointer type + QualType PointeeType; + BlockPointerType(QualType Pointee, QualType CanonicalCls) + : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), + Pointee->isVariablyModifiedType(), + Pointee->containsUnexpandedParameterPack()), + PointeeType(Pointee) {} + +public: // Get the pointee type. Pointee is required to always be a function type. QualType getPointeeType() const { return PointeeType; } @@ -2350,6 +2414,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { ID.AddPointer(Pointee.getAsOpaquePtr()); } @@ -2360,19 +2425,17 @@ public: }; /// Base for LValueReferenceType and RValueReferenceType -/// class ReferenceType : public Type, public llvm::FoldingSetNode { QualType PointeeType; protected: ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, - bool SpelledAsLValue) : - Type(tc, CanonicalRef, Referencee->isDependentType(), - Referencee->isInstantiationDependentType(), - Referencee->isVariablyModifiedType(), - Referencee->containsUnexpandedParameterPack()), - PointeeType(Referencee) - { + bool SpelledAsLValue) + : Type(tc, CanonicalRef, Referencee->isDependentType(), + Referencee->isInstantiationDependentType(), + Referencee->isVariablyModifiedType(), + Referencee->containsUnexpandedParameterPack()), + PointeeType(Referencee) { ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); } @@ -2382,6 +2445,7 @@ public: bool isInnerRef() const { return ReferenceTypeBits.InnerRef; } QualType getPointeeTypeAsWritten() const { return PointeeType; } + QualType getPointeeType() const { // FIXME: this might strip inner qualifiers; okay? const ReferenceType *T = this; @@ -2393,6 +2457,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, PointeeType, isSpelledAsLValue()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee, bool SpelledAsLValue) { @@ -2407,13 +2472,14 @@ public: }; /// An lvalue reference type, per C++11 [dcl.ref]. -/// class LValueReferenceType : public ReferenceType { - LValueReferenceType(QualType Referencee, QualType CanonicalRef, - bool SpelledAsLValue) : - ReferenceType(LValueReference, Referencee, CanonicalRef, SpelledAsLValue) - {} friend class ASTContext; // ASTContext creates these + + LValueReferenceType(QualType Referencee, QualType CanonicalRef, + bool SpelledAsLValue) + : ReferenceType(LValueReference, Referencee, CanonicalRef, + SpelledAsLValue) {} + public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2424,12 +2490,12 @@ public: }; /// An rvalue reference type, per C++11 [dcl.ref]. -/// class RValueReferenceType : public ReferenceType { - RValueReferenceType(QualType Referencee, QualType CanonicalRef) : - ReferenceType(RValueReference, Referencee, CanonicalRef, false) { - } friend class ASTContext; // ASTContext creates these + + RValueReferenceType(QualType Referencee, QualType CanonicalRef) + : ReferenceType(RValueReference, Referencee, CanonicalRef, false) {} + public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2442,24 +2508,24 @@ public: /// A pointer to member type per C++ 8.3.3 - Pointers to members. /// /// This includes both pointers to data members and pointer to member functions. -/// class MemberPointerType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType PointeeType; + /// The class of which the pointee is a member. Must ultimately be a /// RecordType, but could be a typedef or a template parameter too. const Type *Class; - 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) { - } - friend class ASTContext; // ASTContext creates these. + 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) {} public: QualType getPointeeType() const { return PointeeType; } @@ -2485,6 +2551,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType(), getClass()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, const Type *Class) { ID.AddPointer(Pointee.getAsOpaquePtr()); @@ -2497,7 +2564,6 @@ public: }; /// Represents an array type, per C99 6.7.5.2 - Array Declarators. -/// class ArrayType : public Type, public llvm::FoldingSetNode { public: /// Capture whether this is a normal array (e.g. int X[4]) @@ -2507,11 +2573,14 @@ public: enum ArraySizeModifier { Normal, Static, Star }; + private: /// The element type of the array. QualType ElementType; protected: + friend class ASTContext; // ASTContext creates these. + // C++ [temp.dep.type]p1: // A type is dependent if it is... // - an array type constructed from any dependent type or whose @@ -2520,25 +2589,26 @@ protected: ArrayType(TypeClass tc, QualType et, QualType can, ArraySizeModifier sm, unsigned tq, bool ContainsUnexpandedParameterPack) - : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, - et->isInstantiationDependentType() || tc == DependentSizedArray, - (tc == VariableArray || et->isVariablyModifiedType()), - ContainsUnexpandedParameterPack), - ElementType(et) { + : Type(tc, can, et->isDependentType() || tc == DependentSizedArray, + et->isInstantiationDependentType() || tc == DependentSizedArray, + (tc == VariableArray || et->isVariablyModifiedType()), + ContainsUnexpandedParameterPack), + ElementType(et) { ArrayTypeBits.IndexTypeQuals = tq; ArrayTypeBits.SizeModifier = sm; } - friend class ASTContext; // ASTContext creates these. - public: QualType getElementType() const { return ElementType; } + ArraySizeModifier getSizeModifier() const { return ArraySizeModifier(ArrayTypeBits.SizeModifier); } + Qualifiers getIndexTypeQualifiers() const { return Qualifiers::fromCVRMask(getIndexTypeCVRQualifiers()); } + unsigned getIndexTypeCVRQualifiers() const { return ArrayTypeBits.IndexTypeQuals; } @@ -2559,21 +2629,23 @@ class ConstantArrayType : public ArrayType { ConstantArrayType(QualType et, QualType can, const llvm::APInt &size, ArraySizeModifier sm, unsigned tq) - : ArrayType(ConstantArray, et, can, sm, tq, - et->containsUnexpandedParameterPack()), - Size(size) {} + : ArrayType(ConstantArray, et, can, sm, tq, + et->containsUnexpandedParameterPack()), + Size(size) {} + protected: + friend class ASTContext; // ASTContext creates these. + ConstantArrayType(TypeClass tc, QualType et, QualType can, const llvm::APInt &size, ArraySizeModifier sm, unsigned tq) - : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()), - Size(size) {} - friend class ASTContext; // ASTContext creates these. + : ArrayType(tc, et, can, sm, tq, et->containsUnexpandedParameterPack()), + Size(size) {} + public: const llvm::APInt &getSize() const { return Size; } bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } - /// \brief Determine the number of bits required to address a member of // an array with the given element type and number of elements. static unsigned getNumAddressingBits(const ASTContext &Context, @@ -2588,6 +2660,7 @@ public: Profile(ID, getElementType(), getSize(), getSizeModifier(), getIndexTypeCVRQualifiers()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType ET, const llvm::APInt &ArraySize, ArraySizeModifier SizeMod, unsigned TypeQuals) { @@ -2596,6 +2669,7 @@ public: ID.AddInteger(SizeMod); ID.AddInteger(TypeQuals); } + static bool classof(const Type *T) { return T->getTypeClass() == ConstantArray; } @@ -2605,13 +2679,16 @@ public: /// an IncompleteArrayType where the element type is 'int' and the size is /// unspecified. class IncompleteArrayType : public ArrayType { + friend class ASTContext; // ASTContext creates these. IncompleteArrayType(QualType et, QualType can, ArraySizeModifier sm, unsigned tq) - : ArrayType(IncompleteArray, et, can, sm, tq, - et->containsUnexpandedParameterPack()) {} - friend class ASTContext; // ASTContext creates these. + : ArrayType(IncompleteArray, et, can, sm, tq, + et->containsUnexpandedParameterPack()) {} + public: + friend class StmtIteratorBase; + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2619,8 +2696,6 @@ public: return T->getTypeClass() == IncompleteArray; } - friend class StmtIteratorBase; - void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getSizeModifier(), getIndexTypeCVRQualifiers()); @@ -2648,28 +2723,32 @@ public: /// ++x; /// int Z[x]; /// } -/// class VariableArrayType : public ArrayType { + friend class ASTContext; // ASTContext creates these. + /// An assignment-expression. VLA's are only permitted within /// a function block. Stmt *SizeExpr; + /// The range spanned by the left and right array brackets. SourceRange Brackets; VariableArrayType(QualType et, QualType can, Expr *e, ArraySizeModifier sm, unsigned tq, SourceRange brackets) - : ArrayType(VariableArray, et, can, sm, tq, - et->containsUnexpandedParameterPack()), - SizeExpr((Stmt*) e), Brackets(brackets) {} - friend class ASTContext; // ASTContext creates these. + : ArrayType(VariableArray, et, can, sm, tq, + et->containsUnexpandedParameterPack()), + SizeExpr((Stmt*) e), Brackets(brackets) {} public: + friend class StmtIteratorBase; + Expr *getSizeExpr() const { // We use C-style casts instead of cast<> here because we do not wish // to have a dependency of Type.h on Stmt.h/Expr.h. return (Expr*) SizeExpr; } + SourceRange getBracketsRange() const { return Brackets; } SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } @@ -2681,8 +2760,6 @@ public: return T->getTypeClass() == VariableArray; } - friend class StmtIteratorBase; - void Profile(llvm::FoldingSetNodeID &ID) { llvm_unreachable("Cannot unique VariableArrayTypes."); } @@ -2702,6 +2779,8 @@ public: /// until template instantiation occurs, at which point this will /// become either a ConstantArrayType or a VariableArrayType. class DependentSizedArrayType : public ArrayType { + friend class ASTContext; // ASTContext creates these. + const ASTContext &Context; /// \brief An assignment expression that will instantiate to the @@ -2718,14 +2797,15 @@ class DependentSizedArrayType : public ArrayType { Expr *e, ArraySizeModifier sm, unsigned tq, SourceRange brackets); - friend class ASTContext; // ASTContext creates these. - public: + friend class StmtIteratorBase; + Expr *getSizeExpr() const { // We use C-style casts instead of cast<> here because we do not wish // to have a dependency of Type.h on Stmt.h/Expr.h. return (Expr*) SizeExpr; } + SourceRange getBracketsRange() const { return Brackets; } SourceLocation getLBracketLoc() const { return Brackets.getBegin(); } SourceLocation getRBracketLoc() const { return Brackets.getEnd(); } @@ -2737,9 +2817,6 @@ public: return T->getTypeClass() == DependentSizedArray; } - friend class StmtIteratorBase; - - void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getElementType(), getSizeModifier(), getIndexTypeCVRQualifiers(), getSizeExpr()); @@ -2762,6 +2839,8 @@ public: /// } /// \endcode class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + const ASTContext &Context; Expr *AddrSpaceExpr; QualType PointeeType; @@ -2771,8 +2850,6 @@ class DependentAddressSpaceType : public Type, public llvm::FoldingSetNode { QualType can, Expr *AddrSpaceExpr, SourceLocation loc); - friend class ASTContext; - public: Expr *getAddrSpaceExpr() const { return AddrSpaceExpr; } QualType getPointeeType() const { return PointeeType; } @@ -2804,17 +2881,19 @@ public: /// } /// \endcode class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + const ASTContext &Context; Expr *SizeExpr; + /// The element type of the array. QualType ElementType; + SourceLocation loc; DependentSizedExtVectorType(const ASTContext &Context, QualType ElementType, QualType can, Expr *SizeExpr, SourceLocation loc); - friend class ASTContext; - public: Expr *getSizeExpr() const { return SizeExpr; } QualType getElementType() const { return ElementType; } @@ -2844,14 +2923,28 @@ public: class VectorType : public Type, public llvm::FoldingSetNode { public: enum VectorKind { - GenericVector, ///< not a target-specific vector type - AltiVecVector, ///< is AltiVec vector - AltiVecPixel, ///< is AltiVec 'vector Pixel' - AltiVecBool, ///< is AltiVec 'vector bool ...' - NeonVector, ///< is ARM Neon vector - NeonPolyVector ///< is ARM Neon polynomial vector + /// not a target-specific vector type + GenericVector, + + /// is AltiVec vector + AltiVecVector, + + /// is AltiVec 'vector Pixel' + AltiVecPixel, + + /// is AltiVec 'vector bool ...' + AltiVecBool, + + /// is ARM Neon vector + NeonVector, + + /// is ARM Neon polynomial vector + NeonPolyVector }; + protected: + friend class ASTContext; // ASTContext creates these. + /// The element type of the vector. QualType ElementType; @@ -2861,12 +2954,10 @@ protected: VectorType(TypeClass tc, QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind); - friend class ASTContext; // ASTContext creates these. - public: - QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } + static bool isVectorSizeTooLarge(unsigned NumElements) { return NumElements > VectorTypeBitfields::MaxNumElements; } @@ -2882,6 +2973,7 @@ public: Profile(ID, getElementType(), getNumElements(), getTypeClass(), getVectorKind()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, unsigned NumElements, TypeClass TypeClass, VectorKind VecKind) { @@ -2903,9 +2995,11 @@ public: /// points (as .xyzw), colors (as .rgba), and textures (modeled after OpenGL /// Shading Language). class ExtVectorType : public VectorType { - ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) : - VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} - friend class ASTContext; // ASTContext creates these. + friend class ASTContext; // ASTContext creates these. + + ExtVectorType(QualType vecType, unsigned nElements, QualType canonType) + : VectorType(ExtVector, vecType, nElements, canonType, GenericVector) {} + public: static int getPointAccessorIdx(char c) { switch (c) { @@ -2916,6 +3010,7 @@ public: case 'w': case 'a': return 3; } } + static int getNumericAccessorIdx(char c) { switch (c) { default: return -1; @@ -2956,6 +3051,7 @@ public: return unsigned(idx-1) < getNumElements(); return false; } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2966,12 +3062,11 @@ public: /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base /// class of FunctionNoProtoType and FunctionProtoType. -/// class FunctionType : public Type { // The type returned by the function. QualType ResultType; - public: +public: /// A class which abstracts out some details necessary for /// making a call. /// @@ -2993,6 +3088,8 @@ class FunctionType : public Type { // * AST read and write // * Codegen class ExtInfo { + friend class FunctionType; + // Feel free to rearrange or add bits, but if you go over 11, // you'll need to adjust both the Bits field below and // Type::FunctionTypeBitfields. @@ -3011,15 +3108,13 @@ class FunctionType : public Type { RegParmOffset = 8 }; // Assumed to be the last field - uint16_t Bits; + uint16_t Bits = CC_C; ExtInfo(unsigned Bits) : Bits(static_cast(Bits)) {} - friend class FunctionType; - public: - // Constructor with no defaults. Use this when you know that you - // have all the elements (when reading an AST file for example). + // Constructor with no defaults. Use this when you know that you + // have all the elements (when reading an AST file for example). ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, bool producesResult, bool noCallerSavedRegs) { assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); @@ -3031,22 +3126,24 @@ class FunctionType : public Type { // Constructor with all defaults. Use when for example creating a // function known to use defaults. - ExtInfo() : Bits(CC_C) { } + ExtInfo() = default; // Constructor with just the calling convention, which is an important part // of the canonical type. - ExtInfo(CallingConv CC) : Bits(CC) { } + ExtInfo(CallingConv CC) : Bits(CC) {} bool getNoReturn() const { return Bits & NoReturnMask; } bool getProducesResult() const { return Bits & ProducesResultMask; } bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } + unsigned getRegParm() const { unsigned RegParm = Bits >> RegParmOffset; if (RegParm > 0) --RegParm; return RegParm; } + CallingConv getCC() const { return CallingConv(Bits & CallConvMask); } bool operator==(ExtInfo Other) const { @@ -3101,11 +3198,12 @@ protected: bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack, ExtInfo Info) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack), - ResultType(res) { + : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, + ContainsUnexpandedParameterPack), + ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; } + unsigned getTypeQuals() const { return FunctionTypeBits.TypeQuals; } public: @@ -3113,10 +3211,12 @@ public: bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } unsigned getRegParmType() const { return getExtInfo().getRegParm(); } + /// Determine whether this function type includes the GNU noreturn /// attribute. The C++11 [[noreturn]] attribute does not affect the function /// type. bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } + CallingConv getCallConv() const { return getExtInfo().getCC(); } ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } bool isConst() const { return getTypeQuals() & Qualifiers::Const; } @@ -3140,13 +3240,13 @@ public: /// Represents a K&R-style 'int foo()' function, which has /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { - FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) - : FunctionType(FunctionNoProto, Result, Canonical, - /*Dependent=*/false, /*InstantiationDependent=*/false, - Result->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false, Info) {} + friend class ASTContext; // ASTContext creates these. - friend class ASTContext; // ASTContext creates these. + FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) + : FunctionType(FunctionNoProto, Result, Canonical, + /*Dependent=*/false, /*InstantiationDependent=*/false, + Result->isVariablyModifiedType(), + /*ContainsUnexpandedParameterPack=*/false, Info) {} public: // No additional state past what FunctionType provides. @@ -3157,6 +3257,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getReturnType(), getExtInfo()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, ExtInfo Info) { Info.Profile(ID); @@ -3201,10 +3302,10 @@ public: HasPassObjSize = 0x20, IsNoEscape = 0x40, }; - unsigned char Data; + unsigned char Data = 0; public: - ExtParameterInfo() : Data(0) {} + ExtParameterInfo() = default; /// Return the ABI treatment of this parameter. ParameterABI getABI() const { @@ -3269,54 +3370,54 @@ public: }; struct ExceptionSpecInfo { - ExceptionSpecInfo() - : Type(EST_None), NoexceptExpr(nullptr), - SourceDecl(nullptr), SourceTemplate(nullptr) {} - - ExceptionSpecInfo(ExceptionSpecificationType EST) - : Type(EST), NoexceptExpr(nullptr), SourceDecl(nullptr), - SourceTemplate(nullptr) {} - /// The kind of exception specification this is. - ExceptionSpecificationType Type; + ExceptionSpecificationType Type = EST_None; + /// Explicitly-specified list of exception types. ArrayRef Exceptions; + /// Noexcept expression, if this is EST_ComputedNoexcept. - Expr *NoexceptExpr; + Expr *NoexceptExpr = nullptr; + /// The function whose exception specification this is, for /// EST_Unevaluated and EST_Uninstantiated. - FunctionDecl *SourceDecl; + FunctionDecl *SourceDecl = nullptr; + /// The function template whose exception specification this is instantiated /// from, for EST_Uninstantiated. - FunctionDecl *SourceTemplate; + FunctionDecl *SourceTemplate = nullptr; + + ExceptionSpecInfo() = default; + + ExceptionSpecInfo(ExceptionSpecificationType EST) : Type(EST) {} }; /// Extra information about a function prototype. struct ExtProtoInfo { + FunctionType::ExtInfo ExtInfo; + bool Variadic : 1; + bool HasTrailingReturn : 1; + unsigned char TypeQuals = 0; + RefQualifierKind RefQualifier = RQ_None; + ExceptionSpecInfo ExceptionSpec; + const ExtParameterInfo *ExtParameterInfos = nullptr; + ExtProtoInfo() - : Variadic(false), HasTrailingReturn(false), TypeQuals(0), - RefQualifier(RQ_None), ExtParameterInfos(nullptr) {} + : Variadic(false), HasTrailingReturn(false) {} ExtProtoInfo(CallingConv CC) - : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), - RefQualifier(RQ_None), ExtParameterInfos(nullptr) {} + : ExtInfo(CC), Variadic(false), HasTrailingReturn(false) {} ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) { ExtProtoInfo Result(*this); Result.ExceptionSpec = O; return Result; } - - FunctionType::ExtInfo ExtInfo; - bool Variadic : 1; - bool HasTrailingReturn : 1; - unsigned char TypeQuals; - RefQualifierKind RefQualifier; - ExceptionSpecInfo ExceptionSpec; - const ExtParameterInfo *ExtParameterInfos; }; private: + friend class ASTContext; // ASTContext creates these. + /// \brief Determine whether there are any argument types that /// contain an unexpanded parameter pack. static bool containsAnyUnexpandedParameterPack(const QualType *ArgArray, @@ -3368,8 +3469,6 @@ private: // for each of the parameters. This only appears if HasExtParameterInfos // is true. - friend class ASTContext; // ASTContext creates these. - const ExtParameterInfo *getExtParameterInfosBuffer() const { assert(hasExtParameterInfos()); @@ -3397,10 +3496,12 @@ private: public: unsigned getNumParams() const { return NumParams; } + QualType getParamType(unsigned i) const { assert(i < NumParams && "invalid parameter index"); return param_type_begin()[i]; } + ArrayRef getParamTypes() const { return llvm::makeArrayRef(param_type_begin(), param_type_end()); } @@ -3432,31 +3533,47 @@ public: ExceptionSpecificationType getExceptionSpecType() const { return static_cast(ExceptionSpecType); } + /// Return whether this function has any kind of exception spec. bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; } + /// Return whether this function has a dynamic (throw) exception spec. bool hasDynamicExceptionSpec() const { return isDynamicExceptionSpec(getExceptionSpecType()); } + /// Return whether this function has a noexcept exception spec. bool hasNoexceptExceptionSpec() const { return isNoexceptExceptionSpec(getExceptionSpecType()); } + /// Return whether this function has a dependent exception spec. bool hasDependentExceptionSpec() const; + /// Return whether this function has an instantiation-dependent exception /// spec. bool hasInstantiationDependentExceptionSpec() const; + /// Result type of getNoexceptSpec(). enum NoexceptResult { - NR_NoNoexcept, ///< There is no noexcept specifier. - NR_BadNoexcept, ///< The noexcept specifier has a bad expression. - NR_Dependent, ///< The noexcept specifier is dependent. - NR_Throw, ///< The noexcept specifier evaluates to false. - NR_Nothrow ///< The noexcept specifier evaluates to true. + /// There is no noexcept specifier. + NR_NoNoexcept, + + /// The noexcept specifier has a bad expression. + NR_BadNoexcept, + + /// The noexcept specifier is dependent. + NR_Dependent, + + /// The noexcept specifier evaluates to false. + NR_Throw, + + /// The noexcept specifier evaluates to true. + NR_Nothrow }; + /// Get the meaning of the noexcept spec on this function, if any. NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const; unsigned getNumExceptions() const { return NumExceptions; } @@ -3470,6 +3587,7 @@ public: // NoexceptExpr sits where the arguments end. return *reinterpret_cast(param_type_end()); } + /// \brief If this function type has an exception specification which hasn't /// been determined yet (either because it has not been evaluated or because /// it has not been instantiated), this is the function whose exception @@ -3480,6 +3598,7 @@ public: return nullptr; return reinterpret_cast(param_type_end())[0]; } + /// \brief If this function type has an uninstantiated exception /// specification, this is the function whose exception specification /// should be instantiated to find the exception specification for @@ -3489,9 +3608,11 @@ public: return nullptr; return reinterpret_cast(param_type_end())[1]; } + /// Determine whether this function type has a non-throwing exception /// specification. CanThrowResult canThrow(const ASTContext &Ctx) const; + /// Determine whether this function type has a non-throwing exception /// specification. If this depends on template arguments, returns /// \c ResultIfDependent. @@ -3514,34 +3635,37 @@ public: unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); } - /// Retrieve the ref-qualifier associated with this function type. RefQualifierKind getRefQualifier() const { return static_cast(FunctionTypeBits.RefQualifier); } - typedef const QualType *param_type_iterator; - typedef llvm::iterator_range param_type_range; + using param_type_iterator = const QualType *; + using param_type_range = llvm::iterator_range; param_type_range param_types() const { return param_type_range(param_type_begin(), param_type_end()); } + param_type_iterator param_type_begin() const { return reinterpret_cast(this+1); } + param_type_iterator param_type_end() const { return param_type_begin() + NumParams; } - typedef const QualType *exception_iterator; + using exception_iterator = const QualType *; ArrayRef exceptions() const { return llvm::makeArrayRef(exception_begin(), exception_end()); } + exception_iterator exception_begin() const { // exceptions begin where arguments end return param_type_end(); } + exception_iterator exception_end() const { if (getExceptionSpecType() != EST_Dynamic) return exception_begin(); @@ -3556,6 +3680,7 @@ public: return ArrayRef(getExtParameterInfosBuffer(), getNumParams()); } + /// Return a pointer to the beginning of the array of extra parameter /// information, if present, or else null if none of the parameters /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. @@ -3609,15 +3734,16 @@ public: /// /// Template instantiation turns these into the underlying type. class UnresolvedUsingType : public Type { + friend class ASTContext; // ASTContext creates these. + UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) - : Type(UnresolvedUsing, QualType(), true, true, false, - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast(D)) {} - friend class ASTContext; // ASTContext creates these. -public: + : Type(UnresolvedUsing, QualType(), true, true, false, + /*ContainsUnexpandedParameterPack=*/false), + Decl(const_cast(D)) {} +public: UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } bool isSugared() const { return false; } @@ -3630,27 +3756,29 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { return Profile(ID, Decl); } + static void Profile(llvm::FoldingSetNodeID &ID, UnresolvedUsingTypenameDecl *D) { ID.AddPointer(D); } }; - class TypedefType : public Type { TypedefNameDecl *Decl; + protected: + 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->isDependentType(), + can->isInstantiationDependentType(), + can->isVariablyModifiedType(), + /*ContainsUnexpandedParameterPack=*/false), + Decl(const_cast(D)) { assert(!isa(can) && "Invalid canonical type"); } - friend class ASTContext; // ASTContext creates these. -public: +public: TypedefNameDecl *getDecl() const { return Decl; } bool isSugared() const { return true; } @@ -3664,8 +3792,10 @@ class TypeOfExprType : public Type { Expr *TOExpr; protected: + friend class ASTContext; // ASTContext creates these. + TypeOfExprType(Expr *E, QualType can = QualType()); - friend class ASTContext; // ASTContext creates these. + public: Expr *getUnderlyingExpr() const { return TOExpr; } @@ -3690,7 +3820,7 @@ class DependentTypeOfExprType public: DependentTypeOfExprType(const ASTContext &Context, Expr *E) - : TypeOfExprType(E), Context(Context) { } + : TypeOfExprType(E), Context(Context) {} void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Context, getUnderlyingExpr()); @@ -3702,16 +3832,19 @@ public: /// Represents `typeof(type)`, a GCC extension. class TypeOfType : public Type { + friend class ASTContext; // ASTContext creates these. + QualType TOType; + TypeOfType(QualType T, QualType can) - : Type(TypeOf, can, T->isDependentType(), - T->isInstantiationDependentType(), - T->isVariablyModifiedType(), - T->containsUnexpandedParameterPack()), - TOType(T) { + : Type(TypeOf, can, T->isDependentType(), + T->isInstantiationDependentType(), + T->isVariablyModifiedType(), + T->containsUnexpandedParameterPack()), + TOType(T) { assert(!isa(can) && "Invalid canonical type"); } - friend class ASTContext; // ASTContext creates these. + public: QualType getUnderlyingType() const { return TOType; } @@ -3730,8 +3863,10 @@ class DecltypeType : public Type { QualType UnderlyingType; protected: + friend class ASTContext; // ASTContext creates these. + DecltypeType(Expr *E, QualType underlyingType, QualType can = QualType()); - friend class ASTContext; // ASTContext creates these. + public: Expr *getUnderlyingExpr() const { return E; } QualType getUnderlyingType() const { return UnderlyingType; } @@ -3775,14 +3910,18 @@ public: private: /// The untransformed type. QualType BaseType; + /// The transformed type if not dependent, otherwise the same as BaseType. QualType UnderlyingType; UTTKind UKind; + protected: + friend class ASTContext; + UnaryTransformType(QualType BaseTy, QualType UnderlyingTy, UTTKind UKind, QualType CanonicalTy); - friend class ASTContext; + public: bool isSugared() const { return !isDependentType(); } QualType desugar() const { return UnderlyingType; } @@ -3808,6 +3947,7 @@ class DependentUnaryTransformType : public UnaryTransformType, public: DependentUnaryTransformType(const ASTContext &C, QualType BaseType, UTTKind UKind); + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getBaseType(), getUTTKind()); } @@ -3820,11 +3960,11 @@ public: }; class TagType : public Type { + friend class ASTReader; + /// Stores the TagDecl associated with this type. The decl may point to any /// TagDecl that declares the entity. - TagDecl * decl; - - friend class ASTReader; + TagDecl *decl; protected: TagType(TypeClass TC, const TagDecl *D, QualType can); @@ -3844,13 +3984,14 @@ public: /// to detect TagType objects of structs/unions/classes. class RecordType : public TagType { protected: + friend class ASTContext; // ASTContext creates these. + explicit RecordType(const RecordDecl *D) - : TagType(Record, reinterpret_cast(D), QualType()) { } + : TagType(Record, reinterpret_cast(D), QualType()) {} explicit RecordType(TypeClass TC, RecordDecl *D) - : TagType(TC, reinterpret_cast(D), QualType()) { } - friend class ASTContext; // ASTContext creates these. -public: + : TagType(TC, reinterpret_cast(D), QualType()) {} +public: RecordDecl *getDecl() const { return reinterpret_cast(TagType::getDecl()); } @@ -3868,11 +4009,12 @@ public: /// A helper class that allows the use of isa/cast/dyncast /// to detect TagType objects of enums. class EnumType : public TagType { + friend class ASTContext; // ASTContext creates these. + explicit EnumType(const EnumDecl *D) - : TagType(Enum, reinterpret_cast(D), QualType()) { } - friend class ASTContext; // ASTContext creates these. -public: + : TagType(Enum, reinterpret_cast(D), QualType()) {} +public: EnumDecl *getDecl() const { return reinterpret_cast(TagType::getDecl()); } @@ -3947,11 +4089,11 @@ public: }; private: + friend class ASTContext; // ASTContext creates these + QualType ModifiedType; QualType EquivalentType; - friend class ASTContext; // creates these - AttributedType(QualType canon, Kind attrKind, QualType modified, QualType equivalent) : Type(Attributed, canon, equivalent->isDependentType(), @@ -4040,6 +4182,8 @@ public: }; class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these + // Helper data collector for canonical types. struct CanonicalTTPTInfo { unsigned Depth : 15; @@ -4050,31 +4194,30 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { union { // Info for the canonical type. CanonicalTTPTInfo CanTTPTInfo; + // Info for the non-canonical type. TemplateTypeParmDecl *TTPDecl; }; /// Build a non-canonical type. TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) - : Type(TemplateTypeParm, Canon, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - Canon->containsUnexpandedParameterPack()), - TTPDecl(TTPDecl) { } + : Type(TemplateTypeParm, Canon, /*Dependent=*/true, + /*InstantiationDependent=*/true, + /*VariablyModified=*/false, + Canon->containsUnexpandedParameterPack()), + 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) { + : Type(TemplateTypeParm, QualType(this, 0), + /*Dependent=*/true, + /*InstantiationDependent=*/true, + /*VariablyModified=*/false, PP) { CanTTPTInfo.Depth = D; CanTTPTInfo.Index = I; CanTTPTInfo.ParameterPack = PP; } - friend class ASTContext; // ASTContext creates these - const CanonicalTTPTInfo& getCanTTPTInfo() const { QualType Can = getCanonicalTypeInternal(); return Can->castAs()->CanTTPTInfo; @@ -4120,17 +4263,17 @@ public: /// type was originally written as a template type parameter; /// therefore they are never canonical. class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + // The original type parameter. const TemplateTypeParmType *Replaced; SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) - : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), - Canon->isInstantiationDependentType(), - Canon->isVariablyModifiedType(), - Canon->containsUnexpandedParameterPack()), - Replaced(Param) { } - - friend class ASTContext; + : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), + Canon->isInstantiationDependentType(), + Canon->isVariablyModifiedType(), + Canon->containsUnexpandedParameterPack()), + Replaced(Param) {} public: /// Gets the template parameter that was substituted for. @@ -4150,6 +4293,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getReplacedParameter(), getReplacementType()); } + static void Profile(llvm::FoldingSetNodeID &ID, const TemplateTypeParmType *Replaced, QualType Replacement) { @@ -4175,6 +4319,8 @@ public: /// arguments), this type will be replaced with the \c SubstTemplateTypeParmType /// at the current pack substitution index. class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + /// \brief The original type parameter. const TemplateTypeParmType *Replaced; @@ -4189,8 +4335,6 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { QualType Canon, const TemplateArgument &ArgPack); - friend class ASTContext; - public: IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } @@ -4264,6 +4408,8 @@ public: /// \brief Represents a C++11 auto or C++14 decltype(auto) type. class AutoType : public DeducedType, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these + AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, bool IsDeducedAsDependent) : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, @@ -4271,12 +4417,11 @@ class AutoType : public DeducedType, public llvm::FoldingSetNode { AutoTypeBits.Keyword = (unsigned)Keyword; } - friend class ASTContext; // ASTContext creates these - public: bool isDecltypeAuto() const { return getKeyword() == AutoTypeKeyword::DecltypeAuto; } + AutoTypeKeyword getKeyword() const { return (AutoTypeKeyword)AutoTypeBits.Keyword; } @@ -4300,6 +4445,8 @@ public: /// \brief Represents a C++17 deduced template specialization type. class DeducedTemplateSpecializationType : public DeducedType, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these + /// The name of the template whose arguments will be deduced. TemplateName Template; @@ -4312,8 +4459,6 @@ class DeducedTemplateSpecializationType : public DeducedType, Template.containsUnexpandedParameterPack()), Template(Template) {} - friend class ASTContext; // ASTContext creates these - public: /// Retrieve the name of the template that we are deducing. TemplateName getTemplateName() const { return Template;} @@ -4357,6 +4502,8 @@ public: class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these + /// The name of the template being specialized. This is /// either a TemplateName::Template (in which case it is a /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a @@ -4378,8 +4525,6 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType QualType Canon, QualType Aliased); - friend class ASTContext; // ASTContext creates these - public: /// Determine whether any of the given template arguments are dependent. static bool anyDependentTemplateArguments(ArrayRef Args, @@ -4433,7 +4578,7 @@ public: return *reinterpret_cast(end()); } - typedef const TemplateArgument * iterator; + using iterator = const TemplateArgument *; iterator begin() const { return getArgs(); } iterator end() const; // defined inline in TemplateBase.h @@ -4460,6 +4605,7 @@ public: bool isSugared() const { return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); } + QualType desugar() const { return getCanonicalTypeInternal(); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { @@ -4495,6 +4641,12 @@ public: /// will canonicalize to the injected class name (when appropriate /// according to the rules of the language). class InjectedClassNameType : public Type { + friend class ASTContext; // ASTContext creates these. + friend class ASTNodeImporter; + friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not + // currently suitable for AST reading, too much + // interdependencies. + CXXRecordDecl *Decl; /// The template specialization which this type represents. @@ -4508,18 +4660,12 @@ class InjectedClassNameType : public Type { /// and always dependent. QualType InjectedType; - friend class ASTContext; // ASTContext creates these. - friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not - // currently suitable for AST reading, too much - // interdependencies. - friend class ASTNodeImporter; - InjectedClassNameType(CXXRecordDecl *D, QualType TST) - : Type(InjectedClassName, QualType(), /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - /*ContainsUnexpandedParameterPack=*/false), - Decl(D), InjectedType(TST) { + : Type(InjectedClassName, QualType(), /*Dependent=*/true, + /*InstantiationDependent=*/true, + /*VariablyModified=*/false, + /*ContainsUnexpandedParameterPack=*/false), + Decl(D), InjectedType(TST) { assert(isa(TST)); assert(!TST.hasQualifiers()); assert(TST->isDependentType()); @@ -4527,9 +4673,11 @@ class InjectedClassNameType : public Type { public: QualType getInjectedSpecializationType() const { return InjectedType; } + const TemplateSpecializationType *getInjectedTST() const { return cast(InjectedType.getTypePtr()); } + TemplateName getTemplateName() const { return getInjectedTST()->getTemplateName(); } @@ -4548,12 +4696,16 @@ public: enum TagTypeKind { /// \brief The "struct" keyword. TTK_Struct, + /// \brief The "__interface" keyword. TTK_Interface, + /// \brief The "union" keyword. TTK_Union, + /// \brief The "class" keyword. TTK_Class, + /// \brief The "enum" keyword. TTK_Enum }; @@ -4563,17 +4715,23 @@ enum TagTypeKind { enum ElaboratedTypeKeyword { /// \brief The "struct" keyword introduces the elaborated-type-specifier. ETK_Struct, + /// \brief The "__interface" keyword introduces the elaborated-type-specifier. ETK_Interface, + /// \brief The "union" keyword introduces the elaborated-type-specifier. ETK_Union, + /// \brief The "class" keyword introduces the elaborated-type-specifier. ETK_Class, + /// \brief The "enum" keyword introduces the elaborated-type-specifier. ETK_Enum, + /// \brief The "typename" keyword precedes the qualified type name, e.g., /// \c typename T::type. ETK_Typename, + /// \brief No keyword precedes the qualified type name. ETK_None }; @@ -4588,8 +4746,8 @@ protected: QualType Canonical, bool Dependent, bool InstantiationDependent, bool VariablyModified, bool ContainsUnexpandedParameterPack) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack) { + : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, + ContainsUnexpandedParameterPack) { TypeWithKeywordBits.Keyword = Keyword; } @@ -4634,6 +4792,7 @@ public: /// The type itself is always "sugar", used to express what was written /// in the source code but containing no additional semantic information. class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these /// The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; @@ -4654,8 +4813,6 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { "and name qualifier both null."); } - friend class ASTContext; // ASTContext creates these - public: ~ElaboratedType(); @@ -4700,6 +4857,7 @@ public: /// mode, this type is used with non-dependent names to delay name lookup until /// instantiation. class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these /// \brief The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; @@ -4709,13 +4867,11 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) - : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - NNS->containsUnexpandedParameterPack()), - NNS(NNS), Name(Name) {} - - friend class ASTContext; // ASTContext creates these + : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, + /*InstantiationDependent=*/true, + /*VariablyModified=*/false, + NNS->containsUnexpandedParameterPack()), + NNS(NNS), Name(Name) {} public: /// Retrieve the qualification on this type. @@ -4755,6 +4911,7 @@ public: class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType : public TypeWithKeyword, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these /// The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; @@ -4766,20 +4923,19 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType /// specialization. unsigned NumArgs; - const TemplateArgument *getArgBuffer() const { - return reinterpret_cast(this+1); - } - TemplateArgument *getArgBuffer() { - return reinterpret_cast(this+1); - } - DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, ArrayRef Args, QualType Canon); - friend class ASTContext; // ASTContext creates these + const TemplateArgument *getArgBuffer() const { + return reinterpret_cast(this+1); + } + + TemplateArgument *getArgBuffer() { + return reinterpret_cast(this+1); + } public: NestedNameSpecifier *getQualifier() const { return NNS; } @@ -4799,7 +4955,8 @@ public: return {getArgs(), NumArgs}; } - typedef const TemplateArgument * iterator; + using iterator = const TemplateArgument *; + iterator begin() const { return getArgs(); } iterator end() const; // inline in TemplateBase.h @@ -4845,6 +5002,8 @@ public: /// Here, the pack expansion \c Types&... is represented via a /// PackExpansionType whose pattern is Types&. class PackExpansionType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these + /// \brief The pattern of the pack expansion. QualType Pattern; @@ -4858,14 +5017,12 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { PackExpansionType(QualType Pattern, QualType Canon, Optional NumExpansions) - : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), - /*InstantiationDependent=*/true, - /*VariablyModified=*/Pattern->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), - Pattern(Pattern), - NumExpansions(NumExpansions? *NumExpansions + 1: 0) { } - - friend class ASTContext; // ASTContext creates these + : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), + /*InstantiationDependent=*/true, + /*VariablyModified=*/Pattern->isVariablyModifiedType(), + /*ContainsUnexpandedParameterPack=*/false), + Pattern(Pattern), + NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {} public: /// \brief Retrieve the pattern of this pack expansion, which is the @@ -4907,7 +5064,8 @@ public: template class ObjCProtocolQualifiers { protected: - ObjCProtocolQualifiers() {} + ObjCProtocolQualifiers() = default; + ObjCProtocolDecl * const *getProtocolStorage() const { return const_cast(this)->getProtocolStorage(); } @@ -4915,9 +5073,11 @@ protected: ObjCProtocolDecl **getProtocolStorage() { return static_cast(this)->getProtocolStorageImpl(); } + void setNumProtocols(unsigned N) { static_cast(this)->setNumProtocolsImpl(N); } + void initialize(ArrayRef protocols) { setNumProtocols(protocols.size()); assert(getNumProtocols() == protocols.size() && @@ -4928,8 +5088,8 @@ protected: } public: - typedef ObjCProtocolDecl * const *qual_iterator; - typedef llvm::iterator_range qual_range; + using qual_iterator = ObjCProtocolDecl * const *; + using qual_range = llvm::iterator_range; qual_range quals() const { return qual_range(qual_begin(), qual_end()); } qual_iterator qual_begin() const { return getProtocolStorage(); } @@ -4967,21 +5127,26 @@ class ObjCTypeParamType : public Type, unsigned NumProtocols : 6; ObjCTypeParamDecl *OTPDecl; + /// The protocols are stored after the ObjCTypeParamType node. In the /// canonical type, the list of protocols are sorted alphabetically /// and uniqued. ObjCProtocolDecl **getProtocolStorageImpl(); + /// Return the number of qualifying protocols in this interface type, /// or 0 if there are none. unsigned getNumProtocolsImpl() const { return NumProtocols; } + void setNumProtocolsImpl(unsigned N) { NumProtocols = N; } + ObjCTypeParamType(const ObjCTypeParamDecl *D, QualType can, ArrayRef protocols); + public: bool isSugared() const { return true; } QualType desugar() const { return getCanonicalTypeInternal(); } @@ -5029,6 +5194,7 @@ public: class ObjCObjectType : public Type, public ObjCProtocolQualifiers { friend class ObjCProtocolQualifiers; + // ObjCObjectType.NumTypeArgs - the number of type arguments stored // after the ObjCObjectPointerType node. // ObjCObjectType.NumProtocols - the number of protocols stored @@ -5064,15 +5230,16 @@ class ObjCObjectType : public Type, } protected: + enum Nonce_ObjCInterface { Nonce_ObjCInterface }; + ObjCObjectType(QualType Canonical, QualType Base, ArrayRef typeArgs, ArrayRef protocols, bool isKindOf); - enum Nonce_ObjCInterface { Nonce_ObjCInterface }; ObjCObjectType(enum Nonce_ObjCInterface) : Type(ObjCInterface, QualType(), false, false, false, false), - BaseType(QualType(this_(), 0)) { + BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; ObjCObjectTypeBits.NumTypeArgs = 0; ObjCObjectTypeBits.IsKindOf = 0; @@ -5092,9 +5259,11 @@ public: bool isObjCId() const { return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCId); } + bool isObjCClass() const { return getBaseType()->isSpecificBuiltinType(BuiltinType::ObjCClass); } + bool isObjCUnqualifiedId() const { return qual_empty() && isObjCId(); } bool isObjCUnqualifiedClass() const { return qual_empty() && isObjCClass(); } bool isObjCUnqualifiedIdOrClass() const { @@ -5185,7 +5354,7 @@ class ObjCObjectTypeImpl : public ObjCObjectType, public llvm::FoldingSetNode { ArrayRef typeArgs, ArrayRef protocols, bool isKindOf) - : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {} + : ObjCObjectType(Canonical, Base, typeArgs, protocols, isKindOf) {} public: void Profile(llvm::FoldingSetNodeID &ID); @@ -5223,14 +5392,15 @@ inline ObjCProtocolDecl **ObjCTypeParamType::getProtocolStorageImpl() { /// - It is its own base type. That is, if T is an ObjCInterfaceType*, /// T->getBaseType() == QualType(T, 0). class ObjCInterfaceType : public ObjCObjectType { + friend class ASTContext; // ASTContext creates these. + friend class ASTReader; + friend class ObjCInterfaceDecl; + mutable ObjCInterfaceDecl *Decl; ObjCInterfaceType(const ObjCInterfaceDecl *D) - : ObjCObjectType(Nonce_ObjCInterface), - Decl(const_cast(D)) {} - friend class ASTContext; // ASTContext creates these. - friend class ASTReader; - friend class ObjCInterfaceDecl; + : ObjCObjectType(Nonce_ObjCInterface), + Decl(const_cast(D)) {} public: /// Get the declaration of this interface. @@ -5278,16 +5448,17 @@ inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { /// Pointers to pointers to Objective C objects are still PointerTypes; /// only the first level of pointer gets it own type implementation. class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, - Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), - PointeeType(Pointee) {} - friend class ASTContext; // ASTContext creates these. + : Type(ObjCObjectPointer, Canonical, + Pointee->isDependentType(), + Pointee->isInstantiationDependentType(), + Pointee->isVariablyModifiedType(), + Pointee->containsUnexpandedParameterPack()), + PointeeType(Pointee) {} public: /// Gets the type pointed to by this ObjC pointer. @@ -5396,16 +5567,19 @@ public: /// An iterator over the qualifiers on the object type. Provided /// for convenience. This will always iterate over the full set of /// protocols on a type, not just those provided directly. - typedef ObjCObjectType::qual_iterator qual_iterator; - typedef llvm::iterator_range qual_range; + using qual_iterator = ObjCObjectType::qual_iterator; + using qual_range = llvm::iterator_range; qual_range quals() const { return qual_range(qual_begin(), qual_end()); } + qual_iterator qual_begin() const { return getObjectType()->qual_begin(); } + qual_iterator qual_end() const { return getObjectType()->qual_end(); } + bool qual_empty() const { return getObjectType()->qual_empty(); } /// Return the number of qualifying protocols on the object type. @@ -5437,26 +5611,29 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getPointeeType()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { ID.AddPointer(T.getAsOpaquePtr()); } + static bool classof(const Type *T) { return T->getTypeClass() == ObjCObjectPointer; } }; class AtomicType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType ValueType; AtomicType(QualType ValTy, QualType Canonical) - : Type(Atomic, Canonical, ValTy->isDependentType(), - ValTy->isInstantiationDependentType(), - ValTy->isVariablyModifiedType(), - ValTy->containsUnexpandedParameterPack()), - ValueType(ValTy) {} - friend class ASTContext; // ASTContext creates these. + : Type(Atomic, Canonical, ValTy->isDependentType(), + ValTy->isInstantiationDependentType(), + ValTy->isVariablyModifiedType(), + ValTy->containsUnexpandedParameterPack()), + ValueType(ValTy) {} - public: +public: /// Gets the type contained by this atomic type, i.e. /// the type returned by performing an atomic load of this atomic type. QualType getValueType() const { return ValueType; } @@ -5467,9 +5644,11 @@ class AtomicType : public Type, public llvm::FoldingSetNode { void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getValueType()); } + static void Profile(llvm::FoldingSetNodeID &ID, QualType T) { ID.AddPointer(T.getAsOpaquePtr()); } + static bool classof(const Type *T) { return T->getTypeClass() == Atomic; } @@ -5477,16 +5656,17 @@ class AtomicType : public Type, public llvm::FoldingSetNode { /// PipeType - OpenCL20. class PipeType : public Type, public llvm::FoldingSetNode { + friend class ASTContext; // ASTContext creates these. + QualType ElementType; bool isRead; - PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) : - Type(Pipe, CanonicalPtr, elemType->isDependentType(), - elemType->isInstantiationDependentType(), - elemType->isVariablyModifiedType(), - elemType->containsUnexpandedParameterPack()), - ElementType(elemType), isRead(isRead) {} - friend class ASTContext; // ASTContext creates these. + PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) + : Type(Pipe, CanonicalPtr, elemType->isDependentType(), + elemType->isInstantiationDependentType(), + elemType->isVariablyModifiedType(), + elemType->containsUnexpandedParameterPack()), + ElementType(elemType), isRead(isRead) {} public: QualType getElementType() const { return ElementType; } @@ -5536,7 +5716,6 @@ public: QualType apply(const ASTContext &Context, const Type* T) const; }; - // Inline function definitions. inline SplitQualType SplitQualType::getSingleStepDesugaredType() const { @@ -5769,91 +5948,117 @@ inline bool Type::isCompoundType() const { inline bool Type::isFunctionType() const { return isa(CanonicalType); } + inline bool Type::isPointerType() const { return isa(CanonicalType); } + inline bool Type::isAnyPointerType() const { return isPointerType() || isObjCObjectPointerType(); } + inline bool Type::isBlockPointerType() const { return isa(CanonicalType); } + inline bool Type::isReferenceType() const { return isa(CanonicalType); } + inline bool Type::isLValueReferenceType() const { return isa(CanonicalType); } + inline bool Type::isRValueReferenceType() const { return isa(CanonicalType); } + inline bool Type::isFunctionPointerType() const { if (const PointerType *T = getAs()) return T->getPointeeType()->isFunctionType(); else return false; } + inline bool Type::isMemberPointerType() const { return isa(CanonicalType); } + inline bool Type::isMemberFunctionPointerType() const { if (const MemberPointerType* T = getAs()) return T->isMemberFunctionPointer(); else return false; } + inline bool Type::isMemberDataPointerType() const { if (const MemberPointerType* T = getAs()) return T->isMemberDataPointer(); else return false; } + inline bool Type::isArrayType() const { return isa(CanonicalType); } + inline bool Type::isConstantArrayType() const { return isa(CanonicalType); } + inline bool Type::isIncompleteArrayType() const { return isa(CanonicalType); } + inline bool Type::isVariableArrayType() const { return isa(CanonicalType); } + inline bool Type::isDependentSizedArrayType() const { return isa(CanonicalType); } + inline bool Type::isBuiltinType() const { return isa(CanonicalType); } + inline bool Type::isRecordType() const { return isa(CanonicalType); } + inline bool Type::isEnumeralType() const { return isa(CanonicalType); } + inline bool Type::isAnyComplexType() const { return isa(CanonicalType); } + inline bool Type::isVectorType() const { return isa(CanonicalType); } + inline bool Type::isExtVectorType() const { return isa(CanonicalType); } + inline bool Type::isDependentAddressSpaceType() const { return isa(CanonicalType); } + inline bool Type::isObjCObjectPointerType() const { return isa(CanonicalType); } + inline bool Type::isObjCObjectType() const { return isa(CanonicalType); } + inline bool Type::isObjCObjectOrInterfaceType() const { return isa(CanonicalType) || isa(CanonicalType); } + inline bool Type::isAtomicType() const { return isa(CanonicalType); } @@ -5863,26 +6068,31 @@ inline bool Type::isObjCQualifiedIdType() const { return OPT->isObjCQualifiedIdType(); return false; } + inline bool Type::isObjCQualifiedClassType() const { if (const ObjCObjectPointerType *OPT = getAs()) return OPT->isObjCQualifiedClassType(); return false; } + inline bool Type::isObjCIdType() const { if (const ObjCObjectPointerType *OPT = getAs()) return OPT->isObjCIdType(); return false; } + inline bool Type::isObjCClassType() const { if (const ObjCObjectPointerType *OPT = getAs()) return OPT->isObjCClassType(); return false; } + inline bool Type::isObjCSelType() const { if (const PointerType *OPT = getAs()) return OPT->getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCSel); return false; } + inline bool Type::isObjCBuiltinType() const { return isObjCIdType() || isObjCClassType() || isObjCSelType(); } @@ -5917,7 +6127,7 @@ inline bool Type::isImageType() const { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() || return #include "clang/Basic/OpenCLImageTypes.def" - 0; // end boolean or operation + false; // end boolean or operation } inline bool Type::isPipeType() const { @@ -6196,7 +6406,6 @@ QualType DecayedType::getPointeeType() const { return cast(Decayed)->getPointeeType(); } +} // namespace clang -} // end namespace clang - -#endif +#endif // LLVM_CLANG_AST_TYPE_H diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index d0707a4..1afcbf0 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1,4 +1,4 @@ -//===--- Type.cpp - Type representation and manipulation ------------------===// +//===- Type.cpp - Type representation and manipulation --------------------===// // // The LLVM Compiler Infrastructure // @@ -16,17 +16,40 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" #include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" #include "clang/AST/TypeVisitor.h" +#include "clang/Basic/AddressSpaces.h" +#include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/Linkage.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/Visibility.h" +#include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include +#include +#include +#include + using namespace clang; bool Qualifiers::isStrictSupersetOf(Qualifiers Other) const { @@ -126,12 +149,10 @@ DependentSizedArrayType::DependentSizedArrayType(const ASTContext &Context, Expr *e, ArraySizeModifier sm, unsigned tq, SourceRange brackets) - : ArrayType(DependentSizedArray, et, can, sm, tq, + : ArrayType(DependentSizedArray, et, can, sm, tq, (et->containsUnexpandedParameterPack() || (e && e->containsUnexpandedParameterPack()))), - Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) -{ -} + Context(Context), SizeExpr((Stmt*) e), Brackets(brackets) {} void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, @@ -153,13 +174,11 @@ DependentSizedExtVectorType::DependentSizedExtVectorType(const SourceLocation loc) : Type(DependentSizedExtVector, can, /*Dependent=*/true, /*InstantiationDependent=*/true, - ElementType->isVariablyModifiedType(), + ElementType->isVariablyModifiedType(), (ElementType->containsUnexpandedParameterPack() || (SizeExpr && SizeExpr->containsUnexpandedParameterPack()))), Context(Context), SizeExpr(SizeExpr), ElementType(ElementType), - loc(loc) -{ -} + loc(loc) {} void DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, @@ -195,12 +214,11 @@ VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, 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->isDependentType(), + vecType->isInstantiationDependentType(), + vecType->isVariablyModifiedType(), + vecType->containsUnexpandedParameterPack()), + ElementType(vecType) { VectorTypeBits.VecKind = vecKind; VectorTypeBits.NumElements = nElements; } @@ -375,11 +393,13 @@ const Type *Type::getUnqualifiedDesugaredType() const { } } } + bool Type::isClassType() const { if (const RecordType *RT = getAs()) return RT->getDecl()->isClass(); return false; } + bool Type::isStructureType() const { if (const RecordType *RT = getAs()) return RT->getDecl()->isStruct(); @@ -402,6 +422,7 @@ bool Type::isStructureOrClassType() const { } return false; } + bool Type::isVoidPointerType() const { if (const PointerType *PT = getAs()) return PT->getPointeeType()->isVoidType(); @@ -555,12 +576,11 @@ bool Type::isObjCInertUnsafeUnretainedType() const { 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->isDependentType(), + can->isInstantiationDependentType(), + can->isVariablyModifiedType(), + /*ContainsUnexpandedParameterPack=*/false), + OTPDecl(const_cast(D)) { initialize(protocols); } @@ -568,12 +588,11 @@ ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, ArrayRef typeArgs, ArrayRef protocols, bool isKindOf) - : Type(ObjCObject, Canonical, Base->isDependentType(), - Base->isInstantiationDependentType(), - Base->isVariablyModifiedType(), - Base->containsUnexpandedParameterPack()), - BaseType(Base) -{ + : Type(ObjCObject, Canonical, Base->isDependentType(), + Base->isInstantiationDependentType(), + Base->isVariablyModifiedType(), + Base->containsUnexpandedParameterPack()), + BaseType(Base) { ObjCObjectTypeBits.IsKindOf = isKindOf; ObjCObjectTypeBits.NumTypeArgs = typeArgs.size(); @@ -624,13 +643,13 @@ ArrayRef ObjCObjectType::getTypeArgs() const { if (auto objcObject = getBaseType()->getAs()) { // Terminate when we reach an interface type. if (isa(objcObject)) - return { }; + return {}; return objcObject->getTypeArgs(); } // No type arguments. - return { }; + return {}; } bool ObjCObjectType::isKindOfType() const { @@ -666,7 +685,7 @@ QualType ObjCObjectType::stripObjCKindOfTypeAndQuals( return ctx.getObjCObjectType(ctx.getQualifiedType(baseType, splitBaseType.Quals), getTypeArgsAsWritten(), - /*protocols=*/{ }, + /*protocols=*/{}, /*isKindOf=*/false); } @@ -679,10 +698,10 @@ const ObjCObjectPointerType *ObjCObjectPointerType::stripObjCKindOfTypeAndQuals( return ctx.getObjCObjectPointerType(obj)->castAs(); } -namespace { - template -QualType simpleTransform(ASTContext &ctx, QualType type, F &&f); +static QualType simpleTransform(ASTContext &ctx, QualType type, F &&f); + +namespace { /// Visitor used by simpleTransform() to perform the transformation. template @@ -696,7 +715,8 @@ struct SimpleTransformVisitor } public: - SimpleTransformVisitor(ASTContext &ctx, F &&f) : Ctx(ctx), TheFunc(std::move(f)) { } + SimpleTransformVisitor(ASTContext &ctx, F &&f) + : Ctx(ctx), TheFunc(std::move(f)) {} // None of the clients of this transformation can occur where // there are dependent types, so skip dependent types. @@ -1065,10 +1085,12 @@ public: #undef TRIVIAL_TYPE_CLASS }; +} // namespace + /// Perform a simple type transformation that does not change the /// semantics of the type. template -QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) { +static QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) { // Transform the type. If it changed, return the transformed result. QualType transformed = f(type); if (transformed.getAsOpaquePtr() != type.getAsOpaquePtr()) @@ -1088,8 +1110,6 @@ QualType simpleTransform(ASTContext &ctx, QualType type, F &&f) { return ctx.getQualifiedType(result, splitType.Quals); } -} // end anonymous namespace - /// Substitute the given type arguments for Objective-C type /// parameters within the given type, recursively. QualType QualType::substObjCTypeArgs( @@ -1254,7 +1274,7 @@ QualType QualType::substObjCTypeArgs( if (typeArgs.empty() && context != ObjCSubstitutionContext::Superclass) { return ctx.getObjCObjectType( - objcObjectType->getBaseType(), { }, + objcObjectType->getBaseType(), {}, protocols, objcObjectType->isKindOfTypeAsWritten()); } @@ -1364,7 +1384,7 @@ Optional> Type::getObjCSubstitutions( objectType = objectPointerType->getObjectType(); } else if (getAs()) { ASTContext &ctx = dc->getParentASTContext(); - objectType = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, { }, { }) + objectType = ctx.getObjCObjectType(ctx.ObjCBuiltinIdTy, {}, {}) ->castAs(); } else { objectType = getAs(); @@ -1543,6 +1563,7 @@ const ObjCObjectType *Type::getAsObjCInterfaceType() const { } return nullptr; } + const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const { if (const ObjCObjectPointerType *OPT = getAs()) { if (OPT->getInterfaceType()) @@ -1580,14 +1601,17 @@ TagDecl *Type::getAsTagDecl() const { } namespace { + class GetContainedDeducedTypeVisitor : public TypeVisitor { bool Syntactic; + public: GetContainedDeducedTypeVisitor(bool Syntactic = false) : Syntactic(Syntactic) {} using TypeVisitor::Visit; + Type *Visit(QualType T) { if (T.isNull()) return nullptr; @@ -1600,50 +1624,64 @@ namespace { } // Only these types can contain the desired 'auto' type. + Type *VisitElaboratedType(const ElaboratedType *T) { return Visit(T->getNamedType()); } + Type *VisitPointerType(const PointerType *T) { return Visit(T->getPointeeType()); } + Type *VisitBlockPointerType(const BlockPointerType *T) { return Visit(T->getPointeeType()); } + Type *VisitReferenceType(const ReferenceType *T) { return Visit(T->getPointeeTypeAsWritten()); } + Type *VisitMemberPointerType(const MemberPointerType *T) { return Visit(T->getPointeeType()); } + Type *VisitArrayType(const ArrayType *T) { return Visit(T->getElementType()); } + Type *VisitDependentSizedExtVectorType( const DependentSizedExtVectorType *T) { return Visit(T->getElementType()); } + Type *VisitVectorType(const VectorType *T) { return Visit(T->getElementType()); } + Type *VisitFunctionProtoType(const FunctionProtoType *T) { if (Syntactic && T->hasTrailingReturn()) return const_cast(T); return VisitFunctionType(T); } + Type *VisitFunctionType(const FunctionType *T) { return Visit(T->getReturnType()); } + Type *VisitParenType(const ParenType *T) { return Visit(T->getInnerType()); } + Type *VisitAttributedType(const AttributedType *T) { return Visit(T->getModifiedType()); } + Type *VisitAdjustedType(const AdjustedType *T) { return Visit(T->getOriginalType()); } }; -} + +} // namespace DeducedType *Type::getContainedDeducedType() const { return cast_or_null( @@ -1694,7 +1732,6 @@ bool Type::isIntegralType(const ASTContext &Ctx) const { return false; } - bool Type::isIntegralOrUnscopedEnumerationType() const { if (const BuiltinType *BT = dyn_cast(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && @@ -1710,8 +1747,6 @@ bool Type::isIntegralOrUnscopedEnumerationType() const { return false; } - - bool Type::isCharType() const { if (const BuiltinType *BT = dyn_cast(CanonicalType)) return BT->getKind() == BuiltinType::Char_U || @@ -2036,7 +2071,7 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const { // We return false for that case. Except for incomplete arrays of PODs, which // are PODs according to the standard. if (isNull()) - return 0; + return false; if ((*this)->isIncompleteArrayType()) return Context.getBaseElementType(*this).isCXX98PODType(Context); @@ -2084,7 +2119,7 @@ bool QualType::isTrivialType(const ASTContext &Context) const { // We return false for that case. Except for incomplete arrays of PODs, which // are PODs according to the standard. if (isNull()) - return 0; + return false; if ((*this)->isArrayType()) return Context.getBaseElementType(*this).isTrivialType(Context); @@ -2230,7 +2265,6 @@ bool QualType::structHasUniqueObjectRepresentations( // is the sum of the bases. if (RD->field_empty()) return StructSize == BaseSize; - ; CharUnits CurOffset = Context.toCharUnitsFromBits(Context.getFieldOffset(*RD->field_begin())); @@ -3003,7 +3037,6 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, const QualType *ArgTys, unsigned NumParams, const ExtProtoInfo &epi, const ASTContext &Context, bool Canonical) { - // We have to be careful not to get ambiguous profile encodings. // Note that valid type pointers are never ambiguous with anything else. // @@ -3065,12 +3098,11 @@ QualType TypedefType::desugar() const { } TypeOfExprType::TypeOfExprType(Expr *E, QualType can) - : Type(TypeOfExpr, can, E->isTypeDependent(), - E->isInstantiationDependent(), - E->getType()->isVariablyModifiedType(), - E->containsUnexpandedParameterPack()), - TOExpr(E) { -} + : Type(TypeOfExpr, can, E->isTypeDependent(), + E->isInstantiationDependent(), + E->getType()->isVariablyModifiedType(), + E->containsUnexpandedParameterPack()), + TOExpr(E) {} bool TypeOfExprType::isSugared() const { return !TOExpr->isTypeDependent(); @@ -3092,13 +3124,11 @@ 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()), - E(E), - UnderlyingType(underlyingType) { -} + : Type(Decltype, can, E->isInstantiationDependent(), + E->isInstantiationDependent(), + E->getType()->isVariablyModifiedType(), + E->containsUnexpandedParameterPack()), + E(E), UnderlyingType(underlyingType) {} bool DecltypeType::isSugared() const { return !E->isInstantiationDependent(); } @@ -3110,7 +3140,7 @@ QualType DecltypeType::desugar() const { } DependentDecltypeType::DependentDecltypeType(const ASTContext &Context, Expr *E) - : DecltypeType(E, Context.DependentTy), Context(Context) { } + : DecltypeType(E, Context.DependentTy), Context(Context) {} void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, Expr *E) { @@ -3121,26 +3151,23 @@ UnaryTransformType::UnaryTransformType(QualType BaseType, QualType UnderlyingType, UTTKind UKind, QualType CanonicalType) - : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(), - BaseType->isInstantiationDependentType(), - BaseType->isVariablyModifiedType(), - BaseType->containsUnexpandedParameterPack()) - , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) -{} + : Type(UnaryTransform, CanonicalType, BaseType->isDependentType(), + BaseType->isInstantiationDependentType(), + BaseType->isVariablyModifiedType(), + BaseType->containsUnexpandedParameterPack()), + BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {} DependentUnaryTransformType::DependentUnaryTransformType(const ASTContext &C, QualType BaseType, UTTKind UKind) - : UnaryTransformType(BaseType, C.DependentTy, UKind, QualType()) -{} - + : 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(), + /*InstantiationDependent=*/D->isDependentType(), + /*VariablyModified=*/false, + /*ContainsUnexpandedParameterPack=*/false), + decl(const_cast(D)) {} static TagDecl *getInterestingTagDecl(TagDecl *decl) { for (auto I : decl->redecls()) { @@ -3285,11 +3312,9 @@ SubstTemplateTypeParmPackType:: SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, QualType Canon, const TemplateArgument &ArgPack) - : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), - Replaced(Param), - Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) -{ -} + : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), + Replaced(Param), + Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {} TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments)); @@ -3456,11 +3481,13 @@ public: L.hasLocalOrUnnamedType() | R.hasLocalOrUnnamedType()); } }; -} + +} // namespace static CachedProperties computeCachedProperties(const Type *T); namespace clang { + /// The type-property cache. This is templated so as to be /// instantiated at an internal type to prevent unnecessary symbol /// leakage. @@ -3498,13 +3525,19 @@ public: T->TypeBits.CachedLocalOrUnnamed = Result.hasLocalOrUnnamedType(); } }; -} + +} // namespace clang // Instantiate the friend template at a private class. In a // reasonable implementation, these symbols will be internal. // It is terrible that this is the best way to accomplish this. -namespace { class Private {}; } -typedef TypePropertyCache Cache; +namespace { + +class Private {}; + +} // namespace + +using Cache = TypePropertyCache; static CachedProperties computeCachedProperties(const Type *T) { switch (T->getTypeClass()) { @@ -3931,11 +3964,13 @@ bool Type::isObjCIndependentClassType() const { return typedefType->getDecl()->hasAttr(); return false; } + bool Type::isObjCRetainableType() const { return isObjCObjectPointerType() || isBlockPointerType() || isObjCNSObjectType(); } + bool Type::isObjCIndirectLifetimeType() const { if (isObjCLifetimeType()) return true; -- 2.7.4