]> granicus.if.org Git - clang/commitdiff
Add ObjCInterface layout support.
authorDevang Patel <dpatel@apple.com>
Wed, 4 Jun 2008 21:54:36 +0000 (21:54 +0000)
committerDevang Patel <dpatel@apple.com>
Wed, 4 Jun 2008 21:54:36 +0000 (21:54 +0000)
Reuse RecordLayout.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51968 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/AST/RecordLayout.h
lib/AST/ASTContext.cpp
test/Sema/objc-interface-layout.m [new file with mode: 0644]

index cf04f94990979ee00986de8986eba52b7becfd2d..1fd65b1306f928c764182a74209e651450a1da99 100644 (file)
@@ -49,6 +49,8 @@ class ASTContext {
   /// ASTRecordLayouts - A cache mapping from RecordDecls to ASTRecordLayouts.
   ///  This is lazily created.  This is intentionally not serialized.
   llvm::DenseMap<const RecordDecl*, const ASTRecordLayout*> ASTRecordLayouts;
+  llvm::DenseMap<const ObjCInterfaceDecl*, 
+                 const ASTRecordLayout*> ASTObjCInterfaces;
   
   llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
     
@@ -304,6 +306,7 @@ public:
   /// position information.
   const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D);
   
+  const ASTRecordLayout &getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D);
   //===--------------------------------------------------------------------===//
   //                            Type Operators
   //===--------------------------------------------------------------------===//
index a4964b36915c5ce3ed1c839a6c5230df849d379d..82880abfcf58285989058541ed1a1c1c574de83c 100644 (file)
@@ -20,9 +20,13 @@ namespace clang {
   class ASTContext;
   class RecordDecl;
 
-/// ASTRecordLayout - This class contains layout information for one RecordDecl,
+/// ASTRecordLayout - 
+/// This class contains layout information for one RecordDecl,
 /// which is a struct/union/class.  The decl represented must be a definition,
-/// not a forward declaration.  These objects are managed by ASTContext.
+/// not a forward declaration.  
+/// This class is also used to contain layout informaiton for one 
+/// ObjCInterfaceDecl. FIXME - Find appropriate name.
+/// These objects are managed by ASTContext.
 class ASTRecordLayout {
   uint64_t Size;        // Size of record in bits.
   unsigned Alignment;   // Alignment of record in bits.
index 6b5eaa112ce0c352c6072019d38c6ffbeeb66a54..4a1fb39bb60afaaf452fe657e17682d445aeafc9 100644 (file)
@@ -295,6 +295,13 @@ ASTContext::getTypeInfo(QualType T) {
     Align = EltInfo.second;
     break;
   }
+  case Type::ObjCInterface: {
+    ObjCInterfaceType *ObjCI = cast<ObjCInterfaceType>(T);
+    const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
+    Width = Layout.getSize();
+    Align = Layout.getAlignment();
+    break;
+  }
   case Type::Tagged: {
     if (EnumType *ET = dyn_cast<EnumType>(cast<TagType>(T)))
       return getTypeInfo(ET->getDecl()->getIntegerType());
@@ -386,6 +393,42 @@ void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo,
   Alignment = std::max(Alignment, FieldAlign);
 }
 
+
+/// getASTObjcInterfaceLayout - Get or compute information about the layout of the
+/// specified Objective C, which indicates its size and ivar
+/// position information.
+const ASTRecordLayout &
+ASTContext::getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) {
+  // Look up this layout, if already laid out, return what we have.
+  const ASTRecordLayout *&Entry = ASTObjCInterfaces[D];
+  if (Entry) return *Entry;
+
+  // Allocate and assign into ASTRecordLayouts here.  The "Entry" reference can
+  // be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
+  ASTRecordLayout *NewEntry = new ASTRecordLayout();
+  Entry = NewEntry;
+
+  NewEntry->InitializeLayout(D->ivar_size());
+  bool IsPacked = D->getAttr<PackedAttr>();
+
+  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
+    NewEntry->SetAlignment(std::max(NewEntry->getAlignment(), 
+                                    AA->getAlignment()));
+
+  // Layout each ivar sequentially.
+  unsigned i = 0;
+  for (ObjCInterfaceDecl::ivar_iterator IVI = D->ivar_begin(), 
+       IVE = D->ivar_end(); IVI != IVE; ++IVI) {
+    const ObjCIvarDecl* Ivar = (*IVI);
+    NewEntry->LayoutField(Ivar, i++, false, IsPacked, *this);
+  }
+
+  // Finally, round the size of the total struct up to the alignment of the
+  // struct itself.
+  NewEntry->FinalizeLayout();
+  return *NewEntry;
+}
+
 /// getASTRecordLayout - Get or compute information about the layout of the
 /// specified record (struct/union/class), which indicates its size and field
 /// position information.
diff --git a/test/Sema/objc-interface-layout.m b/test/Sema/objc-interface-layout.m
new file mode 100644 (file)
index 0000000..637de8e
--- /dev/null
@@ -0,0 +1,27 @@
+// RUN: clang %s -fsyntax-only -verify
+typedef struct objc_object {} *id;
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+
+@protocol NSObject
+- (BOOL) isEqual:(id) object;
+@end
+
+@protocol NSCopying
+- (id) copyWithZone:(NSZone *) zone;
+@end
+
+@interface NSObject < NSObject > {}
+@end
+
+extern id NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone * zone);
+
+@interface MyClassBase : NSObject < NSCopying > {}
+@end
+
+@interface MyClassDirectNode : MyClassBase < NSCopying >
+{
+  @public NSUInteger attributeRuns[((1024 - 16 - sizeof (MyClassBase)) / (sizeof (NSUInteger) + sizeof (void *)))];
+}
+@end