summaryrefslogtreecommitdiffstats
path: root/lib/ARCMigrate/TransProperties.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-11-07 18:46:46 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-11-07 18:46:46 +0000
commitb0e1e121b32a9a04b39f1b77b3068bce2f3be05a (patch)
tree3c37fc42b2dcb5f13a17e6659028d7c19665333e /lib/ARCMigrate/TransProperties.cpp
parentbf8455c56cc5e328c31a2b56f5587cd0873ba0ae (diff)
[arcmt] In GC, handle (assign) @properties.
-Move __strong/__weak added to a property type to the property attribute, e.g. "@property (assign) __weak Foo *prop;" --> "@property (weak) Foo *prop;" -Remove (assign) in a property so that it becomes strong-by-default in ARC. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143979 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ARCMigrate/TransProperties.cpp')
-rw-r--r--lib/ARCMigrate/TransProperties.cpp144
1 files changed, 41 insertions, 103 deletions
diff --git a/lib/ARCMigrate/TransProperties.cpp b/lib/ARCMigrate/TransProperties.cpp
index f9f642ffc8..050512fbbe 100644
--- a/lib/ARCMigrate/TransProperties.cpp
+++ b/lib/ARCMigrate/TransProperties.cpp
@@ -44,6 +44,7 @@ using namespace trans;
namespace {
class PropertiesRewriter {
+ MigrationContext &MigrateCtx;
MigrationPass &Pass;
ObjCImplementationDecl *CurImplD;
@@ -51,7 +52,7 @@ class PropertiesRewriter {
PropAction_None,
PropAction_RetainToStrong,
PropAction_RetainRemoved,
- PropAction_AssignToStrong,
+ PropAction_AssignRemoved,
PropAction_AssignRewritten,
PropAction_MaybeAddStrong,
PropAction_MaybeAddWeakOrUnsafe
@@ -71,7 +72,8 @@ class PropertiesRewriter {
llvm::DenseMap<IdentifierInfo *, PropActionKind> ActionOnProp;
public:
- PropertiesRewriter(MigrationPass &pass) : Pass(pass) { }
+ explicit PropertiesRewriter(MigrationContext &MigrateCtx)
+ : MigrateCtx(MigrateCtx), Pass(MigrateCtx.Pass) { }
static void collectProperties(ObjCContainerDecl *D, AtPropDeclsTy &AtProps) {
for (ObjCInterfaceDecl::prop_iterator
@@ -167,9 +169,8 @@ private:
case PropAction_RetainRemoved:
removeAttribute("retain", atLoc);
return;
- case PropAction_AssignToStrong:
- rewriteAttribute("assign", "strong", atLoc);
- return;
+ case PropAction_AssignRemoved:
+ return removeAssignForDefaultStrong(props, atLoc);
case PropAction_AssignRewritten:
return rewriteAssign(props, atLoc);
case PropAction_MaybeAddStrong:
@@ -205,21 +206,39 @@ private:
return doPropAction(PropAction_RetainRemoved, props, atLoc);
}
+ bool HasIvarAssignedAPlusOneObject = hasIvarAssignedAPlusOneObject(props);
+
if (propAttrs & ObjCPropertyDecl::OBJC_PR_assign) {
- if (hasIvarAssignedAPlusOneObject(props)) {
- return doPropAction(PropAction_AssignToStrong, props, atLoc);
+ if (HasIvarAssignedAPlusOneObject ||
+ (Pass.isGCMigration() && !hasGCWeak(props, atLoc))) {
+ return doPropAction(PropAction_AssignRemoved, props, atLoc);
}
return doPropAction(PropAction_AssignRewritten, props, atLoc);
}
- if (hasIvarAssignedAPlusOneObject(props))
+ if (HasIvarAssignedAPlusOneObject ||
+ (Pass.isGCMigration() && !hasGCWeak(props, atLoc)))
return doPropAction(PropAction_MaybeAddStrong, props, atLoc);
return doPropAction(PropAction_MaybeAddWeakOrUnsafe, props, atLoc);
}
+ void removeAssignForDefaultStrong(PropsTy &props,
+ SourceLocation atLoc) const {
+ removeAttribute("retain", atLoc);
+ if (!removeAttribute("assign", atLoc))
+ return;
+
+ for (PropsTy::iterator I = props.begin(), E = props.end(); I != E; ++I) {
+ if (I->ImplD)
+ Pass.TA.clearDiagnostic(diag::err_arc_assign_property_ownership,
+ I->ImplD->getLocation());
+ }
+ }
+
void rewriteAssign(PropsTy &props, SourceLocation atLoc) const {
- bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props));
+ bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props),
+ /*AllowOnUnknownClass=*/Pass.isGCMigration());
bool rewroteAttr = rewriteAttribute("assign",
canUseWeak ? "weak" : "unsafe_unretained",
@@ -241,7 +260,8 @@ private:
SourceLocation atLoc) const {
ObjCPropertyDecl::PropertyAttributeKind propAttrs = getPropertyAttrs(props);
- bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props));
+ bool canUseWeak = canApplyWeak(Pass.Ctx, getPropertyType(props),
+ /*AllowOnUnknownClass=*/Pass.isGCMigration());
if (!(propAttrs & ObjCPropertyDecl::OBJC_PR_readonly) ||
!hasAllIvarsBacked(props)) {
bool addedAttr = addAttribute(canUseWeak ? "weak" : "unsafe_unretained",
@@ -289,85 +309,7 @@ private:
bool rewriteAttribute(StringRef fromAttr, StringRef toAttr,
SourceLocation atLoc) const {
- if (atLoc.isMacroID())
- return false;
-
- SourceManager &SM = Pass.Ctx.getSourceManager();
-
- // Break down the source location.
- std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(atLoc);
-
- // Try to load the file buffer.
- bool invalidTemp = false;
- StringRef file = SM.getBufferData(locInfo.first, &invalidTemp);
- if (invalidTemp)
- return false;
-
- const char *tokenBegin = file.data() + locInfo.second;
-
- // Lex from the start of the given location.
- Lexer lexer(SM.getLocForStartOfFile(locInfo.first),
- Pass.Ctx.getLangOptions(),
- file.begin(), tokenBegin, file.end());
- Token tok;
- lexer.LexFromRawLexer(tok);
- if (tok.isNot(tok::at)) return false;
- lexer.LexFromRawLexer(tok);
- if (tok.isNot(tok::raw_identifier)) return false;
- if (StringRef(tok.getRawIdentifierData(), tok.getLength())
- != "property")
- return false;
- lexer.LexFromRawLexer(tok);
- if (tok.isNot(tok::l_paren)) return false;
-
- Token BeforeTok = tok;
- Token AfterTok;
- AfterTok.startToken();
- SourceLocation AttrLoc;
-
- lexer.LexFromRawLexer(tok);
- if (tok.is(tok::r_paren))
- return false;
-
- while (1) {
- if (tok.isNot(tok::raw_identifier)) return false;
- StringRef ident(tok.getRawIdentifierData(), tok.getLength());
- if (ident == fromAttr) {
- if (!toAttr.empty()) {
- Pass.TA.replaceText(tok.getLocation(), fromAttr, toAttr);
- return true;
- }
- // We want to remove the attribute.
- AttrLoc = tok.getLocation();
- }
-
- do {
- lexer.LexFromRawLexer(tok);
- if (AttrLoc.isValid() && AfterTok.is(tok::unknown))
- AfterTok = tok;
- } while (tok.isNot(tok::comma) && tok.isNot(tok::r_paren));
- if (tok.is(tok::r_paren))
- break;
- if (AttrLoc.isInvalid())
- BeforeTok = tok;
- lexer.LexFromRawLexer(tok);
- }
-
- if (toAttr.empty() && AttrLoc.isValid() && AfterTok.isNot(tok::unknown)) {
- // We want to remove the attribute.
- if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::r_paren)) {
- Pass.TA.remove(SourceRange(BeforeTok.getLocation(),
- AfterTok.getLocation()));
- } else if (BeforeTok.is(tok::l_paren) && AfterTok.is(tok::comma)) {
- Pass.TA.remove(SourceRange(AttrLoc, AfterTok.getLocation()));
- } else {
- Pass.TA.remove(SourceRange(BeforeTok.getLocation(), AttrLoc));
- }
-
- return true;
- }
-
- return false;
+ return MigrateCtx.rewritePropertyAttribute(fromAttr, toAttr, atLoc);
}
bool addAttribute(StringRef attr, SourceLocation atLoc) const {
@@ -482,6 +424,15 @@ private:
return true;
}
+ // \brief Returns true if all declarations in the @property have GC __weak.
+ bool hasGCWeak(PropsTy &props, SourceLocation atLoc) const {
+ if (!Pass.isGCMigration())
+ return false;
+ if (props.empty())
+ return false;
+ return MigrateCtx.AtPropsWeak.count(atLoc.getRawEncoding());
+ }
+
bool isUserDeclared(ObjCIvarDecl *ivarD) const {
return ivarD && !ivarD->getSynthesize();
}
@@ -513,23 +464,10 @@ private:
}
};
-class ImplementationChecker :
- public RecursiveASTVisitor<ImplementationChecker> {
- MigrationPass &Pass;
-
-public:
- ImplementationChecker(MigrationPass &pass) : Pass(pass) { }
-
- bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
- PropertiesRewriter(Pass).doTransform(D);
- return true;
- }
-};
-
} // anonymous namespace
void PropertyRewriteTraverser::traverseObjCImplementation(
ObjCImplementationContext &ImplCtx) {
- PropertiesRewriter(ImplCtx.getMigrationContext().Pass)
+ PropertiesRewriter(ImplCtx.getMigrationContext())
.doTransform(ImplCtx.getImplementationDecl());
}