aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-03 11:16:44 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-03 11:16:44 +0000
commit453addbaea98f9678e2f9858057722a028f1ae3c (patch)
tree1a9be5b225744aa369e6bf0313c01ac5b01d0e7f /lib/AST/ASTContext.cpp
parent2bebbf0acee55404de4b8846713b64429e744e8f (diff)
Implement the interface/implementation layout distinction.
- These routines should now be independent of the Sema state. - This is nearly zero functionality change, the distinction only matters in the non-fragile ABI, and the consumers that care about this distinction should be using getASTObjCImplementationLayout. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70692 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r--lib/AST/ASTContext.cpp35
1 files changed, 25 insertions, 10 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 3342ca5bc9..65c9cddd9d 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -745,16 +745,29 @@ const ASTRecordLayout &
ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCImplementationDecl *Impl) {
// Look up this layout, if already laid out, return what we have.
- const ASTRecordLayout *&Entry = ObjCLayouts[D];
+ const ASTRecordLayout *&Entry =
+ ObjCLayouts[Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D];
if (Entry) return *Entry;
+ unsigned FieldCount = D->ivar_size();
+ // Add in synthesized ivar count if laying out an implementation.
+ if (Impl) {
+ for (ObjCInterfaceDecl::prop_iterator I = D->prop_begin(*this),
+ E = D->prop_end(*this); I != E; ++I)
+ if ((*I)->getPropertyIvarDecl())
+ ++FieldCount;
+
+ // If there aren't any sythesized ivar's then reuse the interface
+ // entry. Note we can't cache this because we simply free all
+ // entries later; however we shouldn't look up implementations
+ // frequently.
+ if (FieldCount == D->ivar_size())
+ return getObjCLayout(D, 0);
+ }
+
// Allocate and assign into ASTRecordLayouts here. The "Entry" reference can
// be invalidated (dangle) if the ASTRecordLayouts hashtable is inserted into.
ASTRecordLayout *NewEntry = NULL;
- // FIXME. Add actual count of synthesized ivars, instead of count
- // of properties which is the upper bound, but is safe.
- unsigned FieldCount =
- D->ivar_size() + std::distance(D->prop_begin(*this), D->prop_end(*this));
if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
FieldCount++;
const ASTRecordLayout &SL = getASTObjCInterfaceLayout(SD);
@@ -785,11 +798,13 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
const ObjCIvarDecl* Ivar = (*IVI);
NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this);
}
- // Also synthesized ivars
- for (ObjCInterfaceDecl::prop_iterator I = D->prop_begin(*this),
- E = D->prop_end(*this); I != E; ++I) {
- if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
- NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this);
+ // And synthesized ivars, if this is an implementation.
+ if (Impl) {
+ for (ObjCInterfaceDecl::prop_iterator I = D->prop_begin(*this),
+ E = D->prop_end(*this); I != E; ++I) {
+ if (ObjCIvarDecl *Ivar = (*I)->getPropertyIvarDecl())
+ NewEntry->LayoutField(Ivar, i++, false, StructPacking, *this);
+ }
}
// Finally, round the size of the total struct up to the alignment of the