}
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.
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";
}
// 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);
}
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);
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<EnumDecl>(EnumDeclX.getAs<Decl>());
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.
}
// 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<PackedAttr>() ? 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 {
} 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 <=
}
// 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;
}