From fee13819693c8492f0c364bc704645e844ef737a Mon Sep 17 00:00:00 2001 From: Edward O'Callaghan Date: Sat, 8 Aug 2009 14:36:57 +0000 Subject: [PATCH] Patch should implement packed enums - PR4098. Credit to Anders Johnsen. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78471 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Action.h | 3 +- lib/Frontend/PrintParserCallbacks.cpp | 3 +- lib/Parse/ParseDecl.cpp | 11 ++++---- lib/Sema/Sema.h | 3 +- lib/Sema/SemaDecl.cpp | 35 ++++++++++++++++++++---- lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 ++- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 0781a04777..b2be36eb05 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -530,7 +530,8 @@ public: } virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, DeclPtrTy EnumDecl, - DeclPtrTy *Elements, unsigned NumElements) {} + DeclPtrTy *Elements, unsigned NumElements, + Scope *S, AttributeList *AttrList) {} //===--------------------------------------------------------------------===// // Statement Parsing Callbacks. diff --git a/lib/Frontend/PrintParserCallbacks.cpp b/lib/Frontend/PrintParserCallbacks.cpp index 43a5b6f20f..c933a2f320 100644 --- a/lib/Frontend/PrintParserCallbacks.cpp +++ b/lib/Frontend/PrintParserCallbacks.cpp @@ -245,7 +245,8 @@ namespace { virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, DeclPtrTy EnumDecl, - DeclPtrTy *Elements, unsigned NumElements) { + DeclPtrTy *Elements, unsigned NumElements, + Scope *S, AttributeList *AttrList) { Out << __FUNCTION__ << "\n"; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index a80f57c8ca..029d9b5aae 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1707,14 +1707,15 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) { // Eat the }. SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); - Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl, - EnumConstantDecls.data(), EnumConstantDecls.size()); - - Action::AttrTy *AttrList = 0; + AttributeList *Attr = 0; // If attributes exist after the identifier list, parse them. if (Tok.is(tok::kw___attribute)) - AttrList = ParseAttributes(); // FIXME: where do they do? + Attr = ParseAttributes(); + Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl, + EnumConstantDecls.data(), EnumConstantDecls.size(), + CurScope, Attr); + EnumScope.Exit(); Actions.ActOnTagFinishDefinition(CurScope, EnumDecl, RBraceLoc); } diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 295607b739..4ad7e704ab 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -619,7 +619,8 @@ public: SourceLocation EqualLoc, ExprTy *Val); virtual void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, DeclPtrTy EnumDecl, - DeclPtrTy *Elements, unsigned NumElements); + DeclPtrTy *Elements, unsigned NumElements, + Scope *S, AttributeList *Attr); DeclContext *getContainingDC(DeclContext *DC); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index d6b32a72a3..ed78ec0972 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5059,14 +5059,20 @@ Sema::DeclPtrTy Sema::ActOnEnumConstant(Scope *S, DeclPtrTy theEnumDecl, void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, DeclPtrTy EnumDeclX, - DeclPtrTy *Elements, unsigned NumElements) { + DeclPtrTy *Elements, unsigned NumElements, + Scope *S, AttributeList *Attr) { EnumDecl *Enum = cast(EnumDeclX.getAs()); QualType EnumType = Context.getTypeDeclType(Enum); + + if (Attr) + ProcessDeclAttributeList(S, Enum, Attr); // TODO: If the result value doesn't fit in an int, it must be a long or long // long value. ISO C does not support this, but GCC does as an extension, // emit a warning. unsigned IntWidth = Context.Target.getIntWidth(); + unsigned CharWidth = Context.Target.getCharWidth(); + unsigned ShortWidth = Context.Target.getShortWidth(); // Verify that all the values are okay, compute the size of the values, and // reverse the list. @@ -5108,14 +5114,25 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, } // Figure out the type that should be used for this enum. - // FIXME: Support attribute(packed) on enums and -fshort-enums. + // FIXME: Support -fshort-enums. QualType BestType; unsigned BestWidth; - + + bool Packed = Enum->getAttr() ? true : false; + if (NumNegativeBits) { // If there is a negative value, figure out the smallest integer type (of // int/long/longlong) that fits. - if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) { + // If it's packed, check also if it fits a char or a short. + if (Packed && NumNegativeBits <= CharWidth && NumPositiveBits < CharWidth) { + BestType = Context.SignedCharTy; + BestWidth = CharWidth; + } else if (Packed && NumNegativeBits <= ShortWidth && + NumPositiveBits < ShortWidth) { + BestType = Context.ShortTy; + BestWidth = ShortWidth; + } + else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) { BestType = Context.IntTy; BestWidth = IntWidth; } else { @@ -5134,7 +5151,15 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, } else { // If there is no negative value, figure out which of uint, ulong, ulonglong // fits. - if (NumPositiveBits <= IntWidth) { + // If it's packed, check also if it fits a char or a short. + if (Packed && NumPositiveBits <= CharWidth) { + BestType = Context.UnsignedCharTy; + BestWidth = CharWidth; + } else if (Packed && NumPositiveBits <= ShortWidth) { + BestType = Context.UnsignedShortTy; + BestWidth = ShortWidth; + } + else if (NumPositiveBits <= IntWidth) { BestType = Context.UnsignedIntTy; BestWidth = IntWidth; } else if (NumPositiveBits <= diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 1c98fca6af..86505ee8b0 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -283,9 +283,11 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { } // FIXME: Fixup LBraceLoc and RBraceLoc + // FIXME: Empty Scope and AttributeList (required to handle attribute packed). SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), SourceLocation(), Sema::DeclPtrTy::make(Enum), - &Enumerators[0], Enumerators.size()); + &Enumerators[0], Enumerators.size(), + 0, 0); return Enum; } -- 2.40.0