From 1b5a618c59025898806160ed5e7f0ff5bb79e482 Mon Sep 17 00:00:00 2001 From: John McCall Date: Thu, 6 May 2010 08:49:23 +0000 Subject: [PATCH] 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 --- include/clang/AST/Decl.h | 43 +++++++++++++++++++++++++++++++++- lib/AST/ASTImporter.cpp | 7 +++++- lib/AST/Decl.cpp | 6 ++++- lib/Frontend/PCHReaderDecl.cpp | 2 ++ lib/Frontend/PCHWriterDecl.cpp | 2 ++ lib/Sema/SemaDecl.cpp | 5 ++-- 6 files changed, 60 insertions(+), 5 deletions(-) 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, -- 2.40.0