[Objective-C migrator] replace candidate user setter/getter with
their equivalent property declaration. wip.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185873 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Edit/Commit.h b/include/clang/Edit/Commit.h
index 2a29642..0ff7034 100644
--- a/include/clang/Edit/Commit.h
+++ b/include/clang/Edit/Commit.h
@@ -13,6 +13,7 @@
 #include "clang/Edit/FileOffset.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
 
 namespace clang {
   class LangOptions;
@@ -51,6 +52,8 @@
 
   bool IsCommitable;
   SmallVector<Edit, 8> CachedEdits;
+  
+  llvm::BumpPtrAllocator StrAlloc;
 
 public:
   explicit Commit(EditedSource &Editor);
@@ -131,6 +134,12 @@
                                  SourceLocation *MacroBegin = 0) const;
   bool isAtEndOfMacroExpansion(SourceLocation loc,
                                SourceLocation *MacroEnd = 0) const;
+
+  StringRef copyString(StringRef str) {
+    char *buf = StrAlloc.Allocate<char>(str.size());
+    std::memcpy(buf, str.data(), str.size());
+    return StringRef(buf, str.size());
+  }
 };
 
 }
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index ec19f6e..d01dca4 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -212,7 +212,7 @@
         continue;
       const ParmVarDecl *argDecl = *SetterMethod->param_begin();
       QualType ArgType = argDecl->getType();
-      if (!Ctx.hasSameType(ArgType, GRT))
+      if (!Ctx.hasSameUnqualifiedType(ArgType, GRT))
           continue;
         edit::Commit commit(*Editor);
         edit::rewriteToObjCProperty(Method, SetterMethod, *NSAPIObj, commit);
diff --git a/lib/Edit/Commit.cpp b/lib/Edit/Commit.cpp
index 0b4ea3e..9c08cc2 100644
--- a/lib/Edit/Commit.cpp
+++ b/lib/Edit/Commit.cpp
@@ -183,7 +183,7 @@
   data.Kind = Act_Insert;
   data.OrigLoc = OrigLoc;
   data.Offset = Offs;
-  data.Text = text;
+  data.Text = copyString(text);
   data.BeforePrev = beforePreviousInsertions;
   CachedEdits.push_back(data);
 }
diff --git a/lib/Edit/RewriteObjCFoundationAPI.cpp b/lib/Edit/RewriteObjCFoundationAPI.cpp
index 9af5303..05abbed 100644
--- a/lib/Edit/RewriteObjCFoundationAPI.cpp
+++ b/lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -358,7 +358,33 @@
 bool edit::rewriteToObjCProperty(const ObjCMethodDecl *Getter,
                                  const ObjCMethodDecl *Setter,
                                  const NSAPI &NS, Commit &commit) {
-  return false;
+  std::string PropertyString = "@property";
+  const ParmVarDecl *argDecl = *Setter->param_begin();
+  QualType ArgType = argDecl->getType();
+  Qualifiers::ObjCLifetime propertyLifetime = ArgType.getObjCLifetime();
+  if (propertyLifetime != Qualifiers::OCL_None) {
+    PropertyString += "(";
+    if (propertyLifetime == Qualifiers::OCL_Strong)
+      PropertyString += "strong";
+    else if (propertyLifetime == Qualifiers::OCL_Weak)
+      PropertyString += "weak";
+    else
+      PropertyString += "unsafe_unretained";
+    PropertyString += ")";
+  }
+  QualType PropQT = Getter->getResultType();
+  PropertyString += " ";
+  PropertyString += PropQT.getAsString(NS.getASTContext().getPrintingPolicy());
+  PropertyString += " ";
+  PropertyString += Getter->getNameAsString();
+  commit.replace(CharSourceRange::getCharRange(Getter->getLocStart(),
+                                               Getter->getDeclaratorEndLoc()),
+                 PropertyString);
+  SourceLocation EndLoc = Setter->getDeclaratorEndLoc();
+  // Get location past ';'
+  EndLoc = EndLoc.getLocWithOffset(1);
+  commit.remove(CharSourceRange::getCharRange(Setter->getLocStart(), EndLoc));
+  return true;
 }
 
 /// \brief Returns true if the immediate message arguments of \c Msg should not
diff --git a/test/ARCMT/objcmt-property.m b/test/ARCMT/objcmt-property.m
new file mode 100644
index 0000000..f2d5e1a
--- /dev/null
+++ b/test/ARCMT/objcmt-property.m
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result
+
+@class NSString;
+@interface NSObject @end
+
+@interface I : NSObject {
+  int ivarVal;
+}
+- (void) setWeakProp : (NSString *__weak)Val;
+- (NSString *__weak) WeakProp;
+
+- (NSString *) StrongProp;
+- (void) setStrongProp : (NSString *)Val;
+@end
+
+@implementation I
+@end
diff --git a/test/ARCMT/objcmt-property.m.result b/test/ARCMT/objcmt-property.m.result
new file mode 100644
index 0000000..87b71e1
--- /dev/null
+++ b/test/ARCMT/objcmt-property.m.result
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties -triple x86_64-apple-darwin11
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -x objective-c -fobjc-runtime-has-weak -fobjc-arc -fobjc-default-synthesize-properties %s.result
+
+@class NSString;
+@interface NSObject @end
+
+@interface I : NSObject {
+  int ivarVal;
+}
+
+@property(weak) NSString *__weak WeakProp;
+
+@property(strong) NSString * StrongProp;
+
+@end
+
+@implementation I
+@end