[cfe-commits] r40010 - in /cfe/trunk: AST/ASTContext.cpp include/clang/AST/RecordLayout.h include/clang/AST/Type.h

Chris Lattner sabre at nondot.org
Wed Jul 18 11:27:01 PDT 2007


Author: lattner
Date: Wed Jul 18 13:26:58 2007
New Revision: 40010

URL: http://llvm.org/viewvc/llvm-project?rev=40010&view=rev
Log:
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


Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/include/clang/AST/RecordLayout.h
    cfe/trunk/include/clang/AST/Type.h

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=40010&r1=40009&r2=40010&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Wed Jul 18 13:26:58 2007
@@ -157,16 +157,15 @@
   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 @@
   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;
 }
 
 

Modified: cfe/trunk/include/clang/AST/RecordLayout.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecordLayout.h?rev=40010&r1=40009&r2=40010&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/RecordLayout.h (original)
+++ cfe/trunk/include/clang/AST/RecordLayout.h Wed Jul 18 13:26:58 2007
@@ -35,7 +35,7 @@
   }
   
   void SetLayout(uint64_t size, unsigned alignment, uint64_t *fieldOffsets) {
-    Size = Size; Alignment = alignment;
+    Size = size; Alignment = alignment;
     FieldOffsets = fieldOffsets;
   }
   

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=40010&r1=40009&r2=40010&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Jul 18 13:26:58 2007
@@ -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. 





More information about the cfe-commits mailing list