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.

llvm-svn: 103173
This commit is contained in:
John McCall 2010-05-06 08:49:23 +00:00
parent 31cdcd46d6
commit 9aa35bed45
6 changed files with 60 additions and 5 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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();
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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,