summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevang Patel <dpatel@apple.com>2008-06-04 21:54:36 +0000
committerDevang Patel <dpatel@apple.com>2008-06-04 21:54:36 +0000
commitdbb7263fd96bbe03179b50bac79bb5efa253bf27 (patch)
treeef97b349bcede7fae20e6571d4f5cd2a1f5af8c7
parent524fbe8687bddab6decf6ad58ccd790570c8550f (diff)
downloadbcm5719-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.h3
-rw-r--r--clang/include/clang/AST/RecordLayout.h8
-rw-r--r--clang/lib/AST/ASTContext.cpp43
-rw-r--r--clang/test/Sema/objc-interface-layout.m27
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
OpenPOWER on IntegriCloud