From aedaaa4f35a5fcae89a8a22f6882e6456da0acbf Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 14 Feb 2013 22:33:34 +0000 Subject: [PATCH] objective-C: synthesize properties in order of their declarations to synthesize their ivars in similar determinstic order so they are laid out in a determinstic order. // rdar://13192366 llvm-svn: 175214 --- clang/include/clang/AST/DeclObjC.h | 13 +++++++++---- clang/lib/AST/DeclObjC.cpp | 12 ++++++++---- clang/lib/Sema/SemaObjCProperty.cpp | 17 ++++++++++------- .../StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp | 3 ++- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index a09bcb5..1c5588f 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -549,11 +549,14 @@ public: ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; typedef llvm::DenseMap PropertyMap; - + + typedef llvm::SmallVector PropertyDeclOrder; + /// This routine collects list of properties to be implemented in the class. /// This includes, class's and its conforming protocols' properties. /// Note, the superclass's properties are not included in the list. - virtual void collectPropertiesToImplement(PropertyMap &PM) const {} + virtual void collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const {} SourceLocation getAtStartLoc() const { return AtStart; } void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } @@ -1090,7 +1093,8 @@ public: ObjCPropertyDecl *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; - virtual void collectPropertiesToImplement(PropertyMap &PM) const; + virtual void collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const; /// isSuperClassOf - Return true if this class is the specified class or is a /// super class of the specified interface class. @@ -1489,7 +1493,8 @@ public: return getFirstDeclaration(); } - virtual void collectPropertiesToImplement(PropertyMap &PM) const; + virtual void collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const; static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCProtocol; } diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index 6e740bf..d539e00 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -217,16 +217,18 @@ ObjCInterfaceDecl::FindPropertyVisibleInPrimaryClass( return 0; } -void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM) const { +void ObjCInterfaceDecl::collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const { for (ObjCContainerDecl::prop_iterator P = prop_begin(), E = prop_end(); P != E; ++P) { ObjCPropertyDecl *Prop = *P; PM[Prop->getIdentifier()] = Prop; + PO.push_back(Prop); } for (ObjCInterfaceDecl::all_protocol_iterator PI = all_referenced_protocol_begin(), E = all_referenced_protocol_end(); PI != E; ++PI) - (*PI)->collectPropertiesToImplement(PM); + (*PI)->collectPropertiesToImplement(PM, PO); // Note, the properties declared only in class extensions are still copied // into the main @interface's property list, and therefore we don't // explicitly, have to search class extension properties. @@ -1433,7 +1435,8 @@ void ObjCProtocolDecl::startDefinition() { RD->Data = this->Data; } -void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) const { +void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM, + PropertyDeclOrder &PO) const { if (const ObjCProtocolDecl *PDecl = getDefinition()) { for (ObjCProtocolDecl::prop_iterator P = PDecl->prop_begin(), @@ -1441,11 +1444,12 @@ void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM) const { ObjCPropertyDecl *Prop = *P; // Insert into PM if not there already. PM.insert(std::make_pair(Prop->getIdentifier(), Prop)); + PO.push_back(Prop); } // Scan through protocol's protocols. for (ObjCProtocolDecl::protocol_iterator PI = PDecl->protocol_begin(), E = PDecl->protocol_end(); PI != E; ++PI) - (*PI)->collectPropertiesToImplement(PM); + (*PI)->collectPropertiesToImplement(PM, PO); } } diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index e238b7e..e046faa 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -1534,8 +1534,9 @@ void Sema::CollectImmediateProperties(ObjCContainerDecl *CDecl, static void CollectSuperClassPropertyImplementations(ObjCInterfaceDecl *CDecl, ObjCInterfaceDecl::PropertyMap &PropMap) { if (ObjCInterfaceDecl *SDecl = CDecl->getSuperClass()) { + ObjCInterfaceDecl::PropertyDeclOrder PO; while (SDecl) { - SDecl->collectPropertiesToImplement(PropMap); + SDecl->collectPropertiesToImplement(PropMap, PO); SDecl = SDecl->getSuperClass(); } } @@ -1574,15 +1575,15 @@ void Sema::DefaultSynthesizeProperties(Scope *S, ObjCImplDecl* IMPDecl, ObjCInterfaceDecl *IDecl) { ObjCInterfaceDecl::PropertyMap PropMap; - IDecl->collectPropertiesToImplement(PropMap); + ObjCInterfaceDecl::PropertyDeclOrder PropertyOrder; + IDecl->collectPropertiesToImplement(PropMap, PropertyOrder); if (PropMap.empty()) return; ObjCInterfaceDecl::PropertyMap SuperPropMap; CollectSuperClassPropertyImplementations(IDecl, SuperPropMap); - for (ObjCInterfaceDecl::PropertyMap::iterator - P = PropMap.begin(), E = PropMap.end(); P != E; ++P) { - ObjCPropertyDecl *Prop = P->second; + for (unsigned i = 0, e = PropertyOrder.size(); i != e; i++) { + ObjCPropertyDecl *Prop = PropertyOrder[i]; // If property to be implemented in the super class, ignore. if (SuperPropMap[Prop->getIdentifier()]) continue; @@ -1648,8 +1649,10 @@ void Sema::DiagnoseUnimplementedProperties(Scope *S, ObjCImplDecl* IMPDecl, // For categories, no need to implement properties declared in // its primary class (and its super classes) if property is // declared in one of those containers. - if ((IDecl = C->getClassInterface())) - IDecl->collectPropertiesToImplement(NoNeedToImplPropMap); + if ((IDecl = C->getClassInterface())) { + ObjCInterfaceDecl::PropertyDeclOrder PO; + IDecl->collectPropertiesToImplement(NoNeedToImplPropMap, PO); + } } if (IDecl) CollectSuperClassPropertyImplementations(IDecl, NoNeedToImplPropMap); diff --git a/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp index 0389cc5..5ed28e9 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IvarInvalidationChecker.cpp @@ -396,7 +396,8 @@ visit(const ObjCImplementationDecl *ImplD) const { IvarToPropMapTy IvarToPopertyMap; ObjCInterfaceDecl::PropertyMap PropMap; - InterfaceD->collectPropertiesToImplement(PropMap); + ObjCInterfaceDecl::PropertyDeclOrder PropOrder; + InterfaceD->collectPropertiesToImplement(PropMap, PropOrder); for (ObjCInterfaceDecl::PropertyMap::iterator I = PropMap.begin(), E = PropMap.end(); I != E; ++I) { -- 2.7.4