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 41905c8..f45051b 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -157,16 +157,15 @@
uint64_t Size;
unsigned Align;
switch (T->getTypeClass()) {
- 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!");
+ default:
+ case Type::Array:
+ case Type::Vector:
+ case Type::TypeName:
+ assert(0 && "Unimplemented type sizes!");
+
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 @@
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<ReferenceType>(T)->getReferenceeType(), L);
+
+ case Type::Complex: {
+ // Complex types have the same alignment as their elements, but twice the
+ // size.
+ std::pair<uint64_t, unsigned> EltInfo =
+ getTypeInfo(cast<ComplexType>(T)->getElementType(), L);
+ Size = EltInfo.first*2;
+ Align = EltInfo.second;
+ break;
+ }
+ case Type::Tagged:
+ if (RecordType *RT = dyn_cast<RecordType>(cast<TagType>(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 @@
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 5169737..dec6e3a 100644
--- a/include/clang/AST/RecordLayout.h
+++ b/include/clang/AST/RecordLayout.h
@@ -35,7 +35,7 @@
}
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 7ec97cf..1c2d9b6 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -646,9 +646,13 @@
RecordType(); // DO NOT IMPLEMENT
public:
- RecordDecl *getDecl() const {
+ const RecordDecl *getDecl() const {
return reinterpret_cast<RecordDecl*>(TagType::getDecl());
}
+ RecordDecl *getDecl() {
+ return reinterpret_cast<RecordDecl*>(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.