From: Argyrios Kyrtzidis Date: Wed, 19 Aug 2009 01:28:17 +0000 (+0000) Subject: Introduce LocInfoType which is a Sema-specific implementation detail. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1bb8a45f7386a23871598d05141a07af03067925;p=clang Introduce LocInfoType which is a Sema-specific implementation detail. This is a Type subclass that can hold a DeclaratorInfo* when we have type source info coming out of a declarator that we want to preserve. This is used only at the "border" of Parser/Sema for passing/getting QualTypes, it does not participate in the type system semantics in any way. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79394 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index b5317edb03..70bafc1dec 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -290,7 +290,10 @@ public: #include "clang/AST/TypeNodes.def" TagFirst = Record, TagLast = Enum }; - + +protected: + enum { TypeClassBitSize = 6 }; + private: QualType CanonicalType; @@ -300,7 +303,7 @@ private: /// TypeClass bitfield - Enum that specifies what subclass this belongs to. /// Note that this should stay at the end of the ivars for Type so that /// subclasses can pack their bitfields into the same word. - unsigned TC : 6; + unsigned TC : TypeClassBitSize; Type(const Type&); // DO NOT IMPLEMENT. void operator=(const Type&); // DO NOT IMPLEMENT. @@ -2141,7 +2144,7 @@ public: } static bool classof(const ObjCObjectPointerType *) { return true; } }; - + // Inline function definitions. /// getUnqualifiedType - Return the type without any qualifiers. diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 6547434883..f39055fd87 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -764,7 +764,7 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, #define DEPENDENT_TYPE(Class, Base) case Type::Class: #include "clang/AST/TypeNodes.def" assert(false && "Dependent types cannot show up in debug information"); - + case Type::LValueReference: case Type::RValueReference: case Type::Vector: diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index b93faff7a0..35a2ae6741 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -128,6 +128,40 @@ struct BlockSemaInfo { BlockSemaInfo *PrevBlockInfo; }; +/// \brief Holds a QualType and a DeclaratorInfo* that came out of a declarator +/// parsing. +/// +/// LocInfoType is a "transient" type, only needed for passing to/from Parser +/// and Sema, when we want to preserve type source info for a parsed type. +/// It will not participate in the type system semantics in any way. +class LocInfoType : public Type { + enum { + // The last number that can fit in Type's TC. + // Avoids conflict with an existing Type class. + LocInfo = (1 << TypeClassBitSize) - 1 + }; + + DeclaratorInfo *DeclInfo; + + LocInfoType(QualType ty, DeclaratorInfo *DInfo) + : Type((TypeClass)LocInfo, ty, ty->isDependentType()), DeclInfo(DInfo) { + assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); + } + friend class Sema; + +public: + QualType getType() const { return getCanonicalTypeInternal(); } + DeclaratorInfo *getDeclaratorInfo() const { return DeclInfo; } + + virtual void getAsStringInternal(std::string &Str, + const PrintingPolicy &Policy) const; + + static bool classof(const Type *T) { + return T->getTypeClass() == (TypeClass)LocInfo; + } + static bool classof(const LocInfoType *) { return true; } +}; + /// Sema - This implements semantic analysis and AST building for C. class Sema : public Action { Sema(const Sema&); // DO NOT IMPLEMENT @@ -301,6 +335,8 @@ public: /// unit. bool CompleteTranslationUnit; + llvm::BumpPtrAllocator BumpAlloc; + /// \brief The number of SFINAE diagnostics that have been trapped. unsigned NumSFINAEErrors; @@ -425,6 +461,8 @@ public: unsigned Skip = 0, TagDecl **OwnedDecl = 0); DeclaratorInfo *GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip); + /// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo. + QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo); DeclarationName GetNameForDeclarator(Declarator &D); bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range); bool CheckDistantExceptionSpec(QualType T); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 03735bae40..0890340fe9 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1309,6 +1309,23 @@ Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) { return DInfo; } +/// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo. +QualType Sema::CreateLocInfoType(QualType T, DeclaratorInfo *DInfo) { + // FIXME: LocInfoTypes are "transient", only needed for passing to/from Parser + // and Sema during declaration parsing. Try deallocating/caching them when + // it's appropriate, instead of allocating them and keeping them around. + LocInfoType *LocT = (LocInfoType*)BumpAlloc.Allocate(sizeof(LocInfoType), 8); + new (LocT) LocInfoType(T, DInfo); + assert(LocT->getTypeClass() != T->getTypeClass() && + "LocInfoType's TypeClass conflicts with an existing Type class"); + return QualType(LocT, 0); +} + +void LocInfoType::getAsStringInternal(std::string &Str, + const PrintingPolicy &Policy) const { + assert(false && "LocInfoType should not be used in the type system"); +} + /// CheckSpecifiedExceptionType - Check if the given type is valid in an /// exception specification. Incomplete types, or pointers to incomplete types /// other than void are not allowed. diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 5516ab4410..e734d07e85 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -1561,7 +1561,7 @@ TreeTransform::AddTypeQualifiers(QualType T, unsigned CVRQualifiers) { return T; } - + template QualType TreeTransform::TransformExtQualType(const ExtQualType *T) { // FIXME: Implement