diff options
author | Devang Patel <dpatel@apple.com> | 2008-06-04 21:54:36 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2008-06-04 21:54:36 +0000 |
commit | dbb7263fd96bbe03179b50bac79bb5efa253bf27 (patch) | |
tree | ef97b349bcede7fae20e6571d4f5cd2a1f5af8c7 | |
parent | 524fbe8687bddab6decf6ad58ccd790570c8550f (diff) | |
download | bcm5719-llvm-dbb7263fd96bbe03179b50bac79bb5efa253bf27.tar.gz bcm5719-llvm-dbb7263fd96bbe03179b50bac79bb5efa253bf27.zip |
Add ObjCInterface layout support.
Reuse RecordLayout.
llvm-svn: 51968
-rw-r--r-- | clang/include/clang/AST/ASTContext.h | 3 | ||||
-rw-r--r-- | clang/include/clang/AST/RecordLayout.h | 8 | ||||
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 43 | ||||
-rw-r--r-- | clang/test/Sema/objc-interface-layout.m | 27 |
4 files changed, 79 insertions, 2 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index cf04f949909..1fd65b1306f 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -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 //===--------------------------------------------------------------------===// diff --git a/clang/include/clang/AST/RecordLayout.h b/clang/include/clang/AST/RecordLayout.h index a4964b36915..82880abfcf5 100644 --- a/clang/include/clang/AST/RecordLayout.h +++ b/clang/include/clang/AST/RecordLayout.h @@ -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. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6b5eaa112ce..4a1fb39bb60 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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/clang/test/Sema/objc-interface-layout.m b/clang/test/Sema/objc-interface-layout.m new file mode 100644 index 00000000000..637de8e3ac6 --- /dev/null +++ b/clang/test/Sema/objc-interface-layout.m @@ -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 |