From: John McCall Date: Thu, 6 May 2010 08:49:23 +0000 (+0000) Subject: Remember the number of positive and negative bits used by the enumerators of X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b5a618c59025898806160ed5e7f0ff5bb79e482;p=clang Remember the number of positive and negative bits used by the enumerators of an enum in the enum decl itself. Use some spare bits from TagDecl for this purpose. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103173 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 834c9a0c56..4c95d1da7f 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1651,6 +1651,12 @@ private: /// in the syntax of a declarator. bool IsEmbeddedInDeclarator : 1; +protected: + // These are used by (and only defined for) EnumDecl. + unsigned NumPositiveBits : 8; + unsigned NumNegativeBits : 8; + +private: SourceLocation TagKeywordLoc; SourceLocation RBraceLoc; @@ -1820,6 +1826,13 @@ class EnumDecl : public TagDecl { /// enumeration declared within the template. EnumDecl *InstantiatedFrom; + // The number of positive and negative bits required by the + // enumerators are stored in the SubclassBits field. + enum { + NumBitsWidth = 8, + NumBitsMask = (1 << NumBitsWidth) - 1 + }; + EnumDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, EnumDecl *PrevDecl, SourceLocation TKL) : TagDecl(Enum, TK_enum, DC, L, Id, PrevDecl, TKL), InstantiatedFrom(0) { @@ -1845,7 +1858,9 @@ public: /// added (via DeclContext::addDecl). NewType is the new underlying /// type of the enumeration type. void completeDefinition(QualType NewType, - QualType PromotionType); + QualType PromotionType, + unsigned NumPositiveBits, + unsigned NumNegativeBits); // enumerator_iterator - Iterates through the enumerators of this // enumeration. @@ -1873,6 +1888,32 @@ public: /// \brief Set the underlying integer type. void setIntegerType(QualType T) { IntegerType = T; } + /// \brief Returns the width in bits requred to store all the + /// non-negative enumerators of this enum. + unsigned getNumPositiveBits() const { + return NumPositiveBits; + } + void setNumPositiveBits(unsigned Num) { + NumPositiveBits = Num; + assert(NumPositiveBits == Num && "can't store this bitcount"); + } + + /// \brief Returns the width in bits requred to store all the + /// negative enumerators of this enum. These widths include + /// the rightmost leading 1; that is: + /// + /// MOST NEGATIVE ENUMERATOR PATTERN NUM NEGATIVE BITS + /// ------------------------ ------- ----------------- + /// -1 1111111 1 + /// -10 1110110 5 + /// -101 1001011 8 + unsigned getNumNegativeBits() const { + return NumNegativeBits; + } + void setNumNegativeBits(unsigned Num) { + NumNegativeBits = Num; + } + /// \brief Returns the enumeration (declared within the template) /// from which this enumeration type was instantiated, or NULL if /// this enumeration was not instantiated from any template. diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index ae09d7978e..083c1bf7d8 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -1617,7 +1617,12 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) { D2->startDefinition(); ImportDeclContext(D); - D2->completeDefinition(T, ToPromotionType); + + // FIXME: we might need to merge the number of positive or negative bits + // if the enumerator lists don't match. + D2->completeDefinition(T, ToPromotionType, + D->getNumPositiveBits(), + D->getNumNegativeBits()); } return D2; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index e19a9fb7c2..0336ca1eaa 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1572,10 +1572,14 @@ void EnumDecl::Destroy(ASTContext& C) { } void EnumDecl::completeDefinition(QualType NewType, - QualType NewPromotionType) { + QualType NewPromotionType, + unsigned NumPositiveBits, + unsigned NumNegativeBits) { assert(!isDefinition() && "Cannot redefine enums!"); IntegerType = NewType; PromotionType = NewPromotionType; + setNumPositiveBits(NumPositiveBits); + setNumNegativeBits(NumNegativeBits); TagDecl::completeDefinition(); } diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index 6700dd3af4..7e126600b8 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -142,6 +142,8 @@ void PCHDeclReader::VisitEnumDecl(EnumDecl *ED) { VisitTagDecl(ED); ED->setIntegerType(Reader.GetType(Record[Idx++])); ED->setPromotionType(Reader.GetType(Record[Idx++])); + ED->setNumPositiveBits(Record[Idx++]); + ED->setNumNegativeBits(Record[Idx++]); // FIXME: C++ InstantiatedFrom } diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index d3618df64e..3585093438 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -137,6 +137,8 @@ void PCHDeclWriter::VisitEnumDecl(EnumDecl *D) { VisitTagDecl(D); Writer.AddTypeRef(D->getIntegerType(), Record); Writer.AddTypeRef(D->getPromotionType(), Record); + Record.push_back(D->getNumPositiveBits()); + Record.push_back(D->getNumNegativeBits()); // FIXME: C++ InstantiatedFrom Code = pch::DECL_ENUM; } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a802679b26..bf3c172483 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6435,7 +6435,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->setType(EnumType); } - Enum->completeDefinition(Context.DependentTy, Context.DependentTy); + Enum->completeDefinition(Context.DependentTy, Context.DependentTy, 0, 0); return; } @@ -6616,7 +6616,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->setType(NewTy); } - Enum->completeDefinition(BestType, BestPromotionType); + Enum->completeDefinition(BestType, BestPromotionType, + NumPositiveBits, NumNegativeBits); } Sema::DeclPtrTy Sema::ActOnFileScopeAsmDecl(SourceLocation Loc,