[cfe-commits] r143979 - in /cfe/trunk: lib/ARCMigrate/TransGCAttrs.cpp lib/ARCMigrate/TransProperties.cpp lib/ARCMigrate/Transforms.cpp lib/ARCMigrate/Transforms.h test/ARCMT/GC.m test/ARCMT/GC.m.result
Argyrios Kyrtzidis
akyrtzi at gmail.com
Mon Nov 7 10:46:46 PST 2011
Author: akirtzidis
Date: Mon Nov 7 12:46:46 2011
New Revision: 143979
URL: http://llvm.org/viewvc/llvm-project?rev=143979&view=rev
Log:
[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.
Modified:
cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
cfe/trunk/lib/ARCMigrate/TransProperties.cpp
cfe/trunk/lib/ARCMigrate/Transforms.cpp
cfe/trunk/lib/ARCMigrate/Transforms.h
cfe/trunk/test/ARCMT/GC.m
cfe/trunk/test/ARCMT/GC.m.result
Modified: cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp?rev=143979&r1=143978&r2=143979&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp Mon Nov 7 12:46:46 2011
@@ -13,6 +13,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Analysis/Support/SaveAndRestore.h"
#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/TinyPtrVector.h"
using namespace clang;
using namespace arcmt;
@@ -24,11 +25,14 @@
class GCAttrsCollector : public RecursiveASTVisitor<GCAttrsCollector> {
MigrationContext &MigrateCtx;
bool FullyMigratable;
+ std::vector<ObjCPropertyDecl *> &AllProps;
typedef RecursiveASTVisitor<GCAttrsCollector> base;
public:
- explicit GCAttrsCollector(MigrationContext &ctx)
- : MigrateCtx(ctx), FullyMigratable(false) { }
+ GCAttrsCollector(MigrationContext &ctx,
+ std::vector<ObjCPropertyDecl *> &AllProps)
+ : MigrateCtx(ctx), FullyMigratable(false),
+ AllProps(AllProps) { }
bool shouldWalkTypesOfTypeLocs() const { return false; }
@@ -41,13 +45,14 @@
if (!D || D->isImplicit())
return true;
- bool migratable = isMigratable(D);
- SaveAndRestore<bool> Save(FullyMigratable, migratable);
+ SaveAndRestore<bool> Save(FullyMigratable, isMigratable(D));
- if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
- lookForAttribute(DD, DD->getTypeSourceInfo());
- else if (ObjCPropertyDecl *PropD = dyn_cast<ObjCPropertyDecl>(D))
+ if (ObjCPropertyDecl *PropD = dyn_cast<ObjCPropertyDecl>(D)) {
lookForAttribute(PropD, PropD->getTypeSourceInfo());
+ AllProps.push_back(PropD);
+ } else if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
+ lookForAttribute(DD, DD->getTypeSourceInfo());
+ }
return base::TraverseDecl(D);
}
@@ -56,11 +61,14 @@
return;
TypeLoc TL = TInfo->getTypeLoc();
while (TL) {
- if (const AttributedTypeLoc *Attr = dyn_cast<AttributedTypeLoc>(&TL)) {
+ if (const QualifiedTypeLoc *QL = dyn_cast<QualifiedTypeLoc>(&TL)) {
+ TL = QL->getUnqualifiedLoc();
+ } else if (const AttributedTypeLoc *
+ Attr = dyn_cast<AttributedTypeLoc>(&TL)) {
if (handleAttr(*Attr, D))
break;
TL = Attr->getModifiedLoc();
- } if (const ArrayTypeLoc *Arr = dyn_cast<ArrayTypeLoc>(&TL)) {
+ } else if (const ArrayTypeLoc *Arr = dyn_cast<ArrayTypeLoc>(&TL)) {
TL = Arr->getElementLoc();
} else if (const PointerTypeLoc *PT = dyn_cast<PointerTypeLoc>(&TL)) {
TL = PT->getPointeeLoc();
@@ -108,10 +116,6 @@
Attr.ModifiedType = TL.getModifiedLoc().getType();
Attr.Dcl = D;
Attr.FullyMigratable = FullyMigratable;
-
- if (ObjCPropertyDecl *PD = dyn_cast_or_null<ObjCPropertyDecl>(D))
- MigrateCtx.PropGCAttrs[PD] = MigrateCtx.GCAttrs.size() - 1;
-
return true;
}
@@ -125,15 +129,8 @@
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
return FD->hasBody();
- if (ObjCContainerDecl *ContD = dyn_cast<ObjCContainerDecl>(D)) {
- if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ContD))
- return ID->getImplementation() != 0;
- if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContD))
- return CD->getImplementation() != 0;
- if (isa<ObjCImplDecl>(ContD))
- return true;
- return false;
- }
+ if (ObjCContainerDecl *ContD = dyn_cast<ObjCContainerDecl>(D))
+ return hasObjCImpl(ContD);
if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
for (CXXRecordDecl::method_iterator
@@ -147,6 +144,21 @@
return isMigratable(cast<Decl>(D->getDeclContext()));
}
+ static bool hasObjCImpl(Decl *D) {
+ if (!D)
+ return false;
+ if (ObjCContainerDecl *ContD = dyn_cast<ObjCContainerDecl>(D)) {
+ if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(ContD))
+ return ID->getImplementation() != 0;
+ if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(ContD))
+ return CD->getImplementation() != 0;
+ if (isa<ObjCImplDecl>(ContD))
+ return true;
+ return false;
+ }
+ return false;
+ }
+
bool isInMainFile(Decl *D) {
if (!D)
return false;
@@ -214,8 +226,7 @@
for (unsigned i = 0, e = MigrateCtx.GCAttrs.size(); i != e; ++i) {
MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs[i];
- if (Attr.Kind == MigrationContext::GCAttrOccurrence::Weak &&
- Attr.FullyMigratable) {
+ if (Attr.Kind == MigrationContext::GCAttrOccurrence::Weak) {
if (Attr.ModifiedType.isNull() ||
!Attr.ModifiedType->isObjCRetainableType())
continue;
@@ -231,13 +242,113 @@
}
}
+typedef llvm::TinyPtrVector<ObjCPropertyDecl *> IndivPropsTy;
+
+static void checkAllAtProps(MigrationContext &MigrateCtx,
+ SourceLocation AtLoc,
+ IndivPropsTy &IndProps) {
+ if (IndProps.empty())
+ return;
+
+ for (IndivPropsTy::iterator
+ PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) {
+ QualType T = (*PI)->getType();
+ if (T.isNull() || !T->isObjCRetainableType())
+ return;
+ }
+
+ SmallVector<std::pair<AttributedTypeLoc, ObjCPropertyDecl *>, 4> ATLs;
+ bool hasWeak = false, hasStrong = false;
+ for (IndivPropsTy::iterator
+ PI = IndProps.begin(), PE = IndProps.end(); PI != PE; ++PI) {
+ ObjCPropertyDecl *PD = *PI;
+ TypeSourceInfo *TInfo = PD->getTypeSourceInfo();
+ if (!TInfo)
+ return;
+ TypeLoc TL = TInfo->getTypeLoc();
+ if (AttributedTypeLoc *ATL = dyn_cast<AttributedTypeLoc>(&TL)) {
+ ATLs.push_back(std::make_pair(*ATL, PD));
+ if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
+ hasWeak = true;
+ } else if (TInfo->getType().getObjCLifetime() == Qualifiers::OCL_Strong)
+ hasStrong = true;
+ else
+ return;
+ }
+ }
+ if (ATLs.empty())
+ return;
+ if (hasWeak && hasStrong)
+ return;
+
+ TransformActions &TA = MigrateCtx.Pass.TA;
+ Transaction Trans(TA);
+
+ if (GCAttrsCollector::hasObjCImpl(
+ cast<Decl>(IndProps.front()->getDeclContext()))) {
+ if (hasWeak)
+ MigrateCtx.AtPropsWeak.insert(AtLoc.getRawEncoding());
+
+ } else {
+ StringRef toAttr = "strong";
+ if (hasWeak) {
+ if (canApplyWeak(MigrateCtx.Pass.Ctx, IndProps.front()->getType(),
+ /*AllowOnUnkwownClass=*/true))
+ toAttr = "weak";
+ else
+ toAttr = "unsafe_unretained";
+ }
+ if (!MigrateCtx.rewritePropertyAttribute("assign", toAttr, AtLoc)) {
+ return;
+ }
+ }
+
+ for (unsigned i = 0, e = ATLs.size(); i != e; ++i) {
+ SourceLocation Loc = ATLs[i].first.getAttrNameLoc();
+ if (Loc.isMacroID())
+ Loc = MigrateCtx.Pass.Ctx.getSourceManager()
+ .getImmediateExpansionRange(Loc).first;
+ TA.remove(Loc);
+ TA.clearDiagnostic(diag::err_objc_property_attr_mutually_exclusive, AtLoc);
+ TA.clearDiagnostic(diag::err_arc_inconsistent_property_ownership,
+ ATLs[i].second->getLocation());
+ }
+}
+
+static void checkAllProps(MigrationContext &MigrateCtx,
+ std::vector<ObjCPropertyDecl *> &AllProps) {
+ typedef llvm::TinyPtrVector<ObjCPropertyDecl *> IndivPropsTy;
+ llvm::DenseMap<unsigned, IndivPropsTy> AtProps;
+
+ for (unsigned i = 0, e = AllProps.size(); i != e; ++i) {
+ ObjCPropertyDecl *PD = AllProps[i];
+ if (PD->getPropertyAttributesAsWritten() &
+ ObjCPropertyDecl::OBJC_PR_assign) {
+ SourceLocation AtLoc = PD->getAtLoc();
+ if (AtLoc.isInvalid())
+ continue;
+ unsigned RawAt = AtLoc.getRawEncoding();
+ AtProps[RawAt].push_back(PD);
+ }
+ }
+
+ for (llvm::DenseMap<unsigned, IndivPropsTy>::iterator
+ I = AtProps.begin(), E = AtProps.end(); I != E; ++I) {
+ SourceLocation AtLoc = SourceLocation::getFromRawEncoding(I->first);
+ IndivPropsTy &IndProps = I->second;
+ checkAllAtProps(MigrateCtx, AtLoc, IndProps);
+ }
+}
+
void GCAttrsTraverser::traverseTU(MigrationContext &MigrateCtx) {
- GCAttrsCollector(MigrateCtx).TraverseDecl(
+ std::vector<ObjCPropertyDecl *> AllProps;
+ GCAttrsCollector(MigrateCtx, AllProps).TraverseDecl(
MigrateCtx.Pass.Ctx.getTranslationUnitDecl());
clearRedundantStrongs(MigrateCtx);
errorForGCAttrsOnNonObjC(MigrateCtx);
checkWeakGCAttrs(MigrateCtx);
+ checkAllProps(MigrateCtx, AllProps);
}
void MigrationContext::dumpGCAttrs() {
Modified: cfe/trunk/lib/ARCMigrate/TransProperties.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransProperties.cpp?rev=143979&r1=143978&r2=143979&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransProperties.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransProperties.cpp Mon Nov 7 12:46:46 2011
@@ -44,6 +44,7 @@
namespace {
class PropertiesRewriter {
+ MigrationContext &MigrateCtx;
MigrationPass &Pass;
ObjCImplementationDecl *CurImplD;
@@ -51,7 +52,7 @@
PropAction_None,
PropAction_RetainToStrong,
PropAction_RetainRemoved,
- PropAction_AssignToStrong,
+ PropAction_AssignRemoved,
PropAction_AssignRewritten,
PropAction_MaybeAddStrong,
PropAction_MaybeAddWeakOrUnsafe
@@ -71,7 +72,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
};
-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());
}
Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=143979&r1=143978&r2=143979&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Mon Nov 7 12:46:46 2011
@@ -70,6 +70,9 @@
return false;
QualType T = type;
+ if (T.isNull())
+ return false;
+
while (const PointerType *ptr = T->getAs<PointerType>())
T = ptr->getPointeeType();
if (const ObjCObjectPointerType *ObjT = T->getAs<ObjCObjectPointerType>()) {
@@ -357,6 +360,90 @@
return false;
}
+bool MigrationContext::rewritePropertyAttribute(StringRef fromAttr,
+ StringRef toAttr,
+ SourceLocation atLoc) {
+ 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;
+}
+
void MigrationContext::traverse(TranslationUnitDecl *TU) {
for (traverser_iterator
I = traversers_begin(), E = traversers_end(); I != E; ++I)
Modified: cfe/trunk/lib/ARCMigrate/Transforms.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.h?rev=143979&r1=143978&r2=143979&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.h (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.h Mon Nov 7 12:46:46 2011
@@ -96,8 +96,9 @@
std::vector<GCAttrOccurrence> GCAttrs;
llvm::DenseSet<unsigned> AttrSet;
- /// \brief Map of property decl to the index in the GCAttrs vector.
- llvm::DenseMap<ObjCPropertyDecl *, unsigned> PropGCAttrs;
+ /// \brief Set of raw '@' locations for 'assign' properties group that contain
+ /// GC __weak.
+ llvm::DenseSet<unsigned> AtPropsWeak;
explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
~MigrationContext();
@@ -111,6 +112,8 @@
}
bool isGCOwnedNonObjC(QualType T);
+ bool rewritePropertyAttribute(StringRef fromAttr, StringRef toAttr,
+ SourceLocation atLoc);
void traverse(TranslationUnitDecl *TU);
Modified: cfe/trunk/test/ARCMT/GC.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/GC.m?rev=143979&r1=143978&r2=143979&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/GC.m (original)
+++ cfe/trunk/test/ARCMT/GC.m Mon Nov 7 12:46:46 2011
@@ -48,3 +48,22 @@
__weak QQ *q;
}
@end
+
+ at interface I3
+ at property (assign) I3 *__weak pw1, *__weak pw2;
+ at property (assign) I3 *__strong ps;
+ at property (assign) I3 * pds;
+ at end
+
+ at interface I4Impl {
+ I4Impl *pds2;
+}
+ at property (assign) I4Impl *__weak pw1, *__weak pw2;
+ at property (assign) I4Impl *__strong ps;
+ at property (assign) I4Impl * pds;
+ at property (assign) I4Impl * pds2;
+ at end
+
+ at implementation I4Impl
+ at synthesize pw1, pw2, ps, pds, pds2;
+ at end
Modified: cfe/trunk/test/ARCMT/GC.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/GC.m.result?rev=143979&r1=143978&r2=143979&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/GC.m.result (original)
+++ cfe/trunk/test/ARCMT/GC.m.result Mon Nov 7 12:46:46 2011
@@ -43,3 +43,22 @@
__unsafe_unretained QQ *q;
}
@end
+
+ at interface I3
+ at property (weak) I3 * pw1, * pw2;
+ at property (strong) I3 * ps;
+ at property (assign) I3 * pds;
+ at end
+
+ at interface I4Impl {
+ I4Impl *pds2;
+}
+ at property (weak) I4Impl * pw1, * pw2;
+ at property I4Impl * ps;
+ at property I4Impl * pds;
+ at property I4Impl * pds2;
+ at end
+
+ at implementation I4Impl
+ at synthesize pw1, pw2, ps, pds, pds2;
+ at end
More information about the cfe-commits
mailing list