diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2013-02-13 22:50:36 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2013-02-13 22:50:36 +0000 |
commit | 2c5d8459f12549dc48654a4da33c085835831d1d (patch) | |
tree | f2c68156e3174a47cdbfa04d70dfd12de9091676 /lib/AST/DeclObjC.cpp | |
parent | 8ab612df83b06e7935643d552aec355bb065b9f3 (diff) |
objective-C: Make order of ivars which are synthesized
in the course of property synthesis deterministic (ordered
by their type size), instead of having hashtable order
(as it is currently). // rdar://13192366
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175100 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/DeclObjC.cpp')
-rw-r--r-- | lib/AST/DeclObjC.cpp | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index ce765a7bf5..6e740bfa09 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -1074,6 +1074,20 @@ void ObjCInterfaceDecl::setImplementation(ObjCImplementationDecl *ImplD) { getASTContext().setObjCImplementation(getDefinition(), ImplD); } +namespace { + struct SynthesizeIvarChunk { + uint64_t Size; + ObjCIvarDecl *Ivar; + SynthesizeIvarChunk(uint64_t size, ObjCIvarDecl *ivar) + : Size(size), Ivar(ivar) {} + }; + + bool operator<(const SynthesizeIvarChunk & LHS, + const SynthesizeIvarChunk &RHS) { + return LHS.Size < RHS.Size; + } +} + /// all_declared_ivar_begin - return first ivar declared in this class, /// its extensions and its implementation. Lazily build the list on first /// access. @@ -1110,14 +1124,33 @@ ObjCIvarDecl *ObjCInterfaceDecl::all_declared_ivar_begin() { if (ObjCImplementationDecl *ImplDecl = getImplementation()) { if (!ImplDecl->ivar_empty()) { - ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(), - E = ImplDecl->ivar_end(); - if (!data().IvarList) { - data().IvarList = *I; ++I; - curIvar = data().IvarList; + SmallVector<SynthesizeIvarChunk, 16> layout; + for (ObjCImplementationDecl::ivar_iterator I = ImplDecl->ivar_begin(), + E = ImplDecl->ivar_end(); I != E; ++I) { + ObjCIvarDecl *IV = *I; + if (IV->getSynthesize() && !IV->isInvalidDecl()) { + layout.push_back(SynthesizeIvarChunk( + IV->getASTContext().getTypeSize(IV->getType()), IV)); + continue; + } + if (!data().IvarList) + data().IvarList = *I; + else + curIvar->setNextIvar(*I); + curIvar = *I; + } + + if (!layout.empty()) { + // Order synthesized ivars by their size. + std::stable_sort(layout.begin(), layout.end()); + unsigned Ix = 0, EIx = layout.size(); + if (!data().IvarList) { + data().IvarList = layout[0].Ivar; Ix++; + curIvar = data().IvarList; + } + for ( ; Ix != EIx; curIvar = layout[Ix].Ivar, Ix++) + curIvar->setNextIvar(layout[Ix].Ivar); } - for ( ;I != E; curIvar = *I, ++I) - curIvar->setNextIvar(*I); } } return data().IvarList; |