aboutsummaryrefslogtreecommitdiff
path: root/lib/ARCMigrate
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-18 19:49:19 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-10-18 19:49:19 +0000
commit44679012052b0d57f26a3aa141004687cb71a551 (patch)
tree412d1432a35e9f1cb17128da491245bd5c8ab693 /lib/ARCMigrate
parentb98ffded10453d80369951f33f3892f35d747c95 (diff)
[arcmt] Rewrite attributes in extensions as well. rdar://9992142
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142407 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate')
-rw-r--r--lib/ARCMigrate/TransProperties.cpp100
1 files changed, 83 insertions, 17 deletions
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index 2f5fe8be4c..db34ee27a5 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -46,6 +46,16 @@ namespace {
class PropertiesRewriter {
MigrationPass &Pass;
ObjCImplementationDecl *CurImplD;
+
+ enum PropActionKind {
+ PropAction_None,
+ PropAction_RetainToStrong,
+ PropAction_RetainRemoved,
+ PropAction_AssignToStrong,
+ PropAction_AssignRewritten,
+ PropAction_MaybeAddStrong,
+ PropAction_MaybeAddWeakOrUnsafe
+ };
struct PropData {
ObjCPropertyDecl *PropD;
@@ -58,24 +68,29 @@ class PropertiesRewriter {
typedef SmallVector<PropData, 2> PropsTy;
typedef std::map<unsigned, PropsTy> AtPropDeclsTy;
AtPropDeclsTy AtProps;
+ llvm::DenseMap<IdentifierInfo *, PropActionKind> ActionOnProp;
public:
PropertiesRewriter(MigrationPass &pass) : Pass(pass) { }
- void doTransform(ObjCImplementationDecl *D) {
- CurImplD = D;
- ObjCInterfaceDecl *iface = D->getClassInterface();
- if (!iface)
- return;
-
+ static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps) {
for (ObjCInterfaceDecl::prop_iterator
- propI = iface->prop_begin(),
- propE = iface->prop_end(); propI != propE; ++propI) {
+ propI = D->prop_begin(),
+ propE = D->prop_end(); propI != propE; ++propI) {
if (propI->getAtLoc().isInvalid())
continue;
PropsTy &props = AtProps[propI->getAtLoc().getRawEncoding()];
props.push_back(*propI);
}
+ }
+
+ void doTransform(ObjCImplementationDecl *D) {
+ CurImplD = D;
+ ObjCInterfaceDecl *iface = D->getClassInterface();
+ if (!iface)
+ return;
+
+ collectProperties(iface, AtProps);
typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl>
prop_impl_iterator;
@@ -119,10 +134,62 @@ public:
Transaction Trans(Pass.TA);
rewriteProperty(props, atLoc);
}
+
+ AtPropDeclsTy AtExtProps;
+ // Look through extensions.
+ for (ObjCCategoryDecl *Cat = iface->getCategoryList();
+ Cat; Cat = Cat->getNextClassCategory())
+ if (Cat->IsClassExtension())
+ collectProperties(Cat, AtExtProps);
+
+ for (AtPropDeclsTy::iterator
+ I = AtExtProps.begin(), E = AtExtProps.end(); I != E; ++I) {
+ SourceLocation atLoc = SourceLocation::getFromRawEncoding(I->first);
+ PropsTy &props = I->second;
+ Transaction Trans(Pass.TA);
+ doActionForExtensionProp(props, atLoc);
+ }
}
private:
- void rewriteProperty(PropsTy &props, SourceLocation atLoc) const {
+ void doPropAction(PropActionKind kind,
+ PropsTy &props, SourceLocation atLoc,
+ bool markAction = true) {
+ if (markAction)
+ for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I)
+ ActionOnProp[I->PropD->getIdentifier()] = kind;
+
+ switch (kind) {
+ case PropAction_None:
+ return;
+ case PropAction_RetainToStrong:
+ rewriteAttribute("retain", "strong", atLoc);
+ return;
+ case PropAction_RetainRemoved:
+ removeAttribute("retain", atLoc);
+ return;
+ case PropAction_AssignToStrong:
+ rewriteAttribute("assign", "strong", atLoc);
+ return;
+ case PropAction_AssignRewritten:
+ return rewriteAssign(props, atLoc);
+ case PropAction_MaybeAddStrong:
+ return maybeAddStrongAttr(props, atLoc);
+ case PropAction_MaybeAddWeakOrUnsafe:
+ return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc);
+ }
+ }
+
+ void doActionForExtensionProp(PropsTy &props, SourceLocation atLoc) {
+ llvm::DenseMap<IdentifierInfo *, PropActionKind>::iterator I;
+ I = ActionOnProp.find(props[0].PropD->getIdentifier());
+ if (I == ActionOnProp.end())
+ return;
+
+ doPropAction(I->second, props, atLoc, false);
+ }
+
+ void rewriteProperty(PropsTy &props, SourceLocation atLoc) {
ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props);
if (propAttrs & (ObjCPropertyDecl::OBJC_PR_copy |
@@ -133,24 +200,23 @@ private:
if (propAttrs & ObjCPropertyDecl::OBJC_PR_retain) {
if (propAttrs & ObjCPropertyDecl::OBJC_PR_readonly)
- rewriteAttribute("retain", "strong", atLoc);
+ return doPropAction(PropAction_RetainToStrong, props, atLoc);
else
- removeAttribute("retain", atLoc); // strong is the default.
- return;
+ // strong is the default.
+ return doPropAction(PropAction_RetainRemoved, props, atLoc);
}
if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) {
if (hasIvarAssignedAPlusOneObject(props)) {
- rewriteAttribute("assign", "strong", atLoc);
- return;
+ return doPropAction(PropAction_AssignToStrong, props, atLoc);
}
- return rewriteAssign(props, atLoc);
+ return doPropAction(PropAction_AssignRewritten, props, atLoc);
}
if (hasIvarAssignedAPlusOneObject(props))
- return maybeAddStrongAttr(props, atLoc);
+ return doPropAction(PropAction_MaybeAddStrong, props, atLoc);
- return maybeAddWeakOrUnsafeUnretainedAttr(props, atLoc);
+ return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc);
}
void rewriteAssign(PropsTy &props, SourceLocation atLoc) const {