[cfe-commits] r143883 - in /cfe/trunk/lib/ARCMigrate: CMakeLists.txt TransGCAttrs.cpp TransGCCalls.cpp TransProperties.cpp Transforms.cpp Transforms.h
Argyrios Kyrtzidis
akyrtzi at gmail.com
Sun Nov 6 10:58:03 PST 2011
Author: akirtzidis
Date: Sun Nov 6 12:58:03 2011
New Revision: 143883
URL: http://llvm.org/viewvc/llvm-project?rev=143883&view=rev
Log:
[arcmt] Collect all the places where GC attributes __strong/__weak occur.
Added:
cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
Modified:
cfe/trunk/lib/ARCMigrate/CMakeLists.txt
cfe/trunk/lib/ARCMigrate/TransGCCalls.cpp
cfe/trunk/lib/ARCMigrate/TransProperties.cpp
cfe/trunk/lib/ARCMigrate/Transforms.cpp
cfe/trunk/lib/ARCMigrate/Transforms.h
Modified: cfe/trunk/lib/ARCMigrate/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/CMakeLists.txt?rev=143883&r1=143882&r2=143883&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/CMakeLists.txt (original)
+++ cfe/trunk/lib/ARCMigrate/CMakeLists.txt Sun Nov 6 12:58:03 2011
@@ -12,6 +12,7 @@
TransEmptyStatementsAndDealloc.cpp
TransformActions.cpp
Transforms.cpp
+ TransGCAttrs.cpp
TransGCCalls.cpp
TransProperties.cpp
TransRetainReleaseDealloc.cpp
Added: cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp?rev=143883&view=auto
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp (added)
+++ cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp Sun Nov 6 12:58:03 2011
@@ -0,0 +1,191 @@
+//===--- TransGCAttrs.cpp - Transformations to ARC mode --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Transforms.h"
+#include "Internals.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Analysis/Support/SaveAndRestore.h"
+
+using namespace clang;
+using namespace arcmt;
+using namespace trans;
+
+namespace {
+
+/// \brief Collects all the places where GC attributes __strong/__weak occur.
+class GCAttrsCollector : public RecursiveASTVisitor<GCAttrsCollector> {
+ MigrationContext &MigrateCtx;
+ bool FullyMigratable;
+
+ typedef RecursiveASTVisitor<GCAttrsCollector> base;
+public:
+ explicit GCAttrsCollector(MigrationContext &ctx)
+ : MigrateCtx(ctx), FullyMigratable(false) { }
+
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+ bool VisitAttributedTypeLoc(AttributedTypeLoc TL) {
+ handleAttr(TL);
+ return true;
+ }
+
+ bool TraverseDecl(Decl *D) {
+ if (!D || D->isImplicit())
+ return true;
+
+ bool migratable = isMigratable(D);
+ SaveAndRestore<bool> Save(FullyMigratable, migratable);
+
+ if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
+ lookForAttribute(DD, DD->getTypeSourceInfo());
+ else if (ObjCPropertyDecl *PropD = dyn_cast<ObjCPropertyDecl>(D))
+ lookForAttribute(PropD, PropD->getTypeSourceInfo());
+ return base::TraverseDecl(D);
+ }
+
+ void lookForAttribute(Decl *D, TypeSourceInfo *TInfo) {
+ if (!TInfo)
+ return;
+ TypeLoc TL = TInfo->getTypeLoc();
+ while (TL) {
+ if (const AttributedTypeLoc *Attr = dyn_cast<AttributedTypeLoc>(&TL)) {
+ if (handleAttr(*Attr, D))
+ break;
+ TL = Attr->getModifiedLoc();
+ } if (const ArrayTypeLoc *Arr = dyn_cast<ArrayTypeLoc>(&TL)) {
+ TL = Arr->getElementLoc();
+ } else if (const PointerTypeLoc *PT = dyn_cast<PointerTypeLoc>(&TL)) {
+ TL = PT->getPointeeLoc();
+ } else if (const ReferenceTypeLoc *RT = dyn_cast<ReferenceTypeLoc>(&TL))
+ TL = RT->getPointeeLoc();
+ else
+ break;
+ }
+ }
+
+ bool handleAttr(AttributedTypeLoc TL, Decl *D = 0) {
+ if (TL.getAttrKind() != AttributedType::attr_objc_ownership)
+ return false;
+
+ SourceLocation Loc = TL.getAttrNameLoc();
+ unsigned RawLoc = Loc.getRawEncoding();
+ if (MigrateCtx.AttrSet.count(RawLoc))
+ return true;
+
+ ASTContext &Ctx = MigrateCtx.Pass.Ctx;
+ SourceManager &SM = Ctx.getSourceManager();
+ llvm::SmallString<32> Buf;
+ bool Invalid = false;
+ StringRef Spell = Lexer::getSpelling(
+ SM.getSpellingLoc(TL.getAttrEnumOperandLoc()),
+ Buf, SM, Ctx.getLangOptions(), &Invalid);
+ if (Invalid)
+ return false;
+ MigrationContext::GCAttrOccurrence::AttrKind Kind;
+ if (Spell == "strong")
+ Kind = MigrationContext::GCAttrOccurrence::Strong;
+ else if (Spell == "weak")
+ Kind = MigrationContext::GCAttrOccurrence::Weak;
+ else
+ return false;
+
+ MigrateCtx.AttrSet.insert(RawLoc);
+ MigrateCtx.GCAttrs.push_back(MigrationContext::GCAttrOccurrence());
+ MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs.back();
+
+ Attr.Kind = Kind;
+ Attr.Loc = Loc;
+ Attr.ModifiedType = TL.getModifiedLoc().getType();
+ Attr.Dcl = D;
+ Attr.FullyMigratable = FullyMigratable;
+ return true;
+ }
+
+ bool isMigratable(Decl *D) {
+ if (isa<TranslationUnitDecl>(D))
+ return false;
+
+ if (isInMainFile(D))
+ return true;
+
+ 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 (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ for (CXXRecordDecl::method_iterator
+ MI = RD->method_begin(), ME = RD->method_end(); MI != ME; ++MI) {
+ if ((*MI)->isOutOfLine())
+ return true;
+ }
+ return false;
+ }
+
+ return isMigratable(cast<Decl>(D->getDeclContext()));
+ }
+
+ bool isInMainFile(Decl *D) {
+ if (!D)
+ return false;
+
+ for (Decl::redecl_iterator
+ I = D->redecls_begin(), E = D->redecls_end(); I != E; ++I)
+ if (!isInMainFile((*I)->getLocation()))
+ return false;
+
+ return true;
+ }
+
+ bool isInMainFile(SourceLocation Loc) {
+ if (Loc.isInvalid())
+ return false;
+
+ SourceManager &SM = MigrateCtx.Pass.Ctx.getSourceManager();
+ return SM.isInFileID(SM.getExpansionLoc(Loc), SM.getMainFileID());
+ }
+};
+
+} // anonymous namespace
+
+void GCAttrsTraverser::traverseTU(MigrationContext &MigrateCtx) {
+ GCAttrsCollector(MigrateCtx).TraverseDecl(
+ MigrateCtx.Pass.Ctx.getTranslationUnitDecl());
+#if 0
+ llvm::errs() << "\n################\n";
+ for (unsigned i = 0, e = MigrateCtx.GCAttrs.size(); i != e; ++i) {
+ MigrationContext::GCAttrOccurrence &Attr = MigrateCtx.GCAttrs[i];
+ llvm::errs() << "KIND: "
+ << (Attr.Kind == MigrationContext::GCAttrOccurrence::Strong ? "strong"
+ : "weak");
+ llvm::errs() << "\nLOC: ";
+ Attr.Loc.dump(MigrateCtx.Pass.Ctx.getSourceManager());
+ llvm::errs() << "\nTYPE: ";
+ Attr.ModifiedType.dump();
+ if (Attr.Dcl) {
+ llvm::errs() << "DECL:\n";
+ Attr.Dcl->dump();
+ } else {
+ llvm::errs() << "DECL: NONE";
+ }
+ llvm::errs() << "\nMIGRATABLE: " << Attr.FullyMigratable;
+ llvm::errs() << "\n----------------\n";
+ }
+ llvm::errs() << "\n################\n";
+#endif
+}
Modified: cfe/trunk/lib/ARCMigrate/TransGCCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCCalls.cpp?rev=143883&r1=143882&r2=143883&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransGCCalls.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransGCCalls.cpp Sun Nov 6 12:58:03 2011
@@ -27,13 +27,15 @@
public:
GCCollectableCallsChecker(MigrationContext &ctx, ParentMap &map)
: MigrateCtx(ctx), PMap(map) {
- IdentifierTable &Ids = MigrateCtx.getPass().Ctx.Idents;
+ IdentifierTable &Ids = MigrateCtx.Pass.Ctx.Idents;
NSMakeCollectableII = &Ids.get("NSMakeCollectable");
CFMakeCollectableII = &Ids.get("CFMakeCollectable");
}
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
bool VisitCallExpr(CallExpr *E) {
- TransformActions &TA = MigrateCtx.getPass().TA;
+ TransformActions &TA = MigrateCtx.Pass.TA;
if (MigrateCtx.isGCOwnedNonObjC(E->getType())) {
TA.reportError("call returns pointer to GC managed memory; "
Modified: cfe/trunk/lib/ARCMigrate/TransProperties.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransProperties.cpp?rev=143883&r1=143882&r2=143883&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransProperties.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransProperties.cpp Sun Nov 6 12:58:03 2011
@@ -528,6 +528,6 @@
void PropertyRewriteTraverser::traverseObjCImplementation(
ObjCImplementationContext &ImplCtx) {
- PropertiesRewriter(ImplCtx.getMigrationContext().getPass())
+ PropertiesRewriter(ImplCtx.getMigrationContext().Pass)
.doTransform(ImplCtx.getImplementationDecl());
}
Modified: cfe/trunk/lib/ARCMigrate/Transforms.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.cpp?rev=143883&r1=143882&r2=143883&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.cpp Sun Nov 6 12:58:03 2011
@@ -302,6 +302,8 @@
public:
ASTTransform(MigrationContext &MigrateCtx) : MigrateCtx(MigrateCtx) { }
+ bool shouldWalkTypesOfTypeLocs() const { return false; }
+
bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
ObjCImplementationContext ImplCtx(MigrateCtx, D);
for (MigrationContext::traverser_iterator
@@ -355,6 +357,10 @@
}
void MigrationContext::traverse(TranslationUnitDecl *TU) {
+ for (traverser_iterator
+ I = traversers_begin(), E = traversers_end(); I != E; ++I)
+ (*I)->traverseTU(*this);
+
ASTTransform(*this).TraverseDecl(TU);
}
@@ -367,6 +373,7 @@
if (pass.isGCMigration()) {
MigrateCtx.addTraverser(new GCCollectableCallsTraverser);
+ MigrateCtx.addTraverser(new GCAttrsTraverser());
}
MigrateCtx.addTraverser(new PropertyRewriteTraverser());
Modified: cfe/trunk/lib/ARCMigrate/Transforms.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/Transforms.h?rev=143883&r1=143882&r2=143883&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/Transforms.h (original)
+++ cfe/trunk/lib/ARCMigrate/Transforms.h Sun Nov 6 12:58:03 2011
@@ -79,14 +79,26 @@
};
class MigrationContext {
- MigrationPass &Pass;
std::vector<ASTTraverser *> Traversers;
public:
+ MigrationPass &Pass;
+
+ struct GCAttrOccurrence {
+ enum AttrKind { Weak, Strong } Kind;
+ SourceLocation Loc;
+ QualType ModifiedType;
+ Decl *Dcl;
+ /// \brief true if the attribute is owned, e.g. it is in a body and not just
+ /// in an interface.
+ bool FullyMigratable;
+ };
+ std::vector<GCAttrOccurrence> GCAttrs;
+
+ llvm::DenseSet<unsigned> AttrSet;
+
explicit MigrationContext(MigrationPass &pass) : Pass(pass) {}
~MigrationContext();
-
- MigrationPass &getPass() { return Pass; }
typedef std::vector<ASTTraverser *>::iterator traverser_iterator;
traverser_iterator traversers_begin() { return Traversers.begin(); }
@@ -108,6 +120,11 @@
// GC transformations
+class GCAttrsTraverser : public ASTTraverser {
+public:
+ virtual void traverseTU(MigrationContext &MigrateCtx);
+};
+
class GCCollectableCallsTraverser : public ASTTraverser {
public:
virtual void traverseBody(BodyContext &BodyCtx);
More information about the cfe-commits
mailing list