From: Chris Lattner Date: Wed, 18 Jul 2007 18:26:58 +0000 (+0000) Subject: implement sizeof/alignof support for structs, unions and complex. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d2a6303467184b1f159bb6556efc434e50e3c28;p=clang implement sizeof/alignof support for structs, unions and complex. This allows us to compile this: struct abc { char A; double D; }; int foo() { return sizeof(struct abc); return __alignof__(struct abc); } Into: ret i32 16 ret i32 8 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40010 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 41905c8ecd..f45051bf36 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -157,16 +157,15 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) { uint64_t Size; unsigned Align; switch (T->getTypeClass()) { + case Type::FunctionNoProto: + case Type::FunctionProto: + assert(0 && "Incomplete types have no size!"); default: - case Type::Complex: case Type::Array: case Type::Vector: case Type::TypeName: - case Type::Tagged: assert(0 && "Unimplemented type sizes!"); - case Type::FunctionNoProto: - case Type::FunctionProto: - assert(0 && "Incomplete types have no size!"); + case Type::Builtin: { // FIXME: need to use TargetInfo to derive the target specific sizes. This // implementation will suffice for play with vector support. @@ -196,8 +195,28 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) { case Type::Pointer: Target.getPointerInfo(Size, Align, L); break; case Type::Reference: // "When applied to a reference or a reference type, the result is the size - // of the referenced type." C++98 5.3.3p2: expr.sizeof + // of the referenced type." C++98 5.3.3p2: expr.sizeof. + // FIXME: This is wrong for struct layout! return getTypeInfo(cast(T)->getReferenceeType(), L); + + case Type::Complex: { + // Complex types have the same alignment as their elements, but twice the + // size. + std::pair EltInfo = + getTypeInfo(cast(T)->getElementType(), L); + Size = EltInfo.first*2; + Align = EltInfo.second; + break; + } + case Type::Tagged: + if (RecordType *RT = dyn_cast(cast(T))) { + const RecordLayout &Layout = getRecordLayout(RT->getDecl(), L); + Size = Layout.getSize(); + Align = Layout.getAlignment(); + break; + } + // FIXME: Handle enums. + assert(0 && "Unimplemented type sizes!"); } assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2"); @@ -267,6 +286,9 @@ const RecordLayout &ASTContext::getRecordLayout(const RecordDecl *D, RecordAlign = std::max(RecordAlign, FieldAlign); } } + + NewEntry->SetLayout(RecordSize, RecordAlign, FieldOffsets); + return *NewEntry; } diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 5169737636..dec6e3ae91 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -35,7 +35,7 @@ class RecordLayout { } void SetLayout(uint64_t size, unsigned alignment, uint64_t *fieldOffsets) { - Size = Size; Alignment = alignment; + Size = size; Alignment = alignment; FieldOffsets = fieldOffsets; } diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 7ec97cff49..1c2d9b6f60 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -646,9 +646,13 @@ class RecordType : public TagType { RecordType(); // DO NOT IMPLEMENT public: - RecordDecl *getDecl() const { + const RecordDecl *getDecl() const { return reinterpret_cast(TagType::getDecl()); } + RecordDecl *getDecl() { + return reinterpret_cast(TagType::getDecl()); + } + // FIXME: This predicate is a helper to QualType/Type. It needs to // recursively check all fields for const-ness. If any field is declared // const, it needs to return false.