From: Chris Lattner Date: Mon, 27 Aug 2007 17:38:00 +0000 (+0000) Subject: implement sizeof(enum x), patch inspired by Keith Bauer. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6cd862c631eb4fc10755c146bbeaea37c330e815;p=clang implement sizeof(enum x), patch inspired by Keith Bauer. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41500 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 4b79582e52..1a740b5245 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -227,13 +227,16 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) { break; } case Type::Tagged: - RecordType *RT = dyn_cast(cast(T)); - if (!RT) - // FIXME: Handle enums. + TagType *TT = cast(T); + if (RecordType *RT = dyn_cast(TT)) { + const RecordLayout &Layout = getRecordLayout(RT->getDecl(), L); + Size = Layout.getSize(); + Align = Layout.getAlignment(); + } else if (EnumDecl *ED = dyn_cast(TT->getDecl())) { + return getTypeInfo(getEnumDeclIntegerType(ED), L); + } else { assert(0 && "Unimplemented type sizes!"); - const RecordLayout &Layout = getRecordLayout(RT->getDecl(), L); - Size = Layout.getSize(); - Align = Layout.getAlignment(); + } break; } @@ -309,6 +312,22 @@ const RecordLayout &ASTContext::getRecordLayout(const RecordDecl *D, return *NewEntry; } +/// getEnumDeclIntegerType - returns the integer type compatible with the +/// given enum type. +QualType ASTContext::getEnumDeclIntegerType(EnumDecl *ED) const { + if (EnumConstantDecl *C = ED->getEnumConstantList()) + return C->getType(); + + // If the enum list is empty, it is typed as if it contained a single zero + // element [C++ dcl.enum] and is illegal in C (as an extension, we treat it + // the same as C++ does). + switch (Target.getEnumTypePolicy(ED->getLocation())) { + default: assert(0 && "Unknown enum layout policy"); + case TargetInfo::AlwaysInt: return UnsignedIntTy; // 0 -> unsigned + case TargetInfo::ShortestType: return UnsignedCharTy; // 0 -> unsigned char + } +} + //===----------------------------------------------------------------------===// // Type creation/memoization methods @@ -775,4 +794,4 @@ QualType ASTContext::getCFConstantStringType() { } return getTagDeclType(CFConstantStringTypeDecl); -} +} \ No newline at end of file diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 2bfc6af89a..8973087a52 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -147,6 +147,10 @@ public: /// position information. const RecordLayout &getRecordLayout(const RecordDecl *D, SourceLocation L); + /// getEnumDeclIntegerType - returns the integer type compatible with the + /// given enum type. + QualType getEnumDeclIntegerType(EnumDecl *ED) const; + //===--------------------------------------------------------------------===// // Type Operators //===--------------------------------------------------------------------===//