[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