[cfe-commits] r152141 - in /cfe/trunk: include/clang-c/ include/clang/ARCMigrate/ include/clang/Basic/ include/clang/Driver/ include/clang/Edit/ include/clang/Frontend/ include/clang/Rewrite/ lib/ lib/ARCMigrate/ lib/Basic/ lib/Driver/ lib/Edit/ lib/Frontend/ lib/FrontendTool/ lib/Rewrite/ test/ARCMT/ tools/arcmt-test/ tools/c-arcmt-test/ tools/driver/ tools/libclang/ unittests/Frontend/ unittests/Lex/

Ted Kremenek kremenek at apple.com
Tue Mar 6 12:06:34 PST 2012


Author: kremenek
Date: Tue Mar  6 14:06:33 2012
New Revision: 152141

URL: http://llvm.org/viewvc/llvm-project?rev=152141&view=rev
Log:
Add new code migrator support for migrating existing Objective-C code to use
the new Objective-C NSArray/NSDictionary/NSNumber literal syntax.

This introduces a new library, libEdit, which provides a new way to support
migration of code that improves on the original ARC migrator.  We now believe
that most of its functionality can be refactored into the existing libraries,
and thus this new library may shortly disappear.

Added:
    cfe/trunk/include/clang/Edit/
    cfe/trunk/include/clang/Edit/Commit.h
    cfe/trunk/include/clang/Edit/EditedSource.h
    cfe/trunk/include/clang/Edit/EditsReceiver.h
    cfe/trunk/include/clang/Edit/FileOffset.h
    cfe/trunk/include/clang/Edit/Rewriters.h
    cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
    cfe/trunk/lib/Edit/
    cfe/trunk/lib/Edit/CMakeLists.txt
    cfe/trunk/lib/Edit/Commit.cpp
    cfe/trunk/lib/Edit/EditedSource.cpp
    cfe/trunk/lib/Edit/Makefile   (contents, props changed)
      - copied, changed from r152140, cfe/trunk/lib/Makefile
    cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp
    cfe/trunk/test/ARCMT/dispatch.m
    cfe/trunk/test/ARCMT/dispatch.m.result
    cfe/trunk/test/ARCMT/objcmt-numeric-literals.m
    cfe/trunk/test/ARCMT/objcmt-numeric-literals.m.result
    cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m
    cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result
Modified:
    cfe/trunk/include/clang-c/Index.h
    cfe/trunk/include/clang/ARCMigrate/ARCMT.h
    cfe/trunk/include/clang/ARCMigrate/ARCMTActions.h
    cfe/trunk/include/clang/ARCMigrate/FileRemapper.h
    cfe/trunk/include/clang/Basic/Diagnostic.h
    cfe/trunk/include/clang/Driver/Action.h
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Driver/Types.def
    cfe/trunk/include/clang/Frontend/FrontendOptions.h
    cfe/trunk/include/clang/Rewrite/FixItRewriter.h
    cfe/trunk/lib/ARCMigrate/ARCMT.cpp
    cfe/trunk/lib/ARCMigrate/CMakeLists.txt
    cfe/trunk/lib/ARCMigrate/FileRemapper.cpp
    cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
    cfe/trunk/lib/Basic/DiagnosticIDs.cpp
    cfe/trunk/lib/CMakeLists.txt
    cfe/trunk/lib/Driver/Action.cpp
    cfe/trunk/lib/Driver/Driver.cpp
    cfe/trunk/lib/Driver/ToolChain.cpp
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Driver/WindowsToolChain.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
    cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
    cfe/trunk/lib/Makefile
    cfe/trunk/lib/Rewrite/FixItRewriter.cpp
    cfe/trunk/test/ARCMT/driver-migrate.m
    cfe/trunk/test/ARCMT/migrate-emit-errors.m
    cfe/trunk/test/ARCMT/migrate-plist-output.m
    cfe/trunk/test/ARCMT/migrate-space-in-path.m
    cfe/trunk/test/ARCMT/migrate.m
    cfe/trunk/test/ARCMT/with-arc-mode-migrate.m
    cfe/trunk/test/ARCMT/with-arc-mode-migrate.m.result
    cfe/trunk/tools/arcmt-test/CMakeLists.txt
    cfe/trunk/tools/arcmt-test/Makefile
    cfe/trunk/tools/arcmt-test/arcmt-test.cpp
    cfe/trunk/tools/c-arcmt-test/c-arcmt-test.c
    cfe/trunk/tools/driver/CMakeLists.txt
    cfe/trunk/tools/driver/Makefile
    cfe/trunk/tools/libclang/ARCMigrate.cpp
    cfe/trunk/tools/libclang/CMakeLists.txt
    cfe/trunk/tools/libclang/Makefile
    cfe/trunk/tools/libclang/libclang.exports
    cfe/trunk/unittests/Frontend/Makefile
    cfe/trunk/unittests/Lex/LexerTest.cpp

Modified: cfe/trunk/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang-c/Index.h (original)
+++ cfe/trunk/include/clang-c/Index.h Tue Mar  6 14:06:33 2012
@@ -3983,6 +3983,20 @@
 CINDEX_LINKAGE CXRemapping clang_getRemappings(const char *path);
 
 /**
+ * \brief Retrieve a remapping.
+ *
+ * \param filePaths pointer to an array of file paths containing remapping info.
+ *
+ * \param numFiles number of file paths.
+ *
+ * \returns the requested remapping. This remapping must be freed
+ * via a call to \c clang_remap_dispose(). Can return NULL if an error occurred.
+ */
+CINDEX_LINKAGE
+CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
+                                            unsigned numFiles);
+
+/**
  * \brief Determine the number of remappings.
  */
 CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping);

Modified: cfe/trunk/include/clang/ARCMigrate/ARCMT.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ARCMigrate/ARCMT.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/ARCMigrate/ARCMT.h (original)
+++ cfe/trunk/include/clang/ARCMigrate/ARCMT.h Tue Mar  6 14:06:33 2012
@@ -76,6 +76,15 @@
                        StringRef outputDir,
                        DiagnosticConsumer *DiagClient);
 
+/// \brief Get the set of file remappings from a list of files with remapping
+/// info.
+///
+/// \returns false if no error is produced, true otherwise.
+bool getFileRemappingsFromFileList(
+                        std::vector<std::pair<std::string,std::string> > &remap,
+                        ArrayRef<StringRef> remapFiles,
+                        DiagnosticConsumer *DiagClient);
+
 typedef void (*TransformFn)(MigrationPass &pass);
 
 std::vector<TransformFn> getAllTransformations(LangOptions::GCMode OrigGCMode,

Modified: cfe/trunk/include/clang/ARCMigrate/ARCMTActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ARCMigrate/ARCMTActions.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/ARCMigrate/ARCMTActions.h (original)
+++ cfe/trunk/include/clang/ARCMigrate/ARCMTActions.h Tue Mar  6 14:06:33 2012
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_ARCMIGRATE_ARCMT_ACTION_H
 
 #include "clang/Frontend/FrontendAction.h"
+#include "clang/ARCMigrate/FileRemapper.h"
 #include "llvm/ADT/OwningPtr.h"
 
 namespace clang {
@@ -32,6 +33,14 @@
   ModifyAction(FrontendAction *WrappedAction);
 };
 
+class MigrateSourceAction : public ASTFrontendAction {
+  FileRemapper Remapper;
+protected:
+  virtual bool BeginInvocation(CompilerInstance &CI);
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile);
+};
+
 class MigrateAction : public WrapperFrontendAction {
   std::string MigrateDir;
   std::string PlistOut;
@@ -45,6 +54,23 @@
                 bool emitPremigrationARCErrors);
 };
 
+/// \brief Migrates to modern ObjC syntax.
+class ObjCMigrateAction : public WrapperFrontendAction {
+  std::string MigrateDir;
+  bool MigrateLiterals;
+  bool MigrateSubscripting;
+  FileRemapper Remapper;
+  CompilerInstance *CompInst;
+public:
+  ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir,
+                    bool migrateLiterals,
+                    bool migrateSubscripting);
+
+protected:
+  virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,StringRef InFile);
+  virtual bool BeginInvocation(CompilerInstance &CI);
+};
+
 }
 }
 

Modified: cfe/trunk/include/clang/ARCMigrate/FileRemapper.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ARCMigrate/FileRemapper.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/ARCMigrate/FileRemapper.h (original)
+++ cfe/trunk/include/clang/ARCMigrate/FileRemapper.h Tue Mar  6 14:06:33 2012
@@ -24,7 +24,7 @@
   class FileManager;
   class FileEntry;
   class DiagnosticsEngine;
-  class CompilerInvocation;
+  class PreprocessorOptions;
 
 namespace arcmt {
 
@@ -44,7 +44,10 @@
   
   bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
                     bool ignoreIfFilesChanged);
+  bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
+                    bool ignoreIfFilesChanged);
   bool flushToDisk(StringRef outputDir, DiagnosticsEngine &Diag);
+  bool flushToFile(StringRef outputPath, DiagnosticsEngine &Diag);
 
   bool overwriteOriginal(DiagnosticsEngine &Diag,
                          StringRef outputDir = StringRef());
@@ -52,9 +55,9 @@
   void remap(StringRef filePath, llvm::MemoryBuffer *memBuf);
   void remap(StringRef filePath, StringRef newPath);
 
-  void applyMappings(CompilerInvocation &CI) const;
+  void applyMappings(PreprocessorOptions &PPOpts) const;
 
-  void transferMappingsAndClear(CompilerInvocation &CI);
+  void transferMappingsAndClear(PreprocessorOptions &PPOpts);
 
   void clear(StringRef outputDir = StringRef());
 

Modified: cfe/trunk/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Diagnostic.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Diagnostic.h (original)
+++ cfe/trunk/include/clang/Basic/Diagnostic.h Tue Mar  6 14:06:33 2012
@@ -50,13 +50,19 @@
   /// insertion hint.
   CharSourceRange RemoveRange;
 
+  /// \brief Code in the specific range that should be inserted in the insertion
+  /// location.
+  CharSourceRange InsertFromRange;
+
   /// \brief The actual code to insert at the insertion location, as a
   /// string.
   std::string CodeToInsert;
 
+  bool BeforePreviousInsertions;
+
   /// \brief Empty code modification hint, indicating that no code
   /// modification is known.
-  FixItHint() : RemoveRange() { }
+  FixItHint() : BeforePreviousInsertions(false) { }
 
   bool isNull() const {
     return !RemoveRange.isValid();
@@ -65,11 +71,26 @@
   /// \brief Create a code modification hint that inserts the given
   /// code string at a specific location.
   static FixItHint CreateInsertion(SourceLocation InsertionLoc,
-                                   StringRef Code) {
+                                   StringRef Code,
+                                   bool BeforePreviousInsertions = false) {
     FixItHint Hint;
     Hint.RemoveRange =
       CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
     Hint.CodeToInsert = Code;
+    Hint.BeforePreviousInsertions = BeforePreviousInsertions;
+    return Hint;
+  }
+  
+  /// \brief Create a code modification hint that inserts the given
+  /// code from \arg FromRange at a specific location.
+  static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc,
+                                            CharSourceRange FromRange,
+                                        bool BeforePreviousInsertions = false) {
+    FixItHint Hint;
+    Hint.RemoveRange =
+      CharSourceRange(SourceRange(InsertionLoc, InsertionLoc), false);
+    Hint.InsertFromRange = FromRange;
+    Hint.BeforePreviousInsertions = BeforePreviousInsertions;
     return Hint;
   }
 

Modified: cfe/trunk/include/clang/Driver/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Action.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Action.h (original)
+++ cfe/trunk/include/clang/Driver/Action.h Tue Mar  6 14:06:33 2012
@@ -39,6 +39,7 @@
     PreprocessJobClass,
     PrecompileJobClass,
     AnalyzeJobClass,
+    MigrateJobClass,
     CompileJobClass,
     AssembleJobClass,
     LinkJobClass,
@@ -171,6 +172,17 @@
   static bool classof(const AnalyzeJobAction *) { return true; }
 };
 
+class MigrateJobAction : public JobAction {
+  virtual void anchor();
+public:
+  MigrateJobAction(Action *Input, types::ID OutputType);
+
+  static bool classof(const Action *A) {
+    return A->getKind() == MigrateJobClass;
+  }
+  static bool classof(const MigrateJobAction *) { return true; }
+};
+
 class CompileJobAction : public JobAction {
   virtual void anchor();
 public:

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Tue Mar  6 14:06:33 2012
@@ -433,21 +433,28 @@
   HelpText<"Rewrite ObjC into C (code rewriter example)">;
 def rewrite_macros : Flag<"-rewrite-macros">,
   HelpText<"Expand macros without full preprocessing">;
+def migrate : Flag<"-migrate">,
+  HelpText<"Migrate source code">;
 }
 
+def mt_migrate_directory : Separate<"-mt-migrate-directory">,
+  HelpText<"Directory for temporary files produced during ARC or ObjC migration">;
 def arcmt_check : Flag<"-arcmt-check">,
   HelpText<"Check for ARC migration issues that need manual handling">;
 def arcmt_modify : Flag<"-arcmt-modify">,
   HelpText<"Apply modifications to files to conform to ARC">;
 def arcmt_migrate : Flag<"-arcmt-migrate">,
   HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-def arcmt_migrate_directory : Separate<"-arcmt-migrate-directory">,
-  HelpText<"Directory for temporary files produced during ARC migration">;
 def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">,
   HelpText<"Output path for the plist report">;
 def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">,
   HelpText<"Emit ARC errors even if the migrator can fix them">;
 
+def objcmt_migrate_literals : Flag<"-objcmt-migrate-literals">,
+  HelpText<"Enable migration to modern ObjC literals">;
+def objcmt_migrate_subscripting : Flag<"-objcmt-migrate-subscripting">,
+  HelpText<"Enable migration to modern ObjC subscripting">;
+
 def working_directory : JoinedOrSeparate<"-working-directory">,
   HelpText<"Resolve file paths relative to the specified directory">;
 def working_directory_EQ : Joined<"-working-directory=">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Tue Mar  6 14:06:33 2012
@@ -118,13 +118,21 @@
 def ccc_arrmt_modify : Flag<"-ccc-arrmt-modify">, Alias<ccc_arcmt_modify>;
 def ccc_arcmt_migrate : Separate<"-ccc-arcmt-migrate">, CCCDriverOpt,
   HelpText<"Apply modifications and produces temporary files that conform to ARC">;
-def ccc_arcmt_migrate_EQ : Joined<"-ccc-arcmt-migrate=">, CCCDriverOpt,
-  Alias<ccc_arcmt_migrate>;
 def arcmt_migrate_report_output : Separate<"-arcmt-migrate-report-output">,
   HelpText<"Output path for the plist report">;
 def arcmt_migrate_emit_arc_errors : Flag<"-arcmt-migrate-emit-errors">,
   HelpText<"Emit ARC errors even if the migrator can fix them">;
 
+def _migrate : Flag<"--migrate">, Flags<[DriverOption]>,
+  HelpText<"Run the migrator">;
+def ccc_objcmt_migrate : Separate<"-ccc-objcmt-migrate">, CCCDriverOpt,
+  HelpText<"Apply modifications and produces temporary files to migrate to "
+   "modern ObjC syntax">;
+def objcmt_migrate_literals : Flag<"-objcmt-migrate-literals">,
+  HelpText<"Enable migration to modern ObjC literals">;
+def objcmt_migrate_subscripting : Flag<"-objcmt-migrate-subscripting">,
+  HelpText<"Enable migration to modern ObjC subscripting">;
+
 // Make sure all other -ccc- options are rejected.
 def ccc_ : Joined<"-ccc-">, Group<ccc_Group>, Flags<[Unsupported]>;
 

Modified: cfe/trunk/include/clang/Driver/Types.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Types.def?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Types.def (original)
+++ cfe/trunk/include/clang/Driver/Types.def Tue Mar  6 14:06:33 2012
@@ -82,6 +82,7 @@
 TYPE("ast",                      AST,          INVALID,         "ast",   "u")
 TYPE("plist",                    Plist,        INVALID,         "plist", "")
 TYPE("rewritten-objc",           RewrittenObjC,INVALID,         "cpp",   "")
+TYPE("remap",                    Remap,        INVALID,         "remap", "")
 TYPE("precompiled-header",       PCH,          INVALID,         "gch",   "A")
 TYPE("object",                   Object,       INVALID,         "o",     "")
 TYPE("treelang",                 Treelang,     INVALID,         0,       "u")

Added: cfe/trunk/include/clang/Edit/Commit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Edit/Commit.h?rev=152141&view=auto
==============================================================================
--- cfe/trunk/include/clang/Edit/Commit.h (added)
+++ cfe/trunk/include/clang/Edit/Commit.h Tue Mar  6 14:06:33 2012
@@ -0,0 +1,140 @@
+//===----- Commit.h - A unit of edits ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_COMMIT_H
+#define LLVM_CLANG_EDIT_COMMIT_H
+
+#include "clang/Edit/FileOffset.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+  class LangOptions;
+  class PreprocessingRecord;
+
+namespace edit {
+  class EditedSource;
+
+class Commit {
+public:
+  enum EditKind {
+    Act_Insert,
+    Act_InsertFromRange,
+    Act_Remove
+  };
+
+  struct Edit {
+    EditKind Kind;
+    StringRef Text;
+    SourceLocation OrigLoc;
+    FileOffset Offset;
+    FileOffset InsertFromRangeOffs;
+    unsigned Length;
+    bool BeforePrev;
+
+    SourceLocation getFileLocation(SourceManager &SM) const;
+    CharSourceRange getFileRange(SourceManager &SM) const;
+    CharSourceRange getInsertFromRange(SourceManager &SM) const;
+  };
+
+private:
+  const SourceManager &SourceMgr;
+  const LangOptions &LangOpts;
+  const PreprocessingRecord *PPRec;
+  EditedSource *Editor;
+
+  bool IsCommitable;
+  SmallVector<Edit, 8> CachedEdits;
+
+public:
+  explicit Commit(EditedSource &Editor);
+  Commit(const SourceManager &SM, const LangOptions &LangOpts,
+         const PreprocessingRecord *PPRec = 0)
+    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), Editor(0),
+      IsCommitable(true) { }
+
+  bool isCommitable() const { return IsCommitable; }
+
+  bool insert(SourceLocation loc, StringRef text, bool afterToken = false,
+              bool beforePreviousInsertions = false);
+  bool insertAfterToken(SourceLocation loc, StringRef text,
+                        bool beforePreviousInsertions = false) {
+    return insert(loc, text, /*afterToken=*/true, beforePreviousInsertions);
+  }
+  bool insertBefore(SourceLocation loc, StringRef text) {
+    return insert(loc, text, /*afterToken=*/false,
+                  /*beforePreviousInsertions=*/true);
+  }
+  bool insertFromRange(SourceLocation loc, CharSourceRange range,
+                       bool afterToken = false,
+                       bool beforePreviousInsertions = false);
+  bool insertWrap(StringRef before, CharSourceRange range, StringRef after);
+
+  bool remove(CharSourceRange range);
+
+  bool replace(CharSourceRange range, StringRef text);
+  bool replaceWithInner(CharSourceRange range, CharSourceRange innerRange);
+  bool replaceText(SourceLocation loc, StringRef text,
+                   StringRef replacementText);
+
+  bool insertFromRange(SourceLocation loc, SourceRange TokenRange,
+                       bool afterToken = false,
+                       bool beforePreviousInsertions = false) {
+    return insertFromRange(loc, CharSourceRange::getTokenRange(TokenRange),
+                           afterToken, beforePreviousInsertions);
+  }
+  bool insertWrap(StringRef before, SourceRange TokenRange, StringRef after) {
+    return insertWrap(before, CharSourceRange::getTokenRange(TokenRange), after);
+  }
+  bool remove(SourceRange TokenRange) {
+    return remove(CharSourceRange::getTokenRange(TokenRange));
+  }
+  bool replace(SourceRange TokenRange, StringRef text) {
+    return replace(CharSourceRange::getTokenRange(TokenRange), text);
+  }
+  bool replaceWithInner(SourceRange TokenRange, SourceRange TokenInnerRange) {
+    return replaceWithInner(CharSourceRange::getTokenRange(TokenRange),
+                            CharSourceRange::getTokenRange(TokenInnerRange));
+  }
+
+  typedef SmallVector<Edit, 8>::const_iterator edit_iterator;
+  edit_iterator edit_begin() const { return CachedEdits.begin(); }
+  edit_iterator edit_end() const { return CachedEdits.end(); }
+
+private:
+  void addInsert(SourceLocation OrigLoc,
+                FileOffset Offs, StringRef text, bool beforePreviousInsertions);
+  void addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+                          FileOffset RangeOffs, unsigned RangeLen,
+                          bool beforePreviousInsertions);
+  void addRemove(SourceLocation OrigLoc, FileOffset Offs, unsigned Len);
+
+  bool canInsert(SourceLocation loc, FileOffset &Offset);
+  bool canInsertAfterToken(SourceLocation loc, FileOffset &Offset,
+                           SourceLocation &AfterLoc);
+  bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
+  bool canRemoveRange(CharSourceRange range, FileOffset &Offs, unsigned &Len);
+  bool canReplaceText(SourceLocation loc, StringRef text,
+                      FileOffset &Offs, unsigned &Len);
+
+  void commitInsert(FileOffset offset, StringRef text,
+                    bool beforePreviousInsertions);
+  void commitRemove(FileOffset offset, unsigned length);
+
+  bool isAtStartOfMacroExpansion(SourceLocation loc,
+                                 SourceLocation *MacroBegin = 0) const;
+  bool isAtEndOfMacroExpansion(SourceLocation loc,
+                               SourceLocation *MacroEnd = 0) const;
+};
+
+}
+
+} // end namespace clang
+
+#endif

Added: cfe/trunk/include/clang/Edit/EditedSource.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Edit/EditedSource.h?rev=152141&view=auto
==============================================================================
--- cfe/trunk/include/clang/Edit/EditedSource.h (added)
+++ cfe/trunk/include/clang/Edit/EditedSource.h Tue Mar  6 14:06:33 2012
@@ -0,0 +1,87 @@
+//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H
+#define LLVM_CLANG_EDIT_EDITEDSOURCE_H
+
+#include "clang/Edit/FileOffset.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include <map>
+
+namespace clang {
+  class LangOptions;
+  class PreprocessingRecord;
+
+namespace edit {
+  class Commit;
+  class EditsReceiver;
+
+class EditedSource {
+  const SourceManager &SourceMgr;
+  const LangOptions &LangOpts;
+  const PreprocessingRecord *PPRec;
+
+  struct FileEdit {
+    StringRef Text;
+    unsigned RemoveLen;
+
+    FileEdit() : RemoveLen(0) {}
+  };
+
+  typedef std::map<FileOffset, FileEdit> FileEditsTy;
+  FileEditsTy FileEdits;
+
+  llvm::DenseMap<unsigned, SourceLocation> ExpansionToArgMap;
+
+  llvm::BumpPtrAllocator StrAlloc;
+
+public:
+  EditedSource(const SourceManager &SM, const LangOptions &LangOpts,
+               const PreprocessingRecord *PPRec = 0)
+    : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec),
+      StrAlloc(/*size=*/512) { }
+
+  const SourceManager &getSourceManager() const { return SourceMgr; }
+  const LangOptions &getLangOptions() const { return LangOpts; }
+  const PreprocessingRecord *getPreprocessingRecord() const { return PPRec; }
+
+  bool canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs);
+
+  bool commit(const Commit &commit);
+  
+  void applyRewrites(EditsReceiver &receiver);
+  void clearRewrites();
+
+  StringRef copyString(StringRef str) {
+    char *buf = StrAlloc.Allocate<char>(str.size());
+    std::uninitialized_copy(str.begin(), str.end(), buf);
+    return StringRef(buf, str.size());
+  }
+  StringRef copyString(const Twine &twine);
+
+private:
+  bool commitInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text,
+                    bool beforePreviousInsertions);
+  bool commitInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+                             FileOffset InsertFromRangeOffs, unsigned Len,
+                             bool beforePreviousInsertions);
+  void commitRemove(SourceLocation OrigLoc, FileOffset BeginOffs, unsigned Len);
+
+  StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
+                          bool &Invalid);
+  FileEditsTy::iterator getActionForOffset(FileOffset Offs);
+};
+
+}
+
+} // end namespace clang
+
+#endif

Added: cfe/trunk/include/clang/Edit/EditsReceiver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Edit/EditsReceiver.h?rev=152141&view=auto
==============================================================================
--- cfe/trunk/include/clang/Edit/EditsReceiver.h (added)
+++ cfe/trunk/include/clang/Edit/EditsReceiver.h Tue Mar  6 14:06:33 2012
@@ -0,0 +1,35 @@
+//===----- EditedSource.h - Collection of source edits ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_EDITSRECEIVER_H
+#define LLVM_CLANG_EDIT_EDITSRECEIVER_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+  class SourceLocation;
+  class CharSourceRange;
+
+namespace edit {
+
+class EditsReceiver {
+public:
+  virtual ~EditsReceiver() { }
+
+  virtual void insert(SourceLocation loc, StringRef text) = 0;
+  virtual void replace(CharSourceRange range, StringRef text) = 0;
+  /// \brief By default it calls replace with an empty string.
+  virtual void remove(CharSourceRange range);
+};
+
+}
+
+} // end namespace clang
+
+#endif

Added: cfe/trunk/include/clang/Edit/FileOffset.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Edit/FileOffset.h?rev=152141&view=auto
==============================================================================
--- cfe/trunk/include/clang/Edit/FileOffset.h (added)
+++ cfe/trunk/include/clang/Edit/FileOffset.h Tue Mar  6 14:06:33 2012
@@ -0,0 +1,65 @@
+//===----- FileOffset.h - Offset in a file ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_FILEOFFSET_H
+#define LLVM_CLANG_EDIT_FILEOFFSET_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+namespace edit {
+
+class FileOffset {
+  FileID FID;
+  unsigned Offs;
+public:
+  FileOffset() : Offs(0) { }
+  FileOffset(FileID fid, unsigned offs) : FID(fid), Offs(offs) { }
+
+  bool isInvalid() const { return FID.isInvalid(); }
+
+  FileID getFID() const { return FID; }
+  unsigned getOffset() const { return Offs; }
+
+  FileOffset getWithOffset(unsigned offset) const {
+    FileOffset NewOffs = *this;
+    NewOffs.Offs += offset;
+    return NewOffs;
+  }
+
+  friend bool operator==(FileOffset LHS, FileOffset RHS) {
+    return LHS.FID == RHS.FID && LHS.Offs == RHS.Offs;
+  }
+  friend bool operator!=(FileOffset LHS, FileOffset RHS) {
+    return !(LHS == RHS);
+  }
+  friend bool operator<(FileOffset LHS, FileOffset RHS) {
+    if (LHS.FID != RHS.FID)
+      return LHS.FID < RHS.FID;
+    return LHS.Offs < RHS.Offs;
+  }
+  friend bool operator>(FileOffset LHS, FileOffset RHS) {
+    if (LHS.FID != RHS.FID)
+      return LHS.FID > RHS.FID;
+    return LHS.Offs > RHS.Offs;
+  }
+  friend bool operator>=(FileOffset LHS, FileOffset RHS) {
+    return LHS > RHS || LHS == RHS;
+  }
+  friend bool operator<=(FileOffset LHS, FileOffset RHS) {
+    return LHS < RHS || LHS == RHS;
+  }
+};
+
+}
+
+} // end namespace clang
+
+#endif

Added: cfe/trunk/include/clang/Edit/Rewriters.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Edit/Rewriters.h?rev=152141&view=auto
==============================================================================
--- cfe/trunk/include/clang/Edit/Rewriters.h (added)
+++ cfe/trunk/include/clang/Edit/Rewriters.h Tue Mar  6 14:06:33 2012
@@ -0,0 +1,33 @@
+//===--- Rewriters.h - Rewritings     ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_EDIT_REWRITERS_H
+#define LLVM_CLANG_EDIT_REWRITERS_H
+
+namespace clang {
+  class ObjCMessageExpr;
+  class NSAPI;
+
+namespace edit {
+  class Commit;
+
+bool rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
+                                         const NSAPI &NS, Commit &commit);
+
+bool rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
+                                const NSAPI &NS, Commit &commit);
+
+bool rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
+                                  const NSAPI &NS, Commit &commit);
+
+}
+
+}  // end namespace clang
+
+#endif

Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Tue Mar  6 14:06:33 2012
@@ -46,6 +46,7 @@
     RewriteObjC,            ///< ObjC->C Rewriter.
     RewriteTest,            ///< Rewriter playground
     RunAnalysis,            ///< Run one or more source code analyses.
+    MigrateSource,          ///< Run migrator.
     RunPreprocessorOnly     ///< Just lex, no output.
   };
 }
@@ -118,7 +119,16 @@
     ARCMT_Migrate
   } ARCMTAction;
 
-  std::string ARCMTMigrateDir;
+  enum {
+    ObjCMT_None = 0,
+    /// \brief Enable migration to modern ObjC literals.
+    ObjCMT_Literals = 0x1,
+    /// \brief Enable migration to modern ObjC subscripting.
+    ObjCMT_Subscripting = 0x2
+  };
+  unsigned ObjCMTAction;
+
+  std::string MTMigrateDir;
   std::string ARCMTMigrateReportOut;
 
   /// The input files and their types.
@@ -177,6 +187,7 @@
     ShowVersion = 0;
     ARCMTAction = ARCMT_None;
     ARCMTMigrateEmitARCErrors = 0;
+    ObjCMTAction = ObjCMT_None;
   }
 
   /// getInputKindForExtension - Return the appropriate input kind for a file

Modified: cfe/trunk/include/clang/Rewrite/FixItRewriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/FixItRewriter.h?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/include/clang/Rewrite/FixItRewriter.h (original)
+++ cfe/trunk/include/clang/Rewrite/FixItRewriter.h Tue Mar  6 14:06:33 2012
@@ -18,6 +18,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Rewrite/Rewriter.h"
+#include "clang/Edit/EditedSource.h"
 
 namespace clang {
 
@@ -56,6 +57,8 @@
   /// \brief The diagnostics machinery.
   DiagnosticsEngine &Diags;
 
+  edit::EditedSource Editor;
+
   /// \brief The rewriter used to perform the various code
   /// modifications.
   Rewriter Rewrite;

Modified: cfe/trunk/lib/ARCMigrate/ARCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ARCMT.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ARCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ARCMT.cpp Tue Mar  6 14:06:33 2012
@@ -398,13 +398,51 @@
   if (err)
     return true;
 
-  CompilerInvocation CI;
-  remapper.applyMappings(CI);
-  remap = CI.getPreprocessorOpts().RemappedFiles;
+  PreprocessorOptions PPOpts;
+  remapper.applyMappings(PPOpts);
+  remap = PPOpts.RemappedFiles;
 
   return false;
 }
 
+bool arcmt::getFileRemappingsFromFileList(
+                        std::vector<std::pair<std::string,std::string> > &remap,
+                        ArrayRef<StringRef> remapFiles,
+                        DiagnosticConsumer *DiagClient) {
+  bool hasErrorOccurred = false;
+  llvm::StringMap<bool> Uniquer;
+
+  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
+      new DiagnosticsEngine(DiagID, DiagClient, /*ShouldOwnClient=*/false));
+
+  for (ArrayRef<StringRef>::iterator
+         I = remapFiles.begin(), E = remapFiles.end(); I != E; ++I) {
+    StringRef file = *I;
+
+    FileRemapper remapper;
+    bool err = remapper.initFromFile(file, *Diags,
+                                     /*ignoreIfFilesChanged=*/true);
+    hasErrorOccurred = hasErrorOccurred || err;
+    if (err)
+      continue;
+
+    PreprocessorOptions PPOpts;
+    remapper.applyMappings(PPOpts);
+    for (PreprocessorOptions::remapped_file_iterator
+           RI = PPOpts.remapped_file_begin(), RE = PPOpts.remapped_file_end();
+           RI != RE; ++RI) {
+      bool &inserted = Uniquer[RI->first];
+      if (inserted)
+        continue;
+      inserted = true;
+      remap.push_back(*RI);
+    }
+  }
+
+  return hasErrorOccurred;
+}
+
 //===----------------------------------------------------------------------===//
 // CollectTransformActions.
 //===----------------------------------------------------------------------===//
@@ -504,7 +542,7 @@
   CInvok.reset(createInvocationForMigration(OrigCI));
   CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
-  Remapper.applyMappings(*CInvok);
+  Remapper.applyMappings(CInvok->getPreprocessorOpts());
 
   CapturedDiagList capturedDiags;
   std::vector<SourceLocation> ARCMTMacroLocs;

Modified: cfe/trunk/lib/ARCMigrate/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/CMakeLists.txt?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/CMakeLists.txt (original)
+++ cfe/trunk/lib/ARCMigrate/CMakeLists.txt Tue Mar  6 14:06:33 2012
@@ -4,6 +4,7 @@
   ARCMT.cpp
   ARCMTActions.cpp
   FileRemapper.cpp
+  ObjCMT.cpp
   PlistReporter.cpp
   TransAPIUses.cpp
   TransARCAssign.cpp

Modified: cfe/trunk/lib/ARCMigrate/FileRemapper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/FileRemapper.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/FileRemapper.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/FileRemapper.cpp Tue Mar  6 14:06:33 2012
@@ -8,8 +8,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/ARCMigrate/FileRemapper.h"
-#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/PreprocessorOptions.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/Diagnostic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/FileSystem.h"
@@ -50,9 +51,15 @@
 
 bool FileRemapper::initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag,
                                 bool ignoreIfFilesChanged) {
+  std::string infoFile = getRemapInfoFile(outputDir);
+  return initFromFile(infoFile, Diag, ignoreIfFilesChanged);
+}
+
+bool FileRemapper::initFromFile(StringRef filePath, DiagnosticsEngine &Diag,
+                                bool ignoreIfFilesChanged) {
   assert(FromToMappings.empty() &&
          "initFromDisk should be called before any remap calls");
-  std::string infoFile = getRemapInfoFile(outputDir);
+  std::string infoFile = filePath;
   bool fileExists = false;
   llvm::sys::fs::exists(infoFile, fileExists);
   if (!fileExists)
@@ -108,8 +115,15 @@
   if (fs::create_directory(outputDir, existed) != llvm::errc::success)
     return report("Could not create directory: " + outputDir, Diag);
 
-  std::string errMsg;
   std::string infoFile = getRemapInfoFile(outputDir);
+  return flushToFile(infoFile, Diag);
+}
+
+bool FileRemapper::flushToFile(StringRef outputPath, DiagnosticsEngine &Diag) {
+  using namespace llvm::sys;
+
+  std::string errMsg;
+  std::string infoFile = outputPath;
   llvm::raw_fd_ostream infoOut(infoFile.c_str(), errMsg,
                                llvm::raw_fd_ostream::F_Binary);
   if (!errMsg.empty())
@@ -189,8 +203,7 @@
   return false;
 }
 
-void FileRemapper::applyMappings(CompilerInvocation &CI) const {
-  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+void FileRemapper::applyMappings(PreprocessorOptions &PPOpts) const {
   for (MappingsTy::const_iterator
          I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
     if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {
@@ -204,8 +217,7 @@
   PPOpts.RetainRemappedFileBuffers = true;
 }
 
-void FileRemapper::transferMappingsAndClear(CompilerInvocation &CI) {
-  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+void FileRemapper::transferMappingsAndClear(PreprocessorOptions &PPOpts) {
   for (MappingsTy::iterator
          I = FromToMappings.begin(), E = FromToMappings.end(); I != E; ++I) {
     if (const FileEntry *FE = I->second.dyn_cast<const FileEntry *>()) {

Added: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=152141&view=auto
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (added)
+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Tue Mar  6 14:06:33 2012
@@ -0,0 +1,226 @@
+//===--- ObjCMT.cpp - ObjC Migrate Tool -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ARCMigrate/ARCMTActions.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/MultiplexConsumer.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/NSAPI.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Edit/Rewriters.h"
+#include "clang/Edit/EditedSource.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
+#include "clang/Rewrite/Rewriter.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/SmallString.h"
+
+using namespace clang;
+using namespace arcmt;
+
+namespace {
+
+class ObjCMigrateASTConsumer : public ASTConsumer {
+  void migrateDecl(Decl *D);
+
+public:
+  std::string MigrateDir;
+  bool MigrateLiterals;
+  bool MigrateSubscripting;
+  llvm::OwningPtr<NSAPI> NSAPIObj;
+  llvm::OwningPtr<edit::EditedSource> Editor;
+  FileRemapper &Remapper;
+  FileManager &FileMgr;
+  const PreprocessingRecord *PPRec;
+  bool IsOutputFile;
+
+  ObjCMigrateASTConsumer(StringRef migrateDir,
+                         bool migrateLiterals,
+                         bool migrateSubscripting,
+                         FileRemapper &remapper,
+                         FileManager &fileMgr,
+                         const PreprocessingRecord *PPRec,
+                         bool isOutputFile = false)
+  : MigrateDir(migrateDir),
+    MigrateLiterals(migrateLiterals),
+    MigrateSubscripting(migrateSubscripting),
+    Remapper(remapper), FileMgr(fileMgr), PPRec(PPRec),
+    IsOutputFile(isOutputFile) { }
+
+protected:
+  virtual void Initialize(ASTContext &Context) {
+    NSAPIObj.reset(new NSAPI(Context));
+    Editor.reset(new edit::EditedSource(Context.getSourceManager(),
+                                        Context.getLangOptions(),
+                                        PPRec));
+  }
+
+  virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
+    for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
+      migrateDecl(*I);
+    return true;
+  }
+  virtual void HandleInterestingDecl(DeclGroupRef DG) {
+    // Ignore decls from the PCH.
+  }
+  virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) {
+    ObjCMigrateASTConsumer::HandleTopLevelDecl(DG);
+  }
+
+  virtual void HandleTranslationUnit(ASTContext &Ctx);
+};
+
+}
+
+ObjCMigrateAction::ObjCMigrateAction(FrontendAction *WrappedAction,
+                             StringRef migrateDir,
+                             bool migrateLiterals,
+                             bool migrateSubscripting)
+  : WrapperFrontendAction(WrappedAction), MigrateDir(migrateDir),
+    MigrateLiterals(migrateLiterals), MigrateSubscripting(migrateSubscripting),
+    CompInst(0) {
+  if (MigrateDir.empty())
+    MigrateDir = "."; // user current directory if none is given.
+}
+
+ASTConsumer *ObjCMigrateAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  StringRef InFile) {
+  ASTConsumer *
+    WrappedConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
+  ASTConsumer *MTConsumer = new ObjCMigrateASTConsumer(MigrateDir,
+                                                       MigrateLiterals,
+                                                       MigrateSubscripting,
+                                                       Remapper,
+                                                    CompInst->getFileManager(),
+                          CompInst->getPreprocessor().getPreprocessingRecord()); 
+  ASTConsumer *Consumers[] = { MTConsumer, WrappedConsumer };
+  return new MultiplexConsumer(Consumers);
+}
+
+bool ObjCMigrateAction::BeginInvocation(CompilerInstance &CI) {
+  Remapper.initFromDisk(MigrateDir, CI.getDiagnostics(),
+                        /*ignoreIfFilesChanges=*/true);
+  CompInst = &CI;
+  CI.getDiagnostics().setIgnoreAllWarnings(true);
+  CI.getPreprocessorOpts().DetailedRecord = true;
+  CI.getPreprocessorOpts().DetailedRecordConditionalDirectives = true;
+  return true;
+}
+
+namespace {
+class ObjCMigrator : public RecursiveASTVisitor<ObjCMigrator> {
+  ObjCMigrateASTConsumer &Consumer;
+
+public:
+  ObjCMigrator(ObjCMigrateASTConsumer &consumer) : Consumer(consumer) { }
+
+  bool shouldVisitTemplateInstantiations() const { return false; }
+  bool shouldWalkTypesOfTypeLocs() const { return false; }
+
+  bool VisitObjCMessageExpr(ObjCMessageExpr *E) {
+    if (Consumer.MigrateLiterals) {
+      edit::Commit commit(*Consumer.Editor);
+      edit::rewriteToObjCLiteralSyntax(E, *Consumer.NSAPIObj, commit);
+      Consumer.Editor->commit(commit);
+    }
+
+    if (Consumer.MigrateSubscripting) {
+      edit::Commit commit(*Consumer.Editor);
+      edit::rewriteToObjCSubscriptSyntax(E, *Consumer.NSAPIObj, commit);
+      Consumer.Editor->commit(commit);
+    }
+
+    return true;
+  }
+
+  bool TraverseObjCMessageExpr(ObjCMessageExpr *E) {
+    // Do depth first; we want to rewrite the subexpressions first so that if
+    // we have to move expressions we will move them already rewritten.
+    for (Stmt::child_range range = E->children(); range; ++range)
+      if (!TraverseStmt(*range))
+        return false;
+
+    return WalkUpFromObjCMessageExpr(E);
+  }
+};
+}
+
+void ObjCMigrateASTConsumer::migrateDecl(Decl *D) {
+  if (!D)
+    return;
+  if (isa<ObjCMethodDecl>(D))
+    return; // Wait for the ObjC container declaration.
+
+  ObjCMigrator(*this).TraverseDecl(D);
+}
+
+namespace {
+
+class RewritesReceiver : public edit::EditsReceiver {
+  Rewriter &Rewrite;
+
+public:
+  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
+
+  virtual void insert(SourceLocation loc, StringRef text) {
+    Rewrite.InsertText(loc, text);
+  }
+  virtual void replace(CharSourceRange range, StringRef text) {
+    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
+  }
+};
+
+}
+
+void ObjCMigrateASTConsumer::HandleTranslationUnit(ASTContext &Ctx) {
+  Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOptions());
+  RewritesReceiver Rec(rewriter);
+  Editor->applyRewrites(Rec);
+
+  for (Rewriter::buffer_iterator
+        I = rewriter.buffer_begin(), E = rewriter.buffer_end(); I != E; ++I) {
+    FileID FID = I->first;
+    RewriteBuffer &buf = I->second;
+    const FileEntry *file = Ctx.getSourceManager().getFileEntryForID(FID);
+    assert(file);
+    llvm::SmallString<512> newText;
+    llvm::raw_svector_ostream vecOS(newText);
+    buf.write(vecOS);
+    vecOS.flush();
+    llvm::MemoryBuffer *memBuf = llvm::MemoryBuffer::getMemBufferCopy(
+                   StringRef(newText.data(), newText.size()), file->getName());
+    llvm::SmallString<64> filePath(file->getName());
+    FileMgr.FixupRelativePath(filePath);
+    Remapper.remap(filePath.str(), memBuf);
+  }
+
+  if (IsOutputFile) {
+    Remapper.flushToFile(MigrateDir, Ctx.getDiagnostics());
+  } else {
+    Remapper.flushToDisk(MigrateDir, Ctx.getDiagnostics());
+  }
+}
+
+bool MigrateSourceAction::BeginInvocation(CompilerInstance &CI) {
+  CI.getPreprocessorOpts().DetailedRecord = true;
+  CI.getPreprocessorOpts().DetailedRecordConditionalDirectives = true;
+  return true;
+}
+
+ASTConsumer *MigrateSourceAction::CreateASTConsumer(CompilerInstance &CI,
+                                                  StringRef InFile) {
+  return new ObjCMigrateASTConsumer(CI.getFrontendOpts().OutputFile,
+                                    /*MigrateLiterals=*/true,
+                                    /*MigrateSubscripting=*/true,
+                                    Remapper,
+                                    CI.getFileManager(),
+                                  CI.getPreprocessor().getPreprocessingRecord(),
+                                    /*isOutputFile=*/true); 
+}

Modified: cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/TransRetainReleaseDealloc.cpp Tue Mar  6 14:06:33 2012
@@ -21,6 +21,8 @@
 #include "Internals.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "clang/AST/ParentMap.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
 
 using namespace clang;
 using namespace arcmt;
@@ -128,27 +130,105 @@
     Transaction Trans(Pass.TA);
     clearDiagnostics(rec->getExprLoc());
 
-    if (E->getMethodFamily() == OMF_release &&
-        isRemovable(E) && isInAtFinally(E)) {
+    ObjCMessageExpr *Msg = E;
+    Expr *RecContainer = Msg;
+    SourceRange RecRange = rec->getSourceRange();
+    checkForGCDOrXPC(Msg, RecContainer, rec, RecRange);
+
+    if (Msg->getMethodFamily() == OMF_release &&
+        isRemovable(RecContainer) && isInAtFinally(RecContainer)) {
       // Change the -release to "receiver = nil" in a finally to avoid a leak
       // when an exception is thrown.
-      Pass.TA.replace(E->getSourceRange(), rec->getSourceRange());
+      Pass.TA.replace(RecContainer->getSourceRange(), RecRange);
       std::string str = " = ";
       str += getNilString(Pass.Ctx);
-      Pass.TA.insertAfterToken(rec->getLocEnd(), str);
+      Pass.TA.insertAfterToken(RecRange.getEnd(), str);
       return true;
     }
 
-    if (!hasSideEffects(E, Pass.Ctx)) {
-      if (tryRemoving(E))
+    if (!hasSideEffects(rec, Pass.Ctx)) {
+      if (tryRemoving(RecContainer))
         return true;
     }
-    Pass.TA.replace(E->getSourceRange(), rec->getSourceRange());
+    Pass.TA.replace(RecContainer->getSourceRange(), RecRange);
 
     return true;
   }
 
 private:
+  /// \brief Check if the retain/release is due to a GCD/XPC macro that are
+  /// defined as:
+  ///
+  /// #define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; })
+  /// #define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; })
+  /// #define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; })
+  /// #define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; })
+  ///
+  /// and return the top container which is the StmtExpr and the macro argument
+  /// expression.
+  void checkForGCDOrXPC(ObjCMessageExpr *Msg, Expr *&RecContainer,
+                        Expr *&Rec, SourceRange &RecRange) {
+    SourceLocation Loc = Msg->getExprLoc();
+    if (!Loc.isMacroID())
+      return;
+    SourceManager &SM = Pass.Ctx.getSourceManager();
+    StringRef MacroName = Lexer::getImmediateMacroName(Loc, SM,
+                                                     Pass.Ctx.getLangOptions());
+    bool isGCDOrXPC = llvm::StringSwitch<bool>(MacroName)
+        .Case("dispatch_retain", true)
+        .Case("dispatch_release", true)
+        .Case("xpc_retain", true)
+        .Case("xpc_release", true)
+        .Default(false);
+    if (!isGCDOrXPC)
+      return;
+
+    StmtExpr *StmtE = 0;
+    Stmt *S = Msg;
+    while (S) {
+      if (StmtExpr *SE = dyn_cast<StmtExpr>(S)) {
+        StmtE = SE;
+        break;
+      }
+      S = StmtMap->getParent(S);
+    }
+
+    if (!StmtE)
+      return;
+
+    Stmt::child_range StmtExprChild = StmtE->children();
+    if (!StmtExprChild)
+      return;
+    CompoundStmt *CompS = dyn_cast_or_null<CompoundStmt>(*StmtExprChild);
+    if (!CompS)
+      return;
+
+    Stmt::child_range CompStmtChild = CompS->children();
+    if (!CompStmtChild)
+      return;
+    DeclStmt *DeclS = dyn_cast_or_null<DeclStmt>(*CompStmtChild);
+    if (!DeclS)
+      return;
+    if (!DeclS->isSingleDecl())
+      return;
+    VarDecl *VD = dyn_cast_or_null<VarDecl>(DeclS->getSingleDecl());
+    if (!VD)
+      return;
+    Expr *Init = VD->getInit();
+    if (!Init)
+      return;
+
+    RecContainer = StmtE;
+    Rec = Init->IgnoreParenImpCasts();
+    if (ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Rec))
+      Rec = EWC->getSubExpr()->IgnoreParenImpCasts();
+    RecRange = Rec->getSourceRange();
+    if (SM.isMacroArgExpansion(RecRange.getBegin()))
+      RecRange.setBegin(SM.getImmediateSpellingLoc(RecRange.getBegin()));
+    if (SM.isMacroArgExpansion(RecRange.getEnd()))
+      RecRange.setEnd(SM.getImmediateSpellingLoc(RecRange.getEnd()));
+  }
+
   void clearDiagnostics(SourceLocation loc) const {
     Pass.TA.clearDiagnostic(diag::err_arc_illegal_explicit_message,
                             diag::err_unavailable,

Modified: cfe/trunk/lib/Basic/DiagnosticIDs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/DiagnosticIDs.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/DiagnosticIDs.cpp (original)
+++ cfe/trunk/lib/Basic/DiagnosticIDs.cpp Tue Mar  6 14:06:33 2012
@@ -657,19 +657,6 @@
     }
   }
 
-  // If we have any Fix-Its, make sure that all of the Fix-Its point into
-  // source locations that aren't macro expansions. If any point into macro
-  // expansions, remove all of the Fix-Its.
-  for (unsigned I = 0, N = Diag.FixItHints.size(); I != N; ++I) {
-    const FixItHint &FixIt = Diag.FixItHints[I];
-    if (FixIt.RemoveRange.isInvalid() ||
-        FixIt.RemoveRange.getBegin().isMacroID() ||
-        FixIt.RemoveRange.getEnd().isMacroID()) {
-      Diag.FixItHints.clear();
-      break;
-    }    
-  }
-  
   // Finally, report it.
   Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
   if (Diag.Client->IncludeInDiagnosticCounts()) {

Modified: cfe/trunk/lib/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CMakeLists.txt?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/CMakeLists.txt (original)
+++ cfe/trunk/lib/CMakeLists.txt Tue Mar  6 14:06:33 2012
@@ -6,6 +6,7 @@
 add_subdirectory(Sema)
 add_subdirectory(CodeGen)
 add_subdirectory(Analysis)
+add_subdirectory(Edit)
 add_subdirectory(Rewrite)
 add_subdirectory(ARCMigrate)
 add_subdirectory(Driver)

Modified: cfe/trunk/lib/Driver/Action.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Action.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Action.cpp (original)
+++ cfe/trunk/lib/Driver/Action.cpp Tue Mar  6 14:06:33 2012
@@ -27,6 +27,7 @@
   case PreprocessJobClass: return "preprocessor";
   case PrecompileJobClass: return "precompiler";
   case AnalyzeJobClass: return "analyzer";
+  case MigrateJobClass: return "migrator";
   case CompileJobClass: return "compiler";
   case AssembleJobClass: return "assembler";
   case LinkJobClass: return "linker";
@@ -78,6 +79,12 @@
   : JobAction(AnalyzeJobClass, Input, OutputType) {
 }
 
+void MigrateJobAction::anchor() {}
+
+MigrateJobAction::MigrateJobAction(Action *Input, types::ID OutputType)
+  : JobAction(MigrateJobClass, Input, OutputType) {
+}
+
 void CompileJobAction::anchor() {}
 
 CompileJobAction::CompileJobAction(Action *Input, types::ID OutputType)

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Tue Mar  6 14:06:33 2012
@@ -141,6 +141,7 @@
     // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
   } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
              (PhaseArg = DAL.getLastArg(options::OPT__analyze,
                                               options::OPT__analyze_auto)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_emit_ast)) ||
@@ -1140,6 +1141,8 @@
       return new CompileJobAction(Input, types::TY_RewrittenObjC);
     } else if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto)) {
       return new AnalyzeJobAction(Input, types::TY_Plist);
+    } else if (Args.hasArg(options::OPT__migrate)) {
+      return new MigrateJobAction(Input, types::TY_Remap);
     } else if (Args.hasArg(options::OPT_emit_ast)) {
       return new CompileJobAction(Input, types::TY_AST);
     } else if (IsUsingLTO(Args)) {

Modified: cfe/trunk/lib/Driver/ToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChain.cpp Tue Mar  6 14:06:33 2012
@@ -54,6 +54,7 @@
     // Assume a minimal NeXT runtime.
     runtime.HasARC = false;
     runtime.HasWeak = false;
+    runtime.HasSubscripting = false;
     runtime.HasTerminate = false;
     return;
 
@@ -61,6 +62,7 @@
     // Assume a maximal GNU runtime.
     runtime.HasARC = true;
     runtime.HasWeak = true;
+    runtime.HasSubscripting = false; // to be added
     runtime.HasTerminate = false; // to be added
     return;
   }

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Tue Mar  6 14:06:33 2012
@@ -227,6 +227,7 @@
     case Action::PreprocessJobClass:
       T = new tools::darwin::Preprocess(*this); break;
     case Action::AnalyzeJobClass:
+    case Action::MigrateJobClass:
       T = new tools::Clang(*this); break;
     case Action::PrecompileJobClass:
     case Action::CompileJobClass:
@@ -1409,6 +1410,7 @@
     case Action::PrecompileJobClass:
       T = new tools::gcc::Precompile(*this); break;
     case Action::AnalyzeJobClass:
+    case Action::MigrateJobClass:
       T = new tools::Clang(*this); break;
     case Action::CompileJobClass:
       T = new tools::gcc::Compile(*this); break;

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Tue Mar  6 14:06:33 2012
@@ -1247,6 +1247,8 @@
   if (isa<AnalyzeJobAction>(JA)) {
     assert(JA.getType() == types::TY_Plist && "Invalid output type.");
     CmdArgs.push_back("-analyze");
+  } else if (isa<MigrateJobAction>(JA)) {
+    CmdArgs.push_back("-migrate");
   } else if (isa<PreprocessJobAction>(JA)) {
     if (Output.getType() == types::TY_Dependencies)
       CmdArgs.push_back("-Eonly");
@@ -1716,10 +1718,12 @@
 
   Args.AddLastArg(CmdArgs, options::OPT_working_directory);
 
+  bool ARCMTEnabled = false;
   if (!Args.hasArg(options::OPT_fno_objc_arc)) {
     if (const Arg *A = Args.getLastArg(options::OPT_ccc_arcmt_check,
                                        options::OPT_ccc_arcmt_modify,
                                        options::OPT_ccc_arcmt_migrate)) {
+      ARCMTEnabled = true;
       switch (A->getOption().getID()) {
       default:
         llvm_unreachable("missed a case");
@@ -1731,7 +1735,7 @@
         break;
       case options::OPT_ccc_arcmt_migrate:
         CmdArgs.push_back("-arcmt-migrate");
-        CmdArgs.push_back("-arcmt-migrate-directory");
+        CmdArgs.push_back("-mt-migrate-directory");
         CmdArgs.push_back(A->getValue(Args));
 
         Args.AddLastArg(CmdArgs, options::OPT_arcmt_migrate_report_output);
@@ -1741,6 +1745,25 @@
     }
   }
 
+  if (const Arg *A = Args.getLastArg(options::OPT_ccc_objcmt_migrate)) {
+    if (ARCMTEnabled) {
+      D.Diag(diag::err_drv_argument_not_allowed_with)
+        << A->getAsString(Args) << "-ccc-arcmt-migrate";
+    }
+    CmdArgs.push_back("-mt-migrate-directory");
+    CmdArgs.push_back(A->getValue(Args));
+
+    if (!Args.hasArg(options::OPT_objcmt_migrate_literals,
+                     options::OPT_objcmt_migrate_subscripting)) {
+      // None specified, means enable them all.
+      CmdArgs.push_back("-objcmt-migrate-literals");
+      CmdArgs.push_back("-objcmt-migrate-subscripting");
+    } else {
+      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_literals);
+      Args.AddLastArg(CmdArgs, options::OPT_objcmt_migrate_subscripting);
+    }
+  }
+
   // Add preprocessing options like -I, -D, etc. if we are using the
   // preprocessor.
   //

Modified: cfe/trunk/lib/Driver/WindowsToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/WindowsToolChain.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/WindowsToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/WindowsToolChain.cpp Tue Mar  6 14:06:33 2012
@@ -59,6 +59,7 @@
     case Action::PreprocessJobClass:
     case Action::PrecompileJobClass:
     case Action::AnalyzeJobClass:
+    case Action::MigrateJobClass:
     case Action::CompileJobClass:
       T = new tools::Clang(*this); break;
     case Action::AssembleJobClass:

Added: cfe/trunk/lib/Edit/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/CMakeLists.txt?rev=152141&view=auto
==============================================================================
--- cfe/trunk/lib/Edit/CMakeLists.txt (added)
+++ cfe/trunk/lib/Edit/CMakeLists.txt Tue Mar  6 14:06:33 2012
@@ -0,0 +1,7 @@
+set(LLVM_USED_LIBS clangBasic clangAST clangLex)
+
+add_clang_library(clangEdit
+  Commit.cpp
+  EditedSource.cpp
+  RewriteObjCFoundationAPI.cpp
+  )

Added: cfe/trunk/lib/Edit/Commit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/Commit.cpp?rev=152141&view=auto
==============================================================================
--- cfe/trunk/lib/Edit/Commit.cpp (added)
+++ cfe/trunk/lib/Edit/Commit.cpp Tue Mar  6 14:06:33 2012
@@ -0,0 +1,345 @@
+//===----- Commit.cpp - A unit of edits -----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditedSource.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/PreprocessingRecord.h"
+#include "clang/Basic/SourceManager.h"
+
+using namespace clang;
+using namespace edit;
+
+SourceLocation Commit::Edit::getFileLocation(SourceManager &SM) const {
+  SourceLocation Loc = SM.getLocForStartOfFile(Offset.getFID());
+  Loc = Loc.getLocWithOffset(Offset.getOffset());
+  assert(Loc.isFileID());
+  return Loc;
+}
+
+CharSourceRange Commit::Edit::getFileRange(SourceManager &SM) const {
+  SourceLocation Loc = getFileLocation(SM);
+  return CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(Length));
+}
+
+CharSourceRange Commit::Edit::getInsertFromRange(SourceManager &SM) const {
+  SourceLocation Loc = SM.getLocForStartOfFile(InsertFromRangeOffs.getFID());
+  Loc = Loc.getLocWithOffset(InsertFromRangeOffs.getOffset());
+  assert(Loc.isFileID());
+  return CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(Length));
+}
+
+Commit::Commit(EditedSource &Editor)
+  : SourceMgr(Editor.getSourceManager()), LangOpts(Editor.getLangOptions()),
+    PPRec(Editor.getPreprocessingRecord()),
+    Editor(&Editor), IsCommitable(true) { }
+
+bool Commit::insert(SourceLocation loc, StringRef text,
+                    bool afterToken, bool beforePreviousInsertions) {
+  if (text.empty())
+    return true;
+
+  FileOffset Offs;
+  if ((!afterToken && !canInsert(loc, Offs)) ||
+      ( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
+    IsCommitable = false;
+    return false;
+  }
+
+  addInsert(loc, Offs, text, beforePreviousInsertions);
+  return true;
+}
+
+bool Commit::insertFromRange(SourceLocation loc,
+                             CharSourceRange range,
+                             bool afterToken, bool beforePreviousInsertions) {
+  FileOffset RangeOffs;
+  unsigned RangeLen;
+  if (!canRemoveRange(range, RangeOffs, RangeLen)) {
+    IsCommitable = false;
+    return false;
+  }
+
+  FileOffset Offs;
+  if ((!afterToken && !canInsert(loc, Offs)) ||
+      ( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
+    IsCommitable = false;
+    return false;
+  }
+
+  if (PPRec &&
+      PPRec->areInDifferentConditionalDirectiveRegion(loc, range.getBegin())) {
+    IsCommitable = false;
+    return false;
+  }
+
+  addInsertFromRange(loc, Offs, RangeOffs, RangeLen, beforePreviousInsertions);
+  return true;
+}
+
+bool Commit::remove(CharSourceRange range) {
+  FileOffset Offs;
+  unsigned Len;
+  if (!canRemoveRange(range, Offs, Len)) {
+    IsCommitable = false;
+    return false;
+  }
+
+  addRemove(range.getBegin(), Offs, Len);
+  return true;
+}
+
+bool Commit::insertWrap(StringRef before, CharSourceRange range,
+                        StringRef after) {
+  bool commitableBefore = insert(range.getBegin(), before, /*afterToken=*/false,
+                                 /*beforePreviousInsertions=*/true);
+  bool commitableAfter;
+  if (range.isTokenRange())
+    commitableAfter = insertAfterToken(range.getEnd(), after);
+  else
+    commitableAfter = insert(range.getEnd(), after);
+
+  return commitableBefore && commitableAfter;
+}
+
+bool Commit::replace(CharSourceRange range, StringRef text) {
+  if (text.empty())
+    return remove(range);
+
+  FileOffset Offs;
+  unsigned Len;
+  if (!canInsert(range.getBegin(), Offs) || !canRemoveRange(range, Offs, Len)) {
+    IsCommitable = false;
+    return false;
+  }
+
+  addRemove(range.getBegin(), Offs, Len);
+  addInsert(range.getBegin(), Offs, text, false);
+  return true;
+}
+
+bool Commit::replaceWithInner(CharSourceRange range,
+                              CharSourceRange replacementRange) {
+  FileOffset OuterBegin;
+  unsigned OuterLen;
+  if (!canRemoveRange(range, OuterBegin, OuterLen)) {
+    IsCommitable = false;
+    return false;
+  }
+
+  FileOffset InnerBegin;
+  unsigned InnerLen;
+  if (!canRemoveRange(replacementRange, InnerBegin, InnerLen)) {
+    IsCommitable = false;
+    return false;
+  }
+
+  FileOffset OuterEnd = OuterBegin.getWithOffset(OuterLen);
+  FileOffset InnerEnd = InnerBegin.getWithOffset(InnerLen); 
+  if (OuterBegin.getFID() != InnerBegin.getFID() ||
+      InnerBegin < OuterBegin ||
+      InnerBegin > OuterEnd ||
+      InnerEnd > OuterEnd) {
+    IsCommitable = false;
+    return false;
+  }
+
+  addRemove(range.getBegin(),
+            OuterBegin, InnerBegin.getOffset() - OuterBegin.getOffset());
+  addRemove(replacementRange.getEnd(),
+            InnerEnd, OuterEnd.getOffset() - InnerEnd.getOffset());
+  return true;
+}
+
+bool Commit::replaceText(SourceLocation loc, StringRef text,
+                         StringRef replacementText) {
+  if (text.empty() || replacementText.empty())
+    return true;
+
+  FileOffset Offs;
+  unsigned Len;
+  if (!canReplaceText(loc, replacementText, Offs, Len)) {
+    IsCommitable = false;
+    return false;
+  }
+
+  addRemove(loc, Offs, Len);
+  addInsert(loc, Offs, text, false);
+  return true;
+}
+
+void Commit::addInsert(SourceLocation OrigLoc, FileOffset Offs, StringRef text,
+                       bool beforePreviousInsertions) {
+  if (text.empty())
+    return;
+
+  Edit data;
+  data.Kind = Act_Insert;
+  data.OrigLoc = OrigLoc;
+  data.Offset = Offs;
+  data.Text = text;
+  data.BeforePrev = beforePreviousInsertions;
+  CachedEdits.push_back(data);
+}
+
+void Commit::addInsertFromRange(SourceLocation OrigLoc, FileOffset Offs,
+                                FileOffset RangeOffs, unsigned RangeLen,
+                                bool beforePreviousInsertions) {
+  if (RangeLen == 0)
+    return;
+
+  Edit data;
+  data.Kind = Act_InsertFromRange;
+  data.OrigLoc = OrigLoc;
+  data.Offset = Offs;
+  data.InsertFromRangeOffs = RangeOffs;
+  data.Length = RangeLen;
+  data.BeforePrev = beforePreviousInsertions;
+  CachedEdits.push_back(data);
+}
+
+void Commit::addRemove(SourceLocation OrigLoc,
+                       FileOffset Offs, unsigned Len) {
+  if (Len == 0)
+    return;
+
+  Edit data;
+  data.Kind = Act_Remove;
+  data.OrigLoc = OrigLoc;
+  data.Offset = Offs;
+  data.Length = Len;
+  CachedEdits.push_back(data);
+}
+
+bool Commit::canInsert(SourceLocation loc, FileOffset &offs) {
+  if (loc.isInvalid())
+    return false;
+
+  if (loc.isMacroID())
+    isAtStartOfMacroExpansion(loc, &loc);
+
+  const SourceManager &SM = SourceMgr;
+  while (SM.isMacroArgExpansion(loc))
+    loc = SM.getImmediateSpellingLoc(loc);
+
+  if (loc.isMacroID())
+    if (!isAtStartOfMacroExpansion(loc, &loc))
+      return false;
+
+  if (SM.isInSystemHeader(loc))
+    return false;
+
+  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
+  if (locInfo.first.isInvalid())
+    return false;
+  offs = FileOffset(locInfo.first, locInfo.second);
+  return canInsertInOffset(loc, offs);
+}
+
+bool Commit::canInsertAfterToken(SourceLocation loc, FileOffset &offs,
+                                 SourceLocation &AfterLoc) {
+  if (loc.isInvalid())
+
+    return false;
+
+  SourceLocation spellLoc = SourceMgr.getSpellingLoc(loc);
+  unsigned tokLen = Lexer::MeasureTokenLength(spellLoc, SourceMgr, LangOpts);
+  AfterLoc = loc.getLocWithOffset(tokLen);
+
+  if (loc.isMacroID())
+    isAtEndOfMacroExpansion(loc, &loc);
+
+  const SourceManager &SM = SourceMgr;
+  while (SM.isMacroArgExpansion(loc))
+    loc = SM.getImmediateSpellingLoc(loc);
+
+  if (loc.isMacroID())
+    if (!isAtEndOfMacroExpansion(loc, &loc))
+      return false;
+
+  if (SM.isInSystemHeader(loc))
+    return false;
+
+  loc = Lexer::getLocForEndOfToken(loc, 0, SourceMgr, LangOpts);
+  if (loc.isInvalid())
+    return false;
+
+  std::pair<FileID, unsigned> locInfo = SM.getDecomposedLoc(loc);
+  if (locInfo.first.isInvalid())
+    return false;
+  offs = FileOffset(locInfo.first, locInfo.second);
+  return canInsertInOffset(loc, offs);
+}
+
+bool Commit::canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs) {
+  for (unsigned i = 0, e = CachedEdits.size(); i != e; ++i) {
+    Edit &act = CachedEdits[i];
+    if (act.Kind == Act_Remove) {
+      if (act.Offset.getFID() == Offs.getFID() &&
+          Offs > act.Offset && Offs < act.Offset.getWithOffset(act.Length))
+        return false; // position has been removed.
+    }
+  }
+
+  if (!Editor)
+    return true;
+  return Editor->canInsertInOffset(OrigLoc, Offs);
+}
+
+bool Commit::canRemoveRange(CharSourceRange range,
+                            FileOffset &Offs, unsigned &Len) {
+  const SourceManager &SM = SourceMgr;
+  range = Lexer::makeFileCharRange(range, SM, LangOpts);
+  if (range.isInvalid())
+    return false;
+  
+  if (range.getBegin().isMacroID() || range.getEnd().isMacroID())
+    return false;
+  if (SM.isInSystemHeader(range.getBegin()) ||
+      SM.isInSystemHeader(range.getEnd()))
+    return false;
+
+  if (PPRec && PPRec->rangeIntersectsConditionalDirective(range.getAsRange()))
+    return false;
+
+  std::pair<FileID, unsigned> beginInfo = SM.getDecomposedLoc(range.getBegin());
+  std::pair<FileID, unsigned> endInfo = SM.getDecomposedLoc(range.getEnd());
+  if (beginInfo.first != endInfo.first ||
+      beginInfo.second > endInfo.second)
+    return false;
+
+  Offs = FileOffset(beginInfo.first, beginInfo.second);
+  Len = endInfo.second - beginInfo.second;
+  return true;
+}
+
+bool Commit::canReplaceText(SourceLocation loc, StringRef text,
+                            FileOffset &Offs, unsigned &Len) {
+  assert(!text.empty());
+
+  if (!canInsert(loc, Offs))
+    return false;
+
+  // Try to load the file buffer.
+  bool invalidTemp = false;
+  StringRef file = SourceMgr.getBufferData(Offs.getFID(), &invalidTemp);
+  if (invalidTemp)
+    return false;
+
+  return file.substr(Offs.getOffset()).startswith(text);
+}
+
+bool Commit::isAtStartOfMacroExpansion(SourceLocation loc,
+                                       SourceLocation *MacroBegin) const {
+  return Lexer::isAtStartOfMacroExpansion(loc, SourceMgr, LangOpts, MacroBegin);
+}
+bool Commit::isAtEndOfMacroExpansion(SourceLocation loc,
+                                     SourceLocation *MacroEnd) const {
+  return Lexer::isAtEndOfMacroExpansion(loc, SourceMgr, LangOpts, MacroEnd);
+}

Added: cfe/trunk/lib/Edit/EditedSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/EditedSource.cpp?rev=152141&view=auto
==============================================================================
--- cfe/trunk/lib/Edit/EditedSource.cpp (added)
+++ cfe/trunk/lib/Edit/EditedSource.cpp Tue Mar  6 14:06:33 2012
@@ -0,0 +1,329 @@
+//===----- EditedSource.cpp - Collection of source edits ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Edit/EditedSource.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+
+using namespace clang;
+using namespace edit;
+
+void EditsReceiver::remove(CharSourceRange range) {
+  replace(range, StringRef());
+}
+
+StringRef EditedSource::copyString(const Twine &twine) {
+  llvm::SmallString<128> Data;
+  return copyString(twine.toStringRef(Data));
+}
+
+bool EditedSource::canInsertInOffset(SourceLocation OrigLoc, FileOffset Offs) {
+  FileEditsTy::iterator FA = getActionForOffset(Offs);
+  if (FA != FileEdits.end()) {
+    if (FA->first != Offs)
+      return false; // position has been removed.
+  }
+
+  if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
+    SourceLocation
+      DefArgLoc = SourceMgr.getImmediateExpansionRange(OrigLoc).first;
+    SourceLocation
+      ExpLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+    llvm::DenseMap<unsigned, SourceLocation>::iterator
+      I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
+    if (I != ExpansionToArgMap.end() && I->second != DefArgLoc)
+      return false; // Trying to write in a macro argument input that has
+                 // already been written for another argument of the same macro. 
+  }
+
+  return true;
+}
+
+bool EditedSource::commitInsert(SourceLocation OrigLoc,
+                                FileOffset Offs, StringRef text,
+                                bool beforePreviousInsertions) {
+  if (!canInsertInOffset(OrigLoc, Offs))
+    return false;
+  if (text.empty())
+    return true;
+
+  if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
+    SourceLocation
+      DefArgLoc = SourceMgr.getImmediateExpansionRange(OrigLoc).first;
+    SourceLocation
+      ExpLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+    ExpansionToArgMap[ExpLoc.getRawEncoding()] = DefArgLoc;
+  }
+  
+  FileEdit &FA = FileEdits[Offs];
+  if (FA.Text.empty()) {
+    FA.Text = copyString(text);
+    return true;
+  }
+
+  Twine concat;
+  if (beforePreviousInsertions)
+    concat = Twine(text) + FA.Text;
+  else
+    concat = Twine(FA.Text) +  text;
+
+  FA.Text = copyString(concat);
+  return true;
+}
+
+bool EditedSource::commitInsertFromRange(SourceLocation OrigLoc,
+                                   FileOffset Offs,
+                                   FileOffset InsertFromRangeOffs, unsigned Len,
+                                   bool beforePreviousInsertions) {
+  if (Len == 0)
+    return true;
+
+  llvm::SmallString<128> StrVec;
+  FileOffset BeginOffs = InsertFromRangeOffs;
+  FileOffset EndOffs = BeginOffs.getWithOffset(Len);
+  FileEditsTy::iterator I = FileEdits.upper_bound(BeginOffs);
+  if (I != FileEdits.begin())
+    --I;
+
+  for (; I != FileEdits.end(); ++I) {
+    FileEdit &FA = I->second;
+    FileOffset B = I->first;
+    FileOffset E = B.getWithOffset(FA.RemoveLen);
+
+    if (BeginOffs < E) {
+      if (BeginOffs >= B) {
+        BeginOffs = E;
+        ++I;
+      }
+      break;
+    }
+  }
+
+  for (; I != FileEdits.end() && EndOffs > I->first; ++I) {
+    FileEdit &FA = I->second;
+    FileOffset B = I->first;
+    FileOffset E = B.getWithOffset(FA.RemoveLen);
+
+    if (BeginOffs < B) {
+      bool Invalid = false;
+      StringRef text = getSourceText(BeginOffs, B, Invalid);
+      if (Invalid)
+        return false;
+      StrVec += text;
+    }
+    StrVec += FA.Text;
+    BeginOffs = E;
+  }
+
+  if (BeginOffs < EndOffs) {
+    bool Invalid = false;
+    StringRef text = getSourceText(BeginOffs, EndOffs, Invalid);
+    if (Invalid)
+      return false;
+    StrVec += text;
+  }
+
+  return commitInsert(OrigLoc, Offs, StrVec.str(), beforePreviousInsertions);
+}
+
+void EditedSource::commitRemove(SourceLocation OrigLoc,
+                                FileOffset BeginOffs, unsigned Len) {
+  if (Len == 0)
+    return;
+
+  FileOffset EndOffs = BeginOffs.getWithOffset(Len);
+  FileEditsTy::iterator I = FileEdits.upper_bound(BeginOffs);
+  if (I != FileEdits.begin())
+    --I;
+
+  for (; I != FileEdits.end(); ++I) {
+    FileEdit &FA = I->second;
+    FileOffset B = I->first;
+    FileOffset E = B.getWithOffset(FA.RemoveLen);
+
+    if (BeginOffs < E)
+      break;
+  }
+
+  FileOffset TopBegin, TopEnd;
+  FileEdit *TopFA = 0;
+
+  if (I == FileEdits.end()) {
+    FileEditsTy::iterator
+      NewI = FileEdits.insert(I, std::make_pair(BeginOffs, FileEdit()));
+    NewI->second.RemoveLen = Len;
+    return;
+  }
+
+  FileEdit &FA = I->second;
+  FileOffset B = I->first;
+  FileOffset E = B.getWithOffset(FA.RemoveLen);
+  if (BeginOffs < B) {
+    FileEditsTy::iterator
+      NewI = FileEdits.insert(I, std::make_pair(BeginOffs, FileEdit()));
+    TopBegin = BeginOffs;
+    TopEnd = EndOffs;
+    TopFA = &NewI->second;
+    TopFA->RemoveLen = Len;
+  } else {
+    TopBegin = B;
+    TopEnd = E;
+    TopFA = &I->second;
+    if (TopEnd >= EndOffs)
+      return;
+    unsigned diff = EndOffs.getOffset() - TopEnd.getOffset();
+    TopEnd = EndOffs;
+    TopFA->RemoveLen += diff;
+    ++I;
+  }
+
+  while (I != FileEdits.end()) {
+    FileEdit &FA = I->second;
+    FileOffset B = I->first;
+    FileOffset E = B.getWithOffset(FA.RemoveLen);
+
+    if (B >= TopEnd)
+      break;
+
+    if (E <= TopEnd) {
+      FileEdits.erase(I++);
+      continue;
+    }
+
+    if (B < TopEnd) {
+      unsigned diff = E.getOffset() - TopEnd.getOffset();
+      TopEnd = E;
+      TopFA->RemoveLen += diff;
+      FileEdits.erase(I);
+    }
+
+    break;
+  }
+}
+
+bool EditedSource::commit(const Commit &commit) {
+  if (!commit.isCommitable())
+    return false;
+
+  for (edit::Commit::edit_iterator
+         I = commit.edit_begin(), E = commit.edit_end(); I != E; ++I) {
+    const edit::Commit::Edit &edit = *I;
+    switch (edit.Kind) {
+    case edit::Commit::Act_Insert:
+      commitInsert(edit.OrigLoc, edit.Offset, edit.Text, edit.BeforePrev);
+      break;
+    case edit::Commit::Act_InsertFromRange:
+      commitInsertFromRange(edit.OrigLoc, edit.Offset,
+                            edit.InsertFromRangeOffs, edit.Length,
+                            edit.BeforePrev);
+      break;
+    case edit::Commit::Act_Remove:
+      commitRemove(edit.OrigLoc, edit.Offset, edit.Length);
+      break;
+    }
+  }
+
+  return true;
+}
+
+static void applyRewrite(EditsReceiver &receiver,
+                         StringRef text, FileOffset offs, unsigned len,
+                         const SourceManager &SM) {
+  assert(!offs.getFID().isInvalid());
+  SourceLocation Loc = SM.getLocForStartOfFile(offs.getFID());
+  Loc = Loc.getLocWithOffset(offs.getOffset());
+  assert(Loc.isFileID());
+  CharSourceRange range = CharSourceRange::getCharRange(Loc,
+                                                     Loc.getLocWithOffset(len));
+
+  if (text.empty()) {
+    assert(len);
+    receiver.remove(range);
+    return;
+  }
+
+  if (len)
+    receiver.replace(range, text);
+  else
+    receiver.insert(Loc, text);
+}
+
+void EditedSource::applyRewrites(EditsReceiver &receiver) {
+  llvm::SmallString<128> StrVec;
+  FileOffset CurOffs, CurEnd;
+  unsigned CurLen;
+
+  if (FileEdits.empty())
+    return;
+
+  FileEditsTy::iterator I = FileEdits.begin();
+  CurOffs = I->first;
+  StrVec = I->second.Text;
+  CurLen = I->second.RemoveLen;
+  CurEnd = CurOffs.getWithOffset(CurLen);
+  ++I;
+
+  for (FileEditsTy::iterator E = FileEdits.end(); I != E; ++I) {
+    FileOffset offs = I->first;
+    FileEdit act = I->second;
+    assert(offs >= CurEnd);
+
+    if (offs == CurEnd) {
+      StrVec += act.Text;
+      CurLen += act.RemoveLen;
+      CurEnd.getWithOffset(act.RemoveLen);
+      continue;
+    }
+
+    applyRewrite(receiver, StrVec.str(), CurOffs, CurLen, SourceMgr);
+    CurOffs = offs;
+    StrVec = act.Text;
+    CurLen = act.RemoveLen;
+    CurEnd = CurOffs.getWithOffset(CurLen);
+  }
+
+  applyRewrite(receiver, StrVec.str(), CurOffs, CurLen, SourceMgr);
+}
+
+void EditedSource::clearRewrites() {
+  FileEdits.clear();
+  StrAlloc.Reset();
+}
+
+StringRef EditedSource::getSourceText(FileOffset BeginOffs, FileOffset EndOffs,
+                                      bool &Invalid) {
+  assert(BeginOffs.getFID() == EndOffs.getFID());
+  assert(BeginOffs <= EndOffs);
+  SourceLocation BLoc = SourceMgr.getLocForStartOfFile(BeginOffs.getFID());
+  BLoc = BLoc.getLocWithOffset(BeginOffs.getOffset());
+  assert(BLoc.isFileID());
+  SourceLocation
+    ELoc = BLoc.getLocWithOffset(EndOffs.getOffset() - BeginOffs.getOffset());
+  return Lexer::getSourceText(CharSourceRange::getCharRange(BLoc, ELoc),
+                              SourceMgr, LangOpts, &Invalid);
+}
+
+EditedSource::FileEditsTy::iterator
+EditedSource::getActionForOffset(FileOffset Offs) {
+  FileEditsTy::iterator I = FileEdits.upper_bound(Offs);
+  if (I == FileEdits.begin())
+    return FileEdits.end();
+  --I;
+  FileEdit &FA = I->second;
+  FileOffset B = I->first;
+  FileOffset E = B.getWithOffset(FA.RemoveLen);
+  if (Offs >= B && Offs < E)
+    return I;
+
+  return FileEdits.end();
+}

Copied: cfe/trunk/lib/Edit/Makefile (from r152140, cfe/trunk/lib/Makefile)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/Makefile?p2=cfe/trunk/lib/Edit/Makefile&p1=cfe/trunk/lib/Makefile&r1=152140&r2=152141&rev=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Makefile (original)
+++ cfe/trunk/lib/Edit/Makefile Tue Mar  6 14:06:33 2012
@@ -1,4 +1,4 @@
-##===- lib/Makefile ----------------------------------------*- Makefile -*-===##
+##===- clang/lib/Edit/Makefile -----------------------------*- Makefile -*-===##
 # 
 #                     The LLVM Compiler Infrastructure
 #
@@ -6,11 +6,9 @@
 # License. See LICENSE.TXT for details.
 # 
 ##===----------------------------------------------------------------------===##
-CLANG_LEVEL := ..
 
-PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis \
-                StaticAnalyzer Rewrite ARCMigrate Serialization Frontend \
-                FrontendTool Index Driver
+CLANG_LEVEL := ../..
+LIBRARYNAME := clangEdit
 
 include $(CLANG_LEVEL)/Makefile
 

Added: cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp?rev=152141&view=auto
==============================================================================
--- cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp (added)
+++ cfe/trunk/lib/Edit/RewriteObjCFoundationAPI.cpp Tue Mar  6 14:06:33 2012
@@ -0,0 +1,589 @@
+//===--- RewriteObjCFoundationAPI.cpp - Foundation API Rewriter -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Rewrites legacy method calls to modern syntax.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Edit/Rewriters.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/AST/NSAPI.h"
+
+using namespace clang;
+using namespace edit;
+
+static bool checkForLiteralCreation(const ObjCMessageExpr *Msg,
+                                    IdentifierInfo *&ClassId) {
+  if (!Msg || Msg->isImplicit() || !Msg->getMethodDecl())
+    return false;
+
+  const ObjCInterfaceDecl *Receiver = Msg->getReceiverInterface();
+  if (!Receiver)
+    return false;
+  ClassId = Receiver->getIdentifier();
+
+  if (Msg->getReceiverKind() == ObjCMessageExpr::Class)
+    return true;
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// rewriteObjCRedundantCallWithLiteral.
+//===----------------------------------------------------------------------===//
+
+bool edit::rewriteObjCRedundantCallWithLiteral(const ObjCMessageExpr *Msg,
+                                              const NSAPI &NS, Commit &commit) {
+  IdentifierInfo *II = 0;
+  if (!checkForLiteralCreation(Msg, II))
+    return false;
+  if (Msg->getNumArgs() != 1)
+    return false;
+
+  const Expr *Arg = Msg->getArg(0)->IgnoreParenImpCasts();
+  Selector Sel = Msg->getSelector();
+
+  if ((isa<ObjCStringLiteral>(Arg) &&
+       NS.getNSClassId(NSAPI::ClassId_NSString) == II &&
+       NS.getNSStringSelector(NSAPI::NSStr_stringWithString) == Sel)    ||
+
+      (isa<ObjCArrayLiteral>(Arg) &&
+       NS.getNSClassId(NSAPI::ClassId_NSArray) == II &&
+       NS.getNSArraySelector(NSAPI::NSArr_arrayWithArray) == Sel)      ||
+
+      (isa<ObjCDictionaryLiteral>(Arg) &&
+       NS.getNSClassId(NSAPI::ClassId_NSDictionary) == II &&
+       NS.getNSDictionarySelector(
+                              NSAPI::NSDict_dictionaryWithDictionary) == Sel)) {
+    
+    commit.replaceWithInner(Msg->getSourceRange(),
+                           Msg->getArg(0)->getSourceRange());
+    return true;
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// rewriteToObjCSubscriptSyntax.
+//===----------------------------------------------------------------------===//
+
+static void maybePutParensOnReceiver(const Expr *Receiver, Commit &commit) {
+  Receiver = Receiver->IgnoreImpCasts();
+  if (isa<BinaryOperator>(Receiver) || isa<UnaryOperator>(Receiver)) {
+    SourceRange RecRange = Receiver->getSourceRange();
+    commit.insertWrap("(", RecRange, ")");
+  }
+}
+
+static bool rewriteToSubscriptGet(const ObjCMessageExpr *Msg, Commit &commit) {
+  if (Msg->getNumArgs() != 1)
+    return false;
+  const Expr *Rec = Msg->getInstanceReceiver();
+  if (!Rec)
+    return false;
+
+  SourceRange MsgRange = Msg->getSourceRange();
+  SourceRange RecRange = Rec->getSourceRange();
+  SourceRange ArgRange = Msg->getArg(0)->getSourceRange();
+
+  commit.replaceWithInner(CharSourceRange::getCharRange(MsgRange.getBegin(),
+                                                       ArgRange.getBegin()),
+                         CharSourceRange::getTokenRange(RecRange));
+  commit.replaceWithInner(SourceRange(ArgRange.getBegin(), MsgRange.getEnd()),
+                         ArgRange);
+  commit.insertWrap("[", ArgRange, "]");
+  maybePutParensOnReceiver(Rec, commit);
+  return true;
+}
+
+static bool rewriteToArraySubscriptSet(const ObjCMessageExpr *Msg,
+                                       Commit &commit) {
+  if (Msg->getNumArgs() != 2)
+    return false;
+  const Expr *Rec = Msg->getInstanceReceiver();
+  if (!Rec)
+    return false;
+
+  SourceRange MsgRange = Msg->getSourceRange();
+  SourceRange RecRange = Rec->getSourceRange();
+  SourceRange Arg0Range = Msg->getArg(0)->getSourceRange();
+  SourceRange Arg1Range = Msg->getArg(1)->getSourceRange();
+
+  commit.replaceWithInner(CharSourceRange::getCharRange(MsgRange.getBegin(),
+                                                       Arg0Range.getBegin()),
+                         CharSourceRange::getTokenRange(RecRange));
+  commit.replaceWithInner(CharSourceRange::getCharRange(Arg0Range.getBegin(),
+                                                       Arg1Range.getBegin()),
+                         CharSourceRange::getTokenRange(Arg0Range));
+  commit.replaceWithInner(SourceRange(Arg1Range.getBegin(), MsgRange.getEnd()),
+                         Arg1Range);
+  commit.insertWrap("[", CharSourceRange::getCharRange(Arg0Range.getBegin(),
+                                                       Arg1Range.getBegin()),
+                    "] = ");
+  maybePutParensOnReceiver(Rec, commit);
+  return true;
+}
+
+static bool rewriteToDictionarySubscriptSet(const ObjCMessageExpr *Msg,
+                                            Commit &commit) {
+  if (Msg->getNumArgs() != 2)
+    return false;
+  const Expr *Rec = Msg->getInstanceReceiver();
+  if (!Rec)
+    return false;
+
+  SourceRange MsgRange = Msg->getSourceRange();
+  SourceRange RecRange = Rec->getSourceRange();
+  SourceRange Arg0Range = Msg->getArg(0)->getSourceRange();
+  SourceRange Arg1Range = Msg->getArg(1)->getSourceRange();
+
+  SourceLocation LocBeforeVal = Arg0Range.getBegin();
+  commit.insertBefore(LocBeforeVal, "] = ");
+  commit.insertFromRange(LocBeforeVal, Arg1Range, /*afterToken=*/false,
+                         /*beforePreviousInsertions=*/true);
+  commit.insertBefore(LocBeforeVal, "[");
+  commit.replaceWithInner(CharSourceRange::getCharRange(MsgRange.getBegin(),
+                                                       Arg0Range.getBegin()),
+                         CharSourceRange::getTokenRange(RecRange));
+  commit.replaceWithInner(SourceRange(Arg0Range.getBegin(), MsgRange.getEnd()),
+                         Arg0Range);
+  maybePutParensOnReceiver(Rec, commit);
+  return true;
+}
+
+bool edit::rewriteToObjCSubscriptSyntax(const ObjCMessageExpr *Msg,
+                                           const NSAPI &NS, Commit &commit) {
+  if (!Msg || Msg->isImplicit() ||
+      Msg->getReceiverKind() != ObjCMessageExpr::Instance)
+    return false;
+  const ObjCMethodDecl *Method = Msg->getMethodDecl();
+  if (!Method)
+    return false;
+
+  const ObjCInterfaceDecl *
+    IFace = NS.getASTContext().getObjContainingInterface(
+                                          const_cast<ObjCMethodDecl *>(Method));
+  if (!IFace)
+    return false;
+  IdentifierInfo *II = IFace->getIdentifier();
+  Selector Sel = Msg->getSelector();
+
+  if ((II == NS.getNSClassId(NSAPI::ClassId_NSArray) &&
+       Sel == NS.getNSArraySelector(NSAPI::NSArr_objectAtIndex)) ||
+      (II == NS.getNSClassId(NSAPI::ClassId_NSDictionary) &&
+       Sel == NS.getNSDictionarySelector(NSAPI::NSDict_objectForKey)))
+    return rewriteToSubscriptGet(Msg, commit);
+
+  if (Msg->getNumArgs() != 2)
+    return false;
+
+  if (II == NS.getNSClassId(NSAPI::ClassId_NSMutableArray) &&
+      Sel == NS.getNSArraySelector(NSAPI::NSMutableArr_replaceObjectAtIndex))
+    return rewriteToArraySubscriptSet(Msg, commit);
+
+  if (II == NS.getNSClassId(NSAPI::ClassId_NSMutableDictionary) &&
+      Sel == NS.getNSDictionarySelector(NSAPI::NSMutableDict_setObjectForKey))
+    return rewriteToDictionarySubscriptSet(Msg, commit);
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// rewriteToObjCLiteralSyntax.
+//===----------------------------------------------------------------------===//
+
+static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg,
+                                  const NSAPI &NS, Commit &commit);
+static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg,
+                                  const NSAPI &NS, Commit &commit);
+static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg,
+                                  const NSAPI &NS, Commit &commit);
+
+bool edit::rewriteToObjCLiteralSyntax(const ObjCMessageExpr *Msg,
+                                      const NSAPI &NS, Commit &commit) {
+  IdentifierInfo *II = 0;
+  if (!checkForLiteralCreation(Msg, II))
+    return false;
+
+  if (II == NS.getNSClassId(NSAPI::ClassId_NSArray))
+    return rewriteToArrayLiteral(Msg, NS, commit);
+  if (II == NS.getNSClassId(NSAPI::ClassId_NSDictionary))
+    return rewriteToDictionaryLiteral(Msg, NS, commit);
+  if (II == NS.getNSClassId(NSAPI::ClassId_NSNumber))
+    return rewriteToNumberLiteral(Msg, NS, commit);
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// rewriteToArrayLiteral.
+//===----------------------------------------------------------------------===//
+
+static bool rewriteToArrayLiteral(const ObjCMessageExpr *Msg,
+                                  const NSAPI &NS, Commit &commit) {
+  Selector Sel = Msg->getSelector();
+  SourceRange MsgRange = Msg->getSourceRange();
+
+  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_array)) {
+    if (Msg->getNumArgs() != 0)
+      return false;
+    commit.replace(MsgRange, "@[]");
+    return true;
+  }
+
+  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObject)) {
+    if (Msg->getNumArgs() != 1)
+      return false;
+    SourceRange ArgRange = Msg->getArg(0)->getSourceRange();
+    commit.replaceWithInner(MsgRange, ArgRange);
+    commit.insertWrap("@[", ArgRange, "]");
+    return true;
+  }
+
+  if (Sel == NS.getNSArraySelector(NSAPI::NSArr_arrayWithObjects)) {
+    if (Msg->getNumArgs() == 0)
+      return false;
+    const Expr *SentinelExpr = Msg->getArg(Msg->getNumArgs() - 1);
+    if (!NS.getASTContext().isSentinelNullExpr(SentinelExpr))
+      return false;
+
+    if (Msg->getNumArgs() == 1) {
+      commit.replace(MsgRange, "@[]");
+      return true;
+    }
+    SourceRange ArgRange(Msg->getArg(0)->getLocStart(),
+                         Msg->getArg(Msg->getNumArgs()-2)->getLocEnd());
+    commit.replaceWithInner(MsgRange, ArgRange);
+    commit.insertWrap("@[", ArgRange, "]");
+    return true;
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// rewriteToDictionaryLiteral.
+//===----------------------------------------------------------------------===//
+
+static bool rewriteToDictionaryLiteral(const ObjCMessageExpr *Msg,
+                                       const NSAPI &NS, Commit &commit) {
+  Selector Sel = Msg->getSelector();
+  SourceRange MsgRange = Msg->getSourceRange();
+
+  if (Sel == NS.getNSDictionarySelector(NSAPI::NSDict_dictionary)) {
+    if (Msg->getNumArgs() != 0)
+      return false;
+    commit.replace(MsgRange, "@{}");
+    return true;
+  }
+
+  if (Sel == NS.getNSDictionarySelector(
+                                    NSAPI::NSDict_dictionaryWithObjectForKey)) {
+    if (Msg->getNumArgs() != 2)
+      return false;
+    SourceRange ValRange = Msg->getArg(0)->getSourceRange();
+    SourceRange KeyRange = Msg->getArg(1)->getSourceRange();
+    // Insert key before the value.
+    commit.insertBefore(ValRange.getBegin(), ": ");
+    commit.insertFromRange(ValRange.getBegin(),
+                           CharSourceRange::getTokenRange(KeyRange),
+                       /*afterToken=*/false, /*beforePreviousInsertions=*/true);
+    commit.insertBefore(ValRange.getBegin(), "@{");
+    commit.insertAfterToken(ValRange.getEnd(), "}");
+    commit.replaceWithInner(MsgRange, ValRange);
+    return true;
+  }
+
+  if (Sel == NS.getNSDictionarySelector(
+                                  NSAPI::NSDict_dictionaryWithObjectsAndKeys)) {
+    if (Msg->getNumArgs() % 2 != 1)
+      return false;
+    unsigned SentinelIdx = Msg->getNumArgs() - 1;
+    const Expr *SentinelExpr = Msg->getArg(SentinelIdx);
+    if (!NS.getASTContext().isSentinelNullExpr(SentinelExpr))
+      return false;
+
+    if (Msg->getNumArgs() == 1) {
+      commit.replace(MsgRange, "@{}");
+      return true;
+    }
+
+    for (unsigned i = 0; i < SentinelIdx; i += 2) {
+      SourceRange ValRange = Msg->getArg(i)->getSourceRange();
+      SourceRange KeyRange = Msg->getArg(i+1)->getSourceRange();
+      // Insert value after key.
+      commit.insertAfterToken(KeyRange.getEnd(), ": ");
+      commit.insertFromRange(KeyRange.getEnd(), ValRange, /*afterToken=*/true);
+      commit.remove(CharSourceRange::getCharRange(ValRange.getBegin(),
+                                                  KeyRange.getBegin()));
+    }
+    // Range of arguments up until and including the last key.
+    // The sentinel and first value are cut off, the value will move after the
+    // key.
+    SourceRange ArgRange(Msg->getArg(1)->getLocStart(),
+                         Msg->getArg(SentinelIdx-1)->getLocEnd());
+    commit.insertWrap("@{", ArgRange, "}");
+    commit.replaceWithInner(MsgRange, ArgRange);
+    return true;
+  }
+
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// rewriteToNumberLiteral.
+//===----------------------------------------------------------------------===//
+
+static bool rewriteToCharLiteral(const ObjCMessageExpr *Msg,
+                                   const CharacterLiteral *Arg,
+                                   const NSAPI &NS, Commit &commit) {
+  if (Arg->getKind() != CharacterLiteral::Ascii)
+    return false;
+  if (NS.isNSNumberLiteralSelector(NSAPI::NSNumberWithChar,
+                                   Msg->getSelector())) {
+    SourceRange ArgRange = Arg->getSourceRange();
+    commit.replaceWithInner(Msg->getSourceRange(), ArgRange);
+    commit.insert(ArgRange.getBegin(), "@");
+    return true;
+  }
+
+  return false;
+}
+
+static bool rewriteToBoolLiteral(const ObjCMessageExpr *Msg,
+                                   const Expr *Arg,
+                                   const NSAPI &NS, Commit &commit) {
+  if (NS.isNSNumberLiteralSelector(NSAPI::NSNumberWithBool,
+                                   Msg->getSelector())) {
+    SourceRange ArgRange = Arg->getSourceRange();
+    commit.replaceWithInner(Msg->getSourceRange(), ArgRange);
+    commit.insert(ArgRange.getBegin(), "@");
+    return true;
+  }
+
+  return false;
+}
+
+namespace {
+
+struct LiteralInfo {
+  bool Hex, Octal;
+  StringRef U, F, L, LL;
+  CharSourceRange WithoutSuffRange;
+};
+
+}
+
+static bool getLiteralInfo(SourceRange literalRange,
+                           bool isFloat, bool isIntZero,
+                          ASTContext &Ctx, LiteralInfo &Info) {
+  if (literalRange.getBegin().isMacroID() ||
+      literalRange.getEnd().isMacroID())
+    return false;
+  StringRef text = Lexer::getSourceText(
+                                  CharSourceRange::getTokenRange(literalRange),
+                                  Ctx.getSourceManager(), Ctx.getLangOptions());
+  if (text.empty())
+    return false;
+
+  llvm::Optional<bool> UpperU, UpperL; 
+  bool UpperF = false;
+
+  struct Suff {
+    static bool has(StringRef suff, StringRef &text) {
+      if (text.endswith(suff)) {
+        text = text.substr(0, text.size()-suff.size());
+        return true;
+      }
+      return false;
+    }
+  };
+
+  while (1) {
+    if (Suff::has("u", text)) {
+      UpperU = false;
+    } else if (Suff::has("U", text)) {
+      UpperU = true;
+    } else if (Suff::has("ll", text)) {
+      UpperL = false;
+    } else if (Suff::has("LL", text)) {
+      UpperL = true;
+    } else if (Suff::has("l", text)) {
+      UpperL = false;
+    } else if (Suff::has("L", text)) {
+      UpperL = true;
+    } else if (isFloat && Suff::has("f", text)) {
+      UpperF = false;
+    } else if (isFloat && Suff::has("F", text)) {
+      UpperF = true;
+    } else
+      break;
+  }
+  
+  if (!UpperU.hasValue() && !UpperL.hasValue())
+    UpperU = UpperL = true;
+  else if (UpperU.hasValue() && !UpperL.hasValue())
+    UpperL = UpperU;
+  else if (UpperL.hasValue() && !UpperU.hasValue())
+    UpperU = UpperL;
+
+  Info.U = *UpperU ? "U" : "u";
+  Info.L = *UpperL ? "L" : "l";
+  Info.LL = *UpperL ? "LL" : "ll";
+  Info.F = UpperF ? "F" : "f";
+  
+  Info.Hex = Info.Octal = false;
+  if (text.startswith("0x"))
+    Info.Hex = true;
+  else if (!isFloat && !isIntZero && text.startswith("0"))
+    Info.Octal = true;
+
+  SourceLocation B = literalRange.getBegin();
+  Info.WithoutSuffRange =
+      CharSourceRange::getCharRange(B, B.getLocWithOffset(text.size()));
+  return true;
+}
+
+static bool rewriteToNumberLiteral(const ObjCMessageExpr *Msg,
+                                   const NSAPI &NS, Commit &commit) {
+  if (Msg->getNumArgs() != 1)
+    return false;
+
+  const Expr *Arg = Msg->getArg(0)->IgnoreParenImpCasts();
+  if (const CharacterLiteral *CharE = dyn_cast<CharacterLiteral>(Arg))
+    return rewriteToCharLiteral(Msg, CharE, NS, commit);
+  if (const ObjCBoolLiteralExpr *BE = dyn_cast<ObjCBoolLiteralExpr>(Arg))
+    return rewriteToBoolLiteral(Msg, BE, NS, commit);
+  if (const CXXBoolLiteralExpr *BE = dyn_cast<CXXBoolLiteralExpr>(Arg))
+    return rewriteToBoolLiteral(Msg, BE, NS, commit);
+
+  const Expr *literalE = Arg;
+  if (const UnaryOperator *UOE = dyn_cast<UnaryOperator>(literalE)) {
+    if (UOE->getOpcode() == UO_Plus || UOE->getOpcode() == UO_Minus)
+      literalE = UOE->getSubExpr();
+  }
+
+  // Only integer and floating literals; non-literals or imaginary literal
+  // cannot be rewritten.
+  if (!isa<IntegerLiteral>(literalE) && !isa<FloatingLiteral>(literalE))
+    return false;
+
+  ASTContext &Ctx = NS.getASTContext();
+  Selector Sel = Msg->getSelector();
+  llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
+    MKOpt = NS.getNSNumberLiteralMethodKind(Sel);
+  if (!MKOpt)
+    return false;
+  NSAPI::NSNumberLiteralMethodKind MK = *MKOpt;
+
+  bool CallIsInteger = false, CallIsUnsigned = false;
+  bool CallIsLong = false, CallIsLongLong = false; 
+  bool CallIsFloating = false, CallIsDouble = false;
+
+  switch (MK) {
+  // We cannot have these calls with int/float literals.
+  case NSAPI::NSNumberWithChar:
+  case NSAPI::NSNumberWithUnsignedChar:
+  case NSAPI::NSNumberWithShort:
+  case NSAPI::NSNumberWithUnsignedShort:
+  case NSAPI::NSNumberWithBool:
+    return false;
+
+  case NSAPI::NSNumberWithUnsignedInt:
+  case NSAPI::NSNumberWithUnsignedInteger:
+    CallIsUnsigned = true;
+  case NSAPI::NSNumberWithInt:
+  case NSAPI::NSNumberWithInteger:
+    CallIsInteger = true;
+    break;
+
+  case NSAPI::NSNumberWithUnsignedLong:
+    CallIsUnsigned = true;
+  case NSAPI::NSNumberWithLong:
+    CallIsInteger = true; CallIsLong = true;
+    break;
+
+  case NSAPI::NSNumberWithUnsignedLongLong:
+    CallIsUnsigned = true;
+  case NSAPI::NSNumberWithLongLong:
+    CallIsInteger = true; CallIsLongLong = true;
+    break;
+
+  case NSAPI::NSNumberWithDouble:
+    CallIsDouble = true;
+  case NSAPI::NSNumberWithFloat:
+    CallIsFloating = true;
+    break;
+  }
+
+  SourceRange ArgRange = Arg->getSourceRange();
+  QualType ArgTy = Arg->getType();
+  QualType CallTy = Msg->getArg(0)->getType();
+
+  // Check for the easy case, the literal maps directly to the call.
+  if (Ctx.hasSameType(ArgTy, CallTy)) {
+    commit.replaceWithInner(Msg->getSourceRange(), ArgRange);
+    commit.insert(ArgRange.getBegin(), "@");
+    return true;
+  }
+
+  // We will need to modify the literal suffix to get the same type as the call.
+  // Don't even try if it came from a macro.
+  if (ArgRange.getBegin().isMacroID())
+    return false;
+
+  bool LitIsFloat = ArgTy->isFloatingType();
+  // For a float passed to integer call, don't try rewriting. It is difficult
+  // and a very uncommon case anyway.
+  if (LitIsFloat && !CallIsFloating)
+    return false;
+
+  // Try to modify the literal make it the same type as the method call.
+  // -Modify the suffix, and/or
+  // -Change integer to float
+  
+  LiteralInfo LitInfo;
+  bool isIntZero = false;
+  if (const IntegerLiteral *IntE = dyn_cast<IntegerLiteral>(literalE))
+    isIntZero = !IntE->getValue().getBoolValue();
+  if (!getLiteralInfo(ArgRange, LitIsFloat, isIntZero, Ctx, LitInfo))
+    return false;
+
+  // Not easy to do int -> float with hex/octal and uncommon anyway.
+  if (!LitIsFloat && CallIsFloating && (LitInfo.Hex || LitInfo.Octal))
+    return false;
+  
+  SourceLocation LitB = LitInfo.WithoutSuffRange.getBegin();
+  SourceLocation LitE = LitInfo.WithoutSuffRange.getEnd();
+
+  commit.replaceWithInner(CharSourceRange::getTokenRange(Msg->getSourceRange()),
+                         LitInfo.WithoutSuffRange);
+  commit.insert(LitB, "@");
+
+  if (!LitIsFloat && CallIsFloating)
+    commit.insert(LitE, ".0");
+
+  if (CallIsFloating) {
+    if (!CallIsDouble)
+      commit.insert(LitE, LitInfo.F);
+  } else {
+    if (CallIsUnsigned)
+      commit.insert(LitE, LitInfo.U);
+  
+    if (CallIsLong)
+      commit.insert(LitE, LitInfo.L);
+    else if (CallIsLongLong)
+      commit.insert(LitE, LitInfo.LL);
+  }
+  return true;
+}

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Mar  6 14:06:33 2012
@@ -428,6 +428,7 @@
   case frontend::RewriteObjC:            return "-rewrite-objc";
   case frontend::RewriteTest:            return "-rewrite-test";
   case frontend::RunAnalysis:            return "-analyze";
+  case frontend::MigrateSource:          return "-migrate";
   case frontend::RunPreprocessorOnly:    return "-Eonly";
   }
 
@@ -483,9 +484,9 @@
     Res.push_back("-arcmt-migrate");
     break;
   }
-  if (!Opts.ARCMTMigrateDir.empty()) {
-    Res.push_back("-arcmt-migrate-directory");
-    Res.push_back(Opts.ARCMTMigrateDir);
+  if (!Opts.MTMigrateDir.empty()) {
+    Res.push_back("-mt-migrate-directory");
+    Res.push_back(Opts.MTMigrateDir);
   }
   if (!Opts.ARCMTMigrateReportOut.empty()) {
     Res.push_back("-arcmt-migrate-report-output");
@@ -494,6 +495,11 @@
   if (Opts.ARCMTMigrateEmitARCErrors)
     Res.push_back("-arcmt-migrate-emit-errors");
 
+  if (Opts.ObjCMTAction & ~FrontendOptions::ObjCMT_Literals)
+    Res.push_back("-objcmt-migrate-literals");
+  if (Opts.ObjCMTAction & ~FrontendOptions::ObjCMT_Subscripting)
+    Res.push_back("-objcmt-migrate-subscripting");
+
   bool NeedLang = false;
   for (unsigned i = 0, e = Opts.Inputs.size(); i != e; ++i)
     if (FrontendOptions::getInputKindForExtension(Opts.Inputs[i].File) !=
@@ -828,6 +834,8 @@
     Res.push_back("-fdebugger-support");
   if (Opts.DebuggerCastResultToId)
     Res.push_back("-fdebugger-cast-result-to-id");
+  if (Opts.DebuggerObjCLiteral)
+    Res.push_back("-fdebugger-objc-literal");
   if (Opts.DelayedTemplateParsing)
     Res.push_back("-fdelayed-template-parsing");
   if (Opts.Deprecated)
@@ -1376,6 +1384,8 @@
       Opts.ProgramAction = frontend::RewriteTest; break;
     case OPT_analyze:
       Opts.ProgramAction = frontend::RunAnalysis; break;
+    case OPT_migrate:
+      Opts.ProgramAction = frontend::MigrateSource; break;
     case OPT_Eonly:
       Opts.ProgramAction = frontend::RunPreprocessorOnly; break;
     }
@@ -1432,7 +1442,6 @@
   Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
   Opts.OverrideRecordLayoutsFile
     = Args.getLastArgValue(OPT_foverride_record_layout_EQ);
-  Opts.ARCMTAction = FrontendOptions::ARCMT_None;
   if (const Arg *A = Args.getLastArg(OPT_arcmt_check,
                                      OPT_arcmt_modify,
                                      OPT_arcmt_migrate)) {
@@ -1450,12 +1459,23 @@
       break;
     }
   }
-  Opts.ARCMTMigrateDir = Args.getLastArgValue(OPT_arcmt_migrate_directory);
+  Opts.MTMigrateDir = Args.getLastArgValue(OPT_mt_migrate_directory);
   Opts.ARCMTMigrateReportOut
     = Args.getLastArgValue(OPT_arcmt_migrate_report_output);
   Opts.ARCMTMigrateEmitARCErrors
     = Args.hasArg(OPT_arcmt_migrate_emit_arc_errors);
 
+  if (Args.hasArg(OPT_objcmt_migrate_literals))
+    Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals;
+  if (Args.hasArg(OPT_objcmt_migrate_subscripting))
+    Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting;
+
+  if (Opts.ARCMTAction != FrontendOptions::ARCMT_None &&
+      Opts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
+    Diags.Report(diag::err_drv_argument_not_allowed_with)
+      << "ARC migration" << "ObjC migration";
+  }
+
   InputKind DashX = IK_None;
   if (const Arg *A = Args.getLastArg(OPT_x)) {
     DashX = llvm::StringSwitch<InputKind>(A->getValue(Args))
@@ -1899,6 +1919,7 @@
   Opts.ParseUnknownAnytype = Args.hasArg(OPT_funknown_anytype);
   Opts.DebuggerSupport = Args.hasArg(OPT_fdebugger_support);
   Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
+  Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
   Opts.AddressSanitizer = Args.hasArg(OPT_faddress_sanitizer);
   Opts.ThreadSanitizer = Args.hasArg(OPT_fthread_sanitizer);
   Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);

Modified: cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp (original)
+++ cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp Tue Mar  6 14:06:33 2012
@@ -12,6 +12,9 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Frontend/DiagnosticOptions.h"
 #include "clang/Lex/Lexer.h"
+#include "clang/Edit/EditedSource.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -127,6 +130,54 @@
 
 DiagnosticRenderer::~DiagnosticRenderer() {}
 
+namespace {
+
+class FixitReceiver : public edit::EditsReceiver {
+  SmallVectorImpl<FixItHint> &MergedFixits;
+
+public:
+  FixitReceiver(SmallVectorImpl<FixItHint> &MergedFixits)
+    : MergedFixits(MergedFixits) { }
+  virtual void insert(SourceLocation loc, StringRef text) {
+    MergedFixits.push_back(FixItHint::CreateInsertion(loc, text));
+  }
+  virtual void replace(CharSourceRange range, StringRef text) {
+    MergedFixits.push_back(FixItHint::CreateReplacement(range, text));
+  }
+};
+
+}
+
+static void mergeFixits(ArrayRef<FixItHint> FixItHints,
+                        const SourceManager &SM, const LangOptions &LangOpts,
+                        SmallVectorImpl<FixItHint> &MergedFixits) {
+  edit::Commit commit(SM, LangOpts);
+  for (ArrayRef<FixItHint>::const_iterator
+         I = FixItHints.begin(), E = FixItHints.end(); I != E; ++I) {
+    const FixItHint &Hint = *I;
+    if (Hint.CodeToInsert.empty()) {
+      if (Hint.InsertFromRange.isValid())
+        commit.insertFromRange(Hint.RemoveRange.getBegin(),
+                           Hint.InsertFromRange, /*afterToken=*/false,
+                           Hint.BeforePreviousInsertions);
+      else
+        commit.remove(Hint.RemoveRange);
+    } else {
+      if (Hint.RemoveRange.isTokenRange() ||
+          Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd())
+        commit.replace(Hint.RemoveRange, Hint.CodeToInsert);
+      else
+        commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
+                    /*afterToken=*/false, Hint.BeforePreviousInsertions);
+    }
+  }
+
+  edit::EditedSource Editor(SM, LangOpts);
+  if (Editor.commit(commit)) {
+    FixitReceiver Rec(MergedFixits);
+    Editor.applyRewrites(Rec);
+  }
+}
 
 void DiagnosticRenderer::emitDiagnostic(SourceLocation Loc,
                                         DiagnosticsEngine::Level Level,
@@ -152,6 +203,12 @@
     SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
                                                    Ranges.end());
     
+    llvm::SmallVector<FixItHint, 8> MergedFixits;
+    if (!FixItHints.empty()) {
+      mergeFixits(FixItHints, SM, LangOpts, MergedFixits);
+      FixItHints = MergedFixits;
+    }
+
     for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(),
          E = FixItHints.end();
          I != E; ++I)

Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Tue Mar  6 14:06:33 2012
@@ -76,6 +76,7 @@
   case RewriteObjC:            return new RewriteObjCAction();
   case RewriteTest:            return new RewriteTestAction();
   case RunAnalysis:            return new ento::AnalysisAction();
+  case MigrateSource:          return new arcmt::MigrateSourceAction();
   case RunPreprocessorOnly:    return new PreprocessOnlyAction();
   }
   llvm_unreachable("Invalid program action!");
@@ -105,12 +106,18 @@
     break;
   case FrontendOptions::ARCMT_Migrate:
     Act = new arcmt::MigrateAction(Act,
-                                   FEOpts.ARCMTMigrateDir,
+                                   FEOpts.MTMigrateDir,
                                    FEOpts.ARCMTMigrateReportOut,
                                    FEOpts.ARCMTMigrateEmitARCErrors);
     break;
   }
 
+  if (FEOpts.ObjCMTAction != FrontendOptions::ObjCMT_None) {
+    Act = new arcmt::ObjCMigrateAction(Act, FEOpts.MTMigrateDir,
+                   FEOpts.ObjCMTAction & ~FrontendOptions::ObjCMT_Literals,
+                   FEOpts.ObjCMTAction & ~FrontendOptions::ObjCMT_Subscripting);
+  }
+
   // If there are any AST files to merge, create a frontend action
   // adaptor to perform the merge.
   if (!FEOpts.ASTMergeFiles.empty())

Modified: cfe/trunk/lib/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Makefile?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Makefile (original)
+++ cfe/trunk/lib/Makefile Tue Mar  6 14:06:33 2012
@@ -9,7 +9,7 @@
 CLANG_LEVEL := ..
 
 PARALLEL_DIRS = Headers Basic Lex Parse AST Sema CodeGen Analysis \
-                StaticAnalyzer Rewrite ARCMigrate Serialization Frontend \
+                StaticAnalyzer Edit Rewrite ARCMigrate Serialization Frontend \
                 FrontendTool Index Driver
 
 include $(CLANG_LEVEL)/Makefile

Modified: cfe/trunk/lib/Rewrite/FixItRewriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Rewrite/FixItRewriter.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/lib/Rewrite/FixItRewriter.cpp (original)
+++ cfe/trunk/lib/Rewrite/FixItRewriter.cpp Tue Mar  6 14:06:33 2012
@@ -14,6 +14,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Rewrite/FixItRewriter.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
@@ -29,6 +31,7 @@
                              const LangOptions &LangOpts,
                              FixItOptions *FixItOpts)
   : Diags(Diags),
+    Editor(SourceMgr, LangOpts),
     Rewrite(SourceMgr, LangOpts),
     FixItOpts(FixItOpts),
     NumFailures(0),
@@ -51,6 +54,24 @@
   return false;
 }
 
+namespace {
+
+class RewritesReceiver : public edit::EditsReceiver {
+  Rewriter &Rewrite;
+
+public:
+  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
+
+  virtual void insert(SourceLocation loc, StringRef text) {
+    Rewrite.InsertText(loc, text);
+  }
+  virtual void replace(CharSourceRange range, StringRef text) {
+    Rewrite.ReplaceText(range.getBegin(), Rewrite.getRangeSize(range), text);
+  }
+};
+
+}
+
 bool FixItRewriter::WriteFixedFiles(
             std::vector<std::pair<std::string, std::string> > *RewrittenFiles) {
   if (NumFailures > 0 && !FixItOpts->FixWhatYouCan) {
@@ -58,6 +79,9 @@
     return true;
   }
 
+  RewritesReceiver Rec(Rewrite);
+  Editor.applyRewrites(Rec);
+
   for (iterator I = buffer_begin(), E = buffer_end(); I != E; ++I) {
     const FileEntry *Entry = Rewrite.getSourceMgr().getFileEntryForID(I->first);
     int fd;
@@ -116,16 +140,28 @@
 
   // Make sure that we can perform all of the modifications we
   // in this diagnostic.
-  bool CanRewrite = Info.getNumFixItHints() > 0;
+  edit::Commit commit(Editor);
   for (unsigned Idx = 0, Last = Info.getNumFixItHints();
        Idx < Last; ++Idx) {
     const FixItHint &Hint = Info.getFixItHint(Idx);
-    if (Hint.RemoveRange.isValid() &&
-        Rewrite.getRangeSize(Hint.RemoveRange) == -1) {
-      CanRewrite = false;
-      break;
+
+    if (Hint.CodeToInsert.empty()) {
+      if (Hint.InsertFromRange.isValid())
+        commit.insertFromRange(Hint.RemoveRange.getBegin(),
+                           Hint.InsertFromRange, /*afterToken=*/false,
+                           Hint.BeforePreviousInsertions);
+      else
+        commit.remove(Hint.RemoveRange);
+    } else {
+      if (Hint.RemoveRange.isTokenRange() ||
+          Hint.RemoveRange.getBegin() != Hint.RemoveRange.getEnd())
+        commit.replace(Hint.RemoveRange, Hint.CodeToInsert);
+      else
+        commit.insert(Hint.RemoveRange.getBegin(), Hint.CodeToInsert,
+                    /*afterToken=*/false, Hint.BeforePreviousInsertions);
     }
   }
+  bool CanRewrite = Info.getNumFixItHints() > 0 && commit.isCommitable();
 
   if (!CanRewrite) {
     if (Info.getNumFixItHints() > 0)
@@ -138,27 +174,8 @@
     }
     return;
   }
-
-  bool Failed = false;
-  for (unsigned Idx = 0, Last = Info.getNumFixItHints();
-       Idx < Last; ++Idx) {
-    const FixItHint &Hint = Info.getFixItHint(Idx);
-
-    if (Hint.CodeToInsert.empty()) {
-      // We're removing code.
-      if (Rewrite.RemoveText(Hint.RemoveRange))
-        Failed = true;
-      continue;
-    }
-
-    // We're replacing code.
-    if (Rewrite.ReplaceText(Hint.RemoveRange.getBegin(),
-                            Rewrite.getRangeSize(Hint.RemoveRange),
-                            Hint.CodeToInsert))
-      Failed = true;
-  }
-
-  if (Failed) {
+  
+  if (!Editor.commit(commit)) {
     ++NumFailures;
     Diag(Info.getLocation(), diag::note_fixit_failed);
     return;

Added: cfe/trunk/test/ARCMT/dispatch.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/dispatch.m?rev=152141&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/dispatch.m (added)
+++ cfe/trunk/test/ARCMT/dispatch.m Tue Mar  6 14:06:33 2012
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
+// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t
+// RUN: diff %t %s.result
+
+#include "Common.h"
+
+#define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; })
+#define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; })
+#define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; })
+#define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; })
+
+typedef id dispatch_object_t;
+typedef id xpc_object_t;
+
+void _dispatch_object_validate(dispatch_object_t object);
+void _xpc_object_validate(xpc_object_t object);
+
+dispatch_object_t getme(void);
+
+void func(dispatch_object_t o) {
+  dispatch_retain(o);
+  dispatch_release(o);
+  dispatch_retain(getme());
+}
+
+void func2(xpc_object_t o) {
+  xpc_retain(o);
+  xpc_release(o);
+}

Added: cfe/trunk/test/ARCMT/dispatch.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/dispatch.m.result?rev=152141&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/dispatch.m.result (added)
+++ cfe/trunk/test/ARCMT/dispatch.m.result Tue Mar  6 14:06:33 2012
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -fobjc-arc -x objective-c %s.result
+// RUN: arcmt-test --args -triple x86_64-apple-darwin10 -fblocks -fsyntax-only -x objective-c %s > %t
+// RUN: diff %t %s.result
+
+#include "Common.h"
+
+#define dispatch_retain(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); (void)[_o retain]; })
+#define dispatch_release(object) ({ dispatch_object_t _o = (object); _dispatch_object_validate(_o); [_o release]; })
+#define xpc_retain(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o retain]; })
+#define xpc_release(object) ({ xpc_object_t _o = (object); _xpc_object_validate(_o); [_o release]; })
+
+typedef id dispatch_object_t;
+typedef id xpc_object_t;
+
+void _dispatch_object_validate(dispatch_object_t object);
+void _xpc_object_validate(xpc_object_t object);
+
+dispatch_object_t getme(void);
+
+void func(dispatch_object_t o) {
+  getme();
+}
+
+void func2(xpc_object_t o) {
+}

Modified: cfe/trunk/test/ARCMT/driver-migrate.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/driver-migrate.m?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/driver-migrate.m (original)
+++ cfe/trunk/test/ARCMT/driver-migrate.m Tue Mar  6 14:06:33 2012
@@ -1,6 +1,6 @@
 // RUN: %clang -### -ccc-arcmt-migrate /foo/bar -fsyntax-only %s 2>&1 | FileCheck %s
 
-// CHECK: "-arcmt-migrate" "-arcmt-migrate-directory" "{{[^"]*}}/foo/bar"
+// CHECK: "-arcmt-migrate" "-mt-migrate-directory" "{{[^"]*}}/foo/bar"
 
 // RUN: touch %t.o
 // RUN: %clang -ccc-arcmt-check -target i386-apple-darwin9 -### %t.o 2> %t.log

Modified: cfe/trunk/test/ARCMT/migrate-emit-errors.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/migrate-emit-errors.m?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/migrate-emit-errors.m (original)
+++ cfe/trunk/test/ARCMT/migrate-emit-errors.m Tue Mar  6 14:06:33 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t -arcmt-migrate-emit-errors %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t -arcmt-migrate-emit-errors %s 2>&1 | FileCheck %s
 // RUN: rm -rf %t
 
 @protocol NSObject

Modified: cfe/trunk/test/ARCMT/migrate-plist-output.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/migrate-plist-output.m?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/migrate-plist-output.m (original)
+++ cfe/trunk/test/ARCMT/migrate-plist-output.m Tue Mar  6 14:06:33 2012
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t.dir -arcmt-migrate-report-output %t.plist %s 
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t.dir -arcmt-migrate-report-output %t.plist %s 
 // RUN: FileCheck %s -input-file=%t.plist
 // RUN: rm -rf %t.dir
 

Modified: cfe/trunk/test/ARCMT/migrate-space-in-path.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/migrate-space-in-path.m?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/migrate-space-in-path.m (original)
+++ cfe/trunk/test/ARCMT/migrate-space-in-path.m Tue Mar  6 14:06:33 2012
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t.migrate
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t.migrate %S/"with space"/test1.m.in -x objective-c 
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t.migrate %S/"with space"/test2.m.in -x objective-c 
-// RUN: c-arcmt-test -arcmt-migrate-directory %t.migrate | arcmt-test -verify-transformed-files %S/"with space"/test1.m.in.result %S/"with space"/test2.m.in.result %S/"with space"/test.h.result
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t.migrate %S/"with space"/test1.m.in -x objective-c 
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t.migrate %S/"with space"/test2.m.in -x objective-c 
+// RUN: c-arcmt-test -mt-migrate-directory %t.migrate | arcmt-test -verify-transformed-files %S/"with space"/test1.m.in.result %S/"with space"/test2.m.in.result %S/"with space"/test.h.result
 // RUN: rm -rf %t.migrate
 // DISABLE: mingw32

Modified: cfe/trunk/test/ARCMT/migrate.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/migrate.m?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/migrate.m (original)
+++ cfe/trunk/test/ARCMT/migrate.m Tue Mar  6 14:06:33 2012
@@ -1,6 +1,6 @@
 // RUN: rm -rf %t
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c 
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c 
-// RUN: c-arcmt-test -arcmt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t %S/Inputs/test1.m.in -x objective-c 
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t %S/Inputs/test2.m.in -x objective-c 
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %S/Inputs/test1.m.in.result %S/Inputs/test2.m.in.result %S/Inputs/test.h.result
 // RUN: rm -rf %t
 // DISABLE: mingw32

Added: cfe/trunk/test/ARCMT/objcmt-numeric-literals.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-numeric-literals.m?rev=152141&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-numeric-literals.m (added)
+++ cfe/trunk/test/ARCMT/objcmt-numeric-literals.m Tue Mar  6 14:06:33 2012
@@ -0,0 +1,501 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ 
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+
+#define YES __objc_yes
+#define NO __objc_no
+
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef signed char BOOL;
+#define nil ((void*) 0)
+
+ at interface NSObject
++ (id)alloc;
+ at end
+
+ at interface NSNumber : NSObject
+ at end
+
+ at interface NSNumber (NSNumberCreation)
+- (id)initWithChar:(char)value;
+- (id)initWithUnsignedChar:(unsigned char)value;
+- (id)initWithShort:(short)value;
+- (id)initWithUnsignedShort:(unsigned short)value;
+- (id)initWithInt:(int)value;
+- (id)initWithUnsignedInt:(unsigned int)value;
+- (id)initWithLong:(long)value;
+- (id)initWithUnsignedLong:(unsigned long)value;
+- (id)initWithLongLong:(long long)value;
+- (id)initWithUnsignedLongLong:(unsigned long long)value;
+- (id)initWithFloat:(float)value;
+- (id)initWithDouble:(double)value;
+- (id)initWithBool:(BOOL)value;
+- (id)initWithInteger:(NSInteger)value;
+- (id)initWithUnsignedInteger:(NSUInteger)value;
+
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
++ (NSNumber *)numberWithInteger:(NSInteger)value;
++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value;
+ at end
+
+#define VAL_INT 2
+#define VAL_UINT 2U
+#define VAL_CHAR 'a'
+
+void foo() {
+  [NSNumber numberWithChar:'a'];
+  [NSNumber numberWithChar:L'a'];
+  [NSNumber numberWithChar:2];
+  [NSNumber numberWithChar:2U];
+  [NSNumber numberWithChar:2u];
+  [NSNumber numberWithChar:2L];
+  [NSNumber numberWithChar:2l];
+  [NSNumber numberWithChar:2LL];
+  [NSNumber numberWithChar:2ll];
+  [NSNumber numberWithChar:2ul];
+  [NSNumber numberWithChar:2lu];
+  [NSNumber numberWithChar:2ull];
+  [NSNumber numberWithChar:2llu];
+  [NSNumber numberWithChar:2.0];
+  [NSNumber numberWithChar:2.0f];
+  [NSNumber numberWithChar:2.0F];
+  [NSNumber numberWithChar:2.0l];
+  [NSNumber numberWithChar:2.0L];
+  [NSNumber numberWithChar:0x2f];
+  [NSNumber numberWithChar:04];
+  [NSNumber numberWithChar:0];
+  [NSNumber numberWithChar:0.0];
+  [NSNumber numberWithChar:YES];
+  [NSNumber numberWithChar:NO];
+  [NSNumber numberWithChar:true];
+  [NSNumber numberWithChar:false];
+  [NSNumber numberWithChar:VAL_INT];
+  [NSNumber numberWithChar:VAL_UINT];
+  [NSNumber numberWithChar:VAL_CHAR];
+
+  [NSNumber numberWithUnsignedChar:'a'];
+  [NSNumber numberWithUnsignedChar:L'a'];
+  [NSNumber numberWithUnsignedChar:2];
+  [NSNumber numberWithUnsignedChar:2U];
+  [NSNumber numberWithUnsignedChar:2u];
+  [NSNumber numberWithUnsignedChar:2L];
+  [NSNumber numberWithUnsignedChar:2l];
+  [NSNumber numberWithUnsignedChar:2LL];
+  [NSNumber numberWithUnsignedChar:2ll];
+  [NSNumber numberWithUnsignedChar:2ul];
+  [NSNumber numberWithUnsignedChar:2lu];
+  [NSNumber numberWithUnsignedChar:2ull];
+  [NSNumber numberWithUnsignedChar:2llu];
+  [NSNumber numberWithUnsignedChar:2.0];
+  [NSNumber numberWithUnsignedChar:2.0f];
+  [NSNumber numberWithUnsignedChar:2.0F];
+  [NSNumber numberWithUnsignedChar:2.0l];
+  [NSNumber numberWithUnsignedChar:2.0L];
+  [NSNumber numberWithUnsignedChar:0x2f];
+  [NSNumber numberWithUnsignedChar:04];
+  [NSNumber numberWithUnsignedChar:0];
+  [NSNumber numberWithUnsignedChar:0.0];
+  [NSNumber numberWithUnsignedChar:YES];
+  [NSNumber numberWithUnsignedChar:NO];
+  [NSNumber numberWithUnsignedChar:true];
+  [NSNumber numberWithUnsignedChar:false];
+  [NSNumber numberWithUnsignedChar:VAL_INT];
+  [NSNumber numberWithUnsignedChar:VAL_UINT];
+  [NSNumber numberWithUnsignedChar:VAL_CHAR];
+
+  [NSNumber numberWithShort:'a'];
+  [NSNumber numberWithShort:L'a'];
+  [NSNumber numberWithShort:2];
+  [NSNumber numberWithShort:2U];
+  [NSNumber numberWithShort:2u];
+  [NSNumber numberWithShort:2L];
+  [NSNumber numberWithShort:2l];
+  [NSNumber numberWithShort:2LL];
+  [NSNumber numberWithShort:2ll];
+  [NSNumber numberWithShort:2ul];
+  [NSNumber numberWithShort:2lu];
+  [NSNumber numberWithShort:2ull];
+  [NSNumber numberWithShort:2llu];
+  [NSNumber numberWithShort:2.0];
+  [NSNumber numberWithShort:2.0f];
+  [NSNumber numberWithShort:2.0F];
+  [NSNumber numberWithShort:2.0l];
+  [NSNumber numberWithShort:2.0L];
+  [NSNumber numberWithShort:0x2f];
+  [NSNumber numberWithShort:04];
+  [NSNumber numberWithShort:0];
+  [NSNumber numberWithShort:0.0];
+  [NSNumber numberWithShort:YES];
+  [NSNumber numberWithShort:NO];
+  [NSNumber numberWithShort:true];
+  [NSNumber numberWithShort:false];
+  [NSNumber numberWithShort:VAL_INT];
+  [NSNumber numberWithShort:VAL_UINT];
+
+  [NSNumber numberWithUnsignedShort:'a'];
+  [NSNumber numberWithUnsignedShort:L'a'];
+  [NSNumber numberWithUnsignedShort:2];
+  [NSNumber numberWithUnsignedShort:2U];
+  [NSNumber numberWithUnsignedShort:2u];
+  [NSNumber numberWithUnsignedShort:2L];
+  [NSNumber numberWithUnsignedShort:2l];
+  [NSNumber numberWithUnsignedShort:2LL];
+  [NSNumber numberWithUnsignedShort:2ll];
+  [NSNumber numberWithUnsignedShort:2ul];
+  [NSNumber numberWithUnsignedShort:2lu];
+  [NSNumber numberWithUnsignedShort:2ull];
+  [NSNumber numberWithUnsignedShort:2llu];
+  [NSNumber numberWithUnsignedShort:2.0];
+  [NSNumber numberWithUnsignedShort:2.0f];
+  [NSNumber numberWithUnsignedShort:2.0F];
+  [NSNumber numberWithUnsignedShort:2.0l];
+  [NSNumber numberWithUnsignedShort:2.0L];
+  [NSNumber numberWithUnsignedShort:0x2f];
+  [NSNumber numberWithUnsignedShort:04];
+  [NSNumber numberWithUnsignedShort:0];
+  [NSNumber numberWithUnsignedShort:0.0];
+  [NSNumber numberWithUnsignedShort:YES];
+  [NSNumber numberWithUnsignedShort:NO];
+  [NSNumber numberWithUnsignedShort:true];
+  [NSNumber numberWithUnsignedShort:false];
+  [NSNumber numberWithUnsignedShort:VAL_INT];
+  [NSNumber numberWithUnsignedShort:VAL_UINT];
+
+  [NSNumber numberWithInt:'a'];
+  [NSNumber numberWithInt:L'a'];
+  [NSNumber numberWithInt:2];
+  [NSNumber numberWithInt:2U];
+  [NSNumber numberWithInt:2u];
+  [NSNumber numberWithInt:2L];
+  [NSNumber numberWithInt:2l];
+  [NSNumber numberWithInt:2LL];
+  [NSNumber numberWithInt:2ll];
+  [NSNumber numberWithInt:2ul];
+  [NSNumber numberWithInt:2lu];
+  [NSNumber numberWithInt:2ull];
+  [NSNumber numberWithInt:2llu];
+  [NSNumber numberWithInt:2.0];
+  [NSNumber numberWithInt:2.0f];
+  [NSNumber numberWithInt:2.0F];
+  [NSNumber numberWithInt:2.0l];
+  [NSNumber numberWithInt:2.0L];
+  [NSNumber numberWithInt:0x2f];
+  [NSNumber numberWithInt:04];
+  [NSNumber numberWithInt:0];
+  [NSNumber numberWithInt:0.0];
+  [NSNumber numberWithInt:YES];
+  [NSNumber numberWithInt:NO];
+  [NSNumber numberWithInt:true];
+  [NSNumber numberWithInt:false];
+  [NSNumber numberWithInt:VAL_INT];
+  [NSNumber numberWithInt:VAL_UINT];
+
+  (void)[[NSNumber alloc] initWithInt:2];
+  (void)[[NSNumber alloc] initWithInt:2U];
+
+  [NSNumber numberWithInt:+2];
+  [NSNumber numberWithInt:-2];
+
+  [NSNumber numberWithUnsignedInt:'a'];
+  [NSNumber numberWithUnsignedInt:L'a'];
+  [NSNumber numberWithUnsignedInt:2];
+  [NSNumber numberWithUnsignedInt:2U];
+  [NSNumber numberWithUnsignedInt:2u];
+  [NSNumber numberWithUnsignedInt:2L];
+  [NSNumber numberWithUnsignedInt:2l];
+  [NSNumber numberWithUnsignedInt:2LL];
+  [NSNumber numberWithUnsignedInt:2ll];
+  [NSNumber numberWithUnsignedInt:2ul];
+  [NSNumber numberWithUnsignedInt:2lu];
+  [NSNumber numberWithUnsignedInt:2ull];
+  [NSNumber numberWithUnsignedInt:2llu];
+  [NSNumber numberWithUnsignedInt:2.0];
+  [NSNumber numberWithUnsignedInt:2.0f];
+  [NSNumber numberWithUnsignedInt:2.0F];
+  [NSNumber numberWithUnsignedInt:2.0l];
+  [NSNumber numberWithUnsignedInt:2.0L];
+  [NSNumber numberWithUnsignedInt:0x2f];
+  [NSNumber numberWithUnsignedInt:04];
+  [NSNumber numberWithUnsignedInt:0];
+  [NSNumber numberWithUnsignedInt:0.0];
+  [NSNumber numberWithUnsignedInt:YES];
+  [NSNumber numberWithUnsignedInt:NO];
+  [NSNumber numberWithUnsignedInt:true];
+  [NSNumber numberWithUnsignedInt:false];
+  [NSNumber numberWithUnsignedInt:VAL_INT];
+  [NSNumber numberWithUnsignedInt:VAL_UINT];
+
+  [NSNumber numberWithLong:'a'];
+  [NSNumber numberWithLong:L'a'];
+  [NSNumber numberWithLong:2];
+  [NSNumber numberWithLong:2U];
+  [NSNumber numberWithLong:2u];
+  [NSNumber numberWithLong:2L];
+  [NSNumber numberWithLong:2l];
+  [NSNumber numberWithLong:2LL];
+  [NSNumber numberWithLong:2ll];
+  [NSNumber numberWithLong:2ul];
+  [NSNumber numberWithLong:2lu];
+  [NSNumber numberWithLong:2ull];
+  [NSNumber numberWithLong:2llu];
+  [NSNumber numberWithLong:2.0];
+  [NSNumber numberWithLong:2.0f];
+  [NSNumber numberWithLong:2.0F];
+  [NSNumber numberWithLong:2.0l];
+  [NSNumber numberWithLong:2.0L];
+  [NSNumber numberWithLong:0x2f];
+  [NSNumber numberWithLong:04];
+  [NSNumber numberWithLong:0];
+  [NSNumber numberWithLong:0.0];
+  [NSNumber numberWithLong:YES];
+  [NSNumber numberWithLong:NO];
+  [NSNumber numberWithLong:true];
+  [NSNumber numberWithLong:false];
+  [NSNumber numberWithLong:VAL_INT];
+  [NSNumber numberWithLong:VAL_UINT];
+
+  [NSNumber numberWithUnsignedLong:'a'];
+  [NSNumber numberWithUnsignedLong:L'a'];
+  [NSNumber numberWithUnsignedLong:2];
+  [NSNumber numberWithUnsignedLong:2U];
+  [NSNumber numberWithUnsignedLong:2u];
+  [NSNumber numberWithUnsignedLong:2L];
+  [NSNumber numberWithUnsignedLong:2l];
+  [NSNumber numberWithUnsignedLong:2LL];
+  [NSNumber numberWithUnsignedLong:2ll];
+  [NSNumber numberWithUnsignedLong:2ul];
+  [NSNumber numberWithUnsignedLong:2lu];
+  [NSNumber numberWithUnsignedLong:2ull];
+  [NSNumber numberWithUnsignedLong:2llu];
+  [NSNumber numberWithUnsignedLong:2.0];
+  [NSNumber numberWithUnsignedLong:2.0f];
+  [NSNumber numberWithUnsignedLong:2.0F];
+  [NSNumber numberWithUnsignedLong:2.0l];
+  [NSNumber numberWithUnsignedLong:2.0L];
+  [NSNumber numberWithUnsignedLong:0x2f];
+  [NSNumber numberWithUnsignedLong:04];
+  [NSNumber numberWithUnsignedLong:0];
+  [NSNumber numberWithUnsignedLong:0.0];
+  [NSNumber numberWithUnsignedLong:YES];
+  [NSNumber numberWithUnsignedLong:NO];
+  [NSNumber numberWithUnsignedLong:true];
+  [NSNumber numberWithUnsignedLong:false];
+  [NSNumber numberWithUnsignedLong:VAL_INT];
+  [NSNumber numberWithUnsignedLong:VAL_UINT];
+
+  [NSNumber numberWithLongLong:'a'];
+  [NSNumber numberWithLongLong:L'a'];
+  [NSNumber numberWithLongLong:2];
+  [NSNumber numberWithLongLong:2U];
+  [NSNumber numberWithLongLong:2u];
+  [NSNumber numberWithLongLong:2L];
+  [NSNumber numberWithLongLong:2l];
+  [NSNumber numberWithLongLong:2LL];
+  [NSNumber numberWithLongLong:2ll];
+  [NSNumber numberWithLongLong:2ul];
+  [NSNumber numberWithLongLong:2lu];
+  [NSNumber numberWithLongLong:2ull];
+  [NSNumber numberWithLongLong:2llu];
+  [NSNumber numberWithLongLong:2.0];
+  [NSNumber numberWithLongLong:2.0f];
+  [NSNumber numberWithLongLong:2.0F];
+  [NSNumber numberWithLongLong:2.0l];
+  [NSNumber numberWithLongLong:2.0L];
+  [NSNumber numberWithLongLong:0x2f];
+  [NSNumber numberWithLongLong:04];
+  [NSNumber numberWithLongLong:0];
+  [NSNumber numberWithLongLong:0.0];
+  [NSNumber numberWithLongLong:YES];
+  [NSNumber numberWithLongLong:NO];
+  [NSNumber numberWithLongLong:true];
+  [NSNumber numberWithLongLong:false];
+  [NSNumber numberWithLongLong:VAL_INT];
+  [NSNumber numberWithLongLong:VAL_UINT];
+
+  [NSNumber numberWithUnsignedLongLong:'a'];
+  [NSNumber numberWithUnsignedLongLong:L'a'];
+  [NSNumber numberWithUnsignedLongLong:2];
+  [NSNumber numberWithUnsignedLongLong:2U];
+  [NSNumber numberWithUnsignedLongLong:2u];
+  [NSNumber numberWithUnsignedLongLong:2L];
+  [NSNumber numberWithUnsignedLongLong:2l];
+  [NSNumber numberWithUnsignedLongLong:2LL];
+  [NSNumber numberWithUnsignedLongLong:2ll];
+  [NSNumber numberWithUnsignedLongLong:2ul];
+  [NSNumber numberWithUnsignedLongLong:2lu];
+  [NSNumber numberWithUnsignedLongLong:2ull];
+  [NSNumber numberWithUnsignedLongLong:2llu];
+  [NSNumber numberWithUnsignedLongLong:2.0];
+  [NSNumber numberWithUnsignedLongLong:2.0f];
+  [NSNumber numberWithUnsignedLongLong:2.0F];
+  [NSNumber numberWithUnsignedLongLong:2.0l];
+  [NSNumber numberWithUnsignedLongLong:2.0L];
+  [NSNumber numberWithUnsignedLongLong:0x2f];
+  [NSNumber numberWithUnsignedLongLong:04];
+  [NSNumber numberWithUnsignedLongLong:0];
+  [NSNumber numberWithUnsignedLongLong:0.0];
+  [NSNumber numberWithUnsignedLongLong:YES];
+  [NSNumber numberWithUnsignedLongLong:NO];
+  [NSNumber numberWithUnsignedLongLong:true];
+  [NSNumber numberWithUnsignedLongLong:false];
+  [NSNumber numberWithUnsignedLongLong:VAL_INT];
+  [NSNumber numberWithUnsignedLongLong:VAL_UINT];
+
+  [NSNumber numberWithFloat:'a'];
+  [NSNumber numberWithFloat:L'a'];
+  [NSNumber numberWithFloat:2];
+  [NSNumber numberWithFloat:2U];
+  [NSNumber numberWithFloat:2u];
+  [NSNumber numberWithFloat:2L];
+  [NSNumber numberWithFloat:2l];
+  [NSNumber numberWithFloat:2LL];
+  [NSNumber numberWithFloat:2ll];
+  [NSNumber numberWithFloat:2ul];
+  [NSNumber numberWithFloat:2lu];
+  [NSNumber numberWithFloat:2ull];
+  [NSNumber numberWithFloat:2llu];
+  [NSNumber numberWithFloat:2.0];
+  [NSNumber numberWithFloat:2.0f];
+  [NSNumber numberWithFloat:2.0F];
+  [NSNumber numberWithFloat:2.0l];
+  [NSNumber numberWithFloat:2.0L];
+  [NSNumber numberWithFloat:0x2f];
+  [NSNumber numberWithFloat:04];
+  [NSNumber numberWithFloat:0];
+  [NSNumber numberWithFloat:0.0];
+  [NSNumber numberWithFloat:YES];
+  [NSNumber numberWithFloat:NO];
+  [NSNumber numberWithFloat:true];
+  [NSNumber numberWithFloat:false];
+  [NSNumber numberWithFloat:VAL_INT];
+  [NSNumber numberWithFloat:VAL_UINT];
+
+  [NSNumber numberWithDouble:'a'];
+  [NSNumber numberWithDouble:L'a'];
+  [NSNumber numberWithDouble:2];
+  [NSNumber numberWithDouble:2U];
+  [NSNumber numberWithDouble:2u];
+  [NSNumber numberWithDouble:2L];
+  [NSNumber numberWithDouble:2l];
+  [NSNumber numberWithDouble:2LL];
+  [NSNumber numberWithDouble:2ll];
+  [NSNumber numberWithDouble:2ul];
+  [NSNumber numberWithDouble:2lu];
+  [NSNumber numberWithDouble:2ull];
+  [NSNumber numberWithDouble:2llu];
+  [NSNumber numberWithDouble:2.0];
+  [NSNumber numberWithDouble:2.0f];
+  [NSNumber numberWithDouble:2.0F];
+  [NSNumber numberWithDouble:2.0l];
+  [NSNumber numberWithDouble:2.0L];
+  [NSNumber numberWithDouble:0x2f];
+  [NSNumber numberWithDouble:04];
+  [NSNumber numberWithDouble:0];
+  [NSNumber numberWithDouble:0.0];
+  [NSNumber numberWithDouble:YES];
+  [NSNumber numberWithDouble:NO];
+  [NSNumber numberWithDouble:true];
+  [NSNumber numberWithDouble:false];
+  [NSNumber numberWithDouble:VAL_INT];
+  [NSNumber numberWithDouble:VAL_UINT];
+
+  [NSNumber numberWithBool:'a'];
+  [NSNumber numberWithBool:L'a'];
+  [NSNumber numberWithBool:2];
+  [NSNumber numberWithBool:2U];
+  [NSNumber numberWithBool:2u];
+  [NSNumber numberWithBool:2L];
+  [NSNumber numberWithBool:2l];
+  [NSNumber numberWithBool:2LL];
+  [NSNumber numberWithBool:2ll];
+  [NSNumber numberWithBool:2ul];
+  [NSNumber numberWithBool:2lu];
+  [NSNumber numberWithBool:2ull];
+  [NSNumber numberWithBool:2llu];
+  [NSNumber numberWithBool:2.0];
+  [NSNumber numberWithBool:2.0f];
+  [NSNumber numberWithBool:2.0F];
+  [NSNumber numberWithBool:2.0l];
+  [NSNumber numberWithBool:2.0L];
+  [NSNumber numberWithBool:0x2f];
+  [NSNumber numberWithBool:04];
+  [NSNumber numberWithBool:0];
+  [NSNumber numberWithBool:0.0];
+  [NSNumber numberWithBool:YES];
+  [NSNumber numberWithBool:NO];
+  [NSNumber numberWithBool:true];
+  [NSNumber numberWithBool:false];
+  [NSNumber numberWithBool:VAL_INT];
+  [NSNumber numberWithBool:VAL_UINT];
+
+  [NSNumber numberWithInteger:'a'];
+  [NSNumber numberWithInteger:L'a'];
+  [NSNumber numberWithInteger:2];
+  [NSNumber numberWithInteger:2U];
+  [NSNumber numberWithInteger:2u];
+  [NSNumber numberWithInteger:2L];
+  [NSNumber numberWithInteger:2l];
+  [NSNumber numberWithInteger:2LL];
+  [NSNumber numberWithInteger:2ll];
+  [NSNumber numberWithInteger:2ul];
+  [NSNumber numberWithInteger:2lu];
+  [NSNumber numberWithInteger:2ull];
+  [NSNumber numberWithInteger:2llu];
+  [NSNumber numberWithInteger:2.0];
+  [NSNumber numberWithInteger:2.0f];
+  [NSNumber numberWithInteger:2.0F];
+  [NSNumber numberWithInteger:2.0l];
+  [NSNumber numberWithInteger:2.0L];
+  [NSNumber numberWithInteger:0x2f];
+  [NSNumber numberWithInteger:04];
+  [NSNumber numberWithInteger:0];
+  [NSNumber numberWithInteger:0.0];
+  [NSNumber numberWithInteger:YES];
+  [NSNumber numberWithInteger:NO];
+  [NSNumber numberWithInteger:true];
+  [NSNumber numberWithInteger:false];
+  [NSNumber numberWithInteger:VAL_INT];
+  [NSNumber numberWithInteger:VAL_UINT];
+
+  [NSNumber numberWithUnsignedInteger:'a'];
+  [NSNumber numberWithUnsignedInteger:L'a'];
+  [NSNumber numberWithUnsignedInteger:2];
+  [NSNumber numberWithUnsignedInteger:2U];
+  [NSNumber numberWithUnsignedInteger:2u];
+  [NSNumber numberWithUnsignedInteger:2L];
+  [NSNumber numberWithUnsignedInteger:2l];
+  [NSNumber numberWithUnsignedInteger:2LL];
+  [NSNumber numberWithUnsignedInteger:2ll];
+  [NSNumber numberWithUnsignedInteger:2ul];
+  [NSNumber numberWithUnsignedInteger:2lu];
+  [NSNumber numberWithUnsignedInteger:2ull];
+  [NSNumber numberWithUnsignedInteger:2llu];
+  [NSNumber numberWithUnsignedInteger:2.0];
+  [NSNumber numberWithUnsignedInteger:2.0f];
+  [NSNumber numberWithUnsignedInteger:2.0F];
+  [NSNumber numberWithUnsignedInteger:2.0l];
+  [NSNumber numberWithUnsignedInteger:2.0L];
+  [NSNumber numberWithUnsignedInteger:0x2f];
+  [NSNumber numberWithUnsignedInteger:04];
+  [NSNumber numberWithUnsignedInteger:0];
+  [NSNumber numberWithUnsignedInteger:0.0];
+  [NSNumber numberWithUnsignedInteger:YES];
+  [NSNumber numberWithUnsignedInteger:NO];
+  [NSNumber numberWithUnsignedInteger:true];
+  [NSNumber numberWithUnsignedInteger:false];
+  [NSNumber numberWithUnsignedInteger:VAL_INT];
+  [NSNumber numberWithUnsignedInteger:VAL_UINT];
+}

Added: cfe/trunk/test/ARCMT/objcmt-numeric-literals.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-numeric-literals.m.result?rev=152141&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-numeric-literals.m.result (added)
+++ cfe/trunk/test/ARCMT/objcmt-numeric-literals.m.result Tue Mar  6 14:06:33 2012
@@ -0,0 +1,501 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c++ 
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+
+#define YES __objc_yes
+#define NO __objc_no
+
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+typedef signed char BOOL;
+#define nil ((void*) 0)
+
+ at interface NSObject
++ (id)alloc;
+ at end
+
+ at interface NSNumber : NSObject
+ at end
+
+ at interface NSNumber (NSNumberCreation)
+- (id)initWithChar:(char)value;
+- (id)initWithUnsignedChar:(unsigned char)value;
+- (id)initWithShort:(short)value;
+- (id)initWithUnsignedShort:(unsigned short)value;
+- (id)initWithInt:(int)value;
+- (id)initWithUnsignedInt:(unsigned int)value;
+- (id)initWithLong:(long)value;
+- (id)initWithUnsignedLong:(unsigned long)value;
+- (id)initWithLongLong:(long long)value;
+- (id)initWithUnsignedLongLong:(unsigned long long)value;
+- (id)initWithFloat:(float)value;
+- (id)initWithDouble:(double)value;
+- (id)initWithBool:(BOOL)value;
+- (id)initWithInteger:(NSInteger)value;
+- (id)initWithUnsignedInteger:(NSUInteger)value;
+
++ (NSNumber *)numberWithChar:(char)value;
++ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
++ (NSNumber *)numberWithShort:(short)value;
++ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
++ (NSNumber *)numberWithInt:(int)value;
++ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
++ (NSNumber *)numberWithLong:(long)value;
++ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
++ (NSNumber *)numberWithLongLong:(long long)value;
++ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
++ (NSNumber *)numberWithFloat:(float)value;
++ (NSNumber *)numberWithDouble:(double)value;
++ (NSNumber *)numberWithBool:(BOOL)value;
++ (NSNumber *)numberWithInteger:(NSInteger)value;
++ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value;
+ at end
+
+#define VAL_INT 2
+#define VAL_UINT 2U
+#define VAL_CHAR 'a'
+
+void foo() {
+  @'a';
+  [NSNumber numberWithChar:L'a'];
+  [NSNumber numberWithChar:2];
+  [NSNumber numberWithChar:2U];
+  [NSNumber numberWithChar:2u];
+  [NSNumber numberWithChar:2L];
+  [NSNumber numberWithChar:2l];
+  [NSNumber numberWithChar:2LL];
+  [NSNumber numberWithChar:2ll];
+  [NSNumber numberWithChar:2ul];
+  [NSNumber numberWithChar:2lu];
+  [NSNumber numberWithChar:2ull];
+  [NSNumber numberWithChar:2llu];
+  [NSNumber numberWithChar:2.0];
+  [NSNumber numberWithChar:2.0f];
+  [NSNumber numberWithChar:2.0F];
+  [NSNumber numberWithChar:2.0l];
+  [NSNumber numberWithChar:2.0L];
+  [NSNumber numberWithChar:0x2f];
+  [NSNumber numberWithChar:04];
+  [NSNumber numberWithChar:0];
+  [NSNumber numberWithChar:0.0];
+  [NSNumber numberWithChar:YES];
+  [NSNumber numberWithChar:NO];
+  [NSNumber numberWithChar:true];
+  [NSNumber numberWithChar:false];
+  [NSNumber numberWithChar:VAL_INT];
+  [NSNumber numberWithChar:VAL_UINT];
+  @VAL_CHAR;
+
+  [NSNumber numberWithUnsignedChar:'a'];
+  [NSNumber numberWithUnsignedChar:L'a'];
+  [NSNumber numberWithUnsignedChar:2];
+  [NSNumber numberWithUnsignedChar:2U];
+  [NSNumber numberWithUnsignedChar:2u];
+  [NSNumber numberWithUnsignedChar:2L];
+  [NSNumber numberWithUnsignedChar:2l];
+  [NSNumber numberWithUnsignedChar:2LL];
+  [NSNumber numberWithUnsignedChar:2ll];
+  [NSNumber numberWithUnsignedChar:2ul];
+  [NSNumber numberWithUnsignedChar:2lu];
+  [NSNumber numberWithUnsignedChar:2ull];
+  [NSNumber numberWithUnsignedChar:2llu];
+  [NSNumber numberWithUnsignedChar:2.0];
+  [NSNumber numberWithUnsignedChar:2.0f];
+  [NSNumber numberWithUnsignedChar:2.0F];
+  [NSNumber numberWithUnsignedChar:2.0l];
+  [NSNumber numberWithUnsignedChar:2.0L];
+  [NSNumber numberWithUnsignedChar:0x2f];
+  [NSNumber numberWithUnsignedChar:04];
+  [NSNumber numberWithUnsignedChar:0];
+  [NSNumber numberWithUnsignedChar:0.0];
+  [NSNumber numberWithUnsignedChar:YES];
+  [NSNumber numberWithUnsignedChar:NO];
+  [NSNumber numberWithUnsignedChar:true];
+  [NSNumber numberWithUnsignedChar:false];
+  [NSNumber numberWithUnsignedChar:VAL_INT];
+  [NSNumber numberWithUnsignedChar:VAL_UINT];
+  [NSNumber numberWithUnsignedChar:VAL_CHAR];
+
+  [NSNumber numberWithShort:'a'];
+  [NSNumber numberWithShort:L'a'];
+  [NSNumber numberWithShort:2];
+  [NSNumber numberWithShort:2U];
+  [NSNumber numberWithShort:2u];
+  [NSNumber numberWithShort:2L];
+  [NSNumber numberWithShort:2l];
+  [NSNumber numberWithShort:2LL];
+  [NSNumber numberWithShort:2ll];
+  [NSNumber numberWithShort:2ul];
+  [NSNumber numberWithShort:2lu];
+  [NSNumber numberWithShort:2ull];
+  [NSNumber numberWithShort:2llu];
+  [NSNumber numberWithShort:2.0];
+  [NSNumber numberWithShort:2.0f];
+  [NSNumber numberWithShort:2.0F];
+  [NSNumber numberWithShort:2.0l];
+  [NSNumber numberWithShort:2.0L];
+  [NSNumber numberWithShort:0x2f];
+  [NSNumber numberWithShort:04];
+  [NSNumber numberWithShort:0];
+  [NSNumber numberWithShort:0.0];
+  [NSNumber numberWithShort:YES];
+  [NSNumber numberWithShort:NO];
+  [NSNumber numberWithShort:true];
+  [NSNumber numberWithShort:false];
+  [NSNumber numberWithShort:VAL_INT];
+  [NSNumber numberWithShort:VAL_UINT];
+
+  [NSNumber numberWithUnsignedShort:'a'];
+  [NSNumber numberWithUnsignedShort:L'a'];
+  [NSNumber numberWithUnsignedShort:2];
+  [NSNumber numberWithUnsignedShort:2U];
+  [NSNumber numberWithUnsignedShort:2u];
+  [NSNumber numberWithUnsignedShort:2L];
+  [NSNumber numberWithUnsignedShort:2l];
+  [NSNumber numberWithUnsignedShort:2LL];
+  [NSNumber numberWithUnsignedShort:2ll];
+  [NSNumber numberWithUnsignedShort:2ul];
+  [NSNumber numberWithUnsignedShort:2lu];
+  [NSNumber numberWithUnsignedShort:2ull];
+  [NSNumber numberWithUnsignedShort:2llu];
+  [NSNumber numberWithUnsignedShort:2.0];
+  [NSNumber numberWithUnsignedShort:2.0f];
+  [NSNumber numberWithUnsignedShort:2.0F];
+  [NSNumber numberWithUnsignedShort:2.0l];
+  [NSNumber numberWithUnsignedShort:2.0L];
+  [NSNumber numberWithUnsignedShort:0x2f];
+  [NSNumber numberWithUnsignedShort:04];
+  [NSNumber numberWithUnsignedShort:0];
+  [NSNumber numberWithUnsignedShort:0.0];
+  [NSNumber numberWithUnsignedShort:YES];
+  [NSNumber numberWithUnsignedShort:NO];
+  [NSNumber numberWithUnsignedShort:true];
+  [NSNumber numberWithUnsignedShort:false];
+  [NSNumber numberWithUnsignedShort:VAL_INT];
+  [NSNumber numberWithUnsignedShort:VAL_UINT];
+
+  [NSNumber numberWithInt:'a'];
+  [NSNumber numberWithInt:L'a'];
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  [NSNumber numberWithInt:2.0];
+  [NSNumber numberWithInt:2.0f];
+  [NSNumber numberWithInt:2.0F];
+  [NSNumber numberWithInt:2.0l];
+  [NSNumber numberWithInt:2.0L];
+  @0x2f;
+  @04;
+  @0;
+  [NSNumber numberWithInt:0.0];
+  [NSNumber numberWithInt:YES];
+  [NSNumber numberWithInt:NO];
+  [NSNumber numberWithInt:true];
+  [NSNumber numberWithInt:false];
+  @VAL_INT;
+  [NSNumber numberWithInt:VAL_UINT];
+
+  (void)[[NSNumber alloc] initWithInt:2];
+  (void)[[NSNumber alloc] initWithInt:2U];
+
+  @+2;
+  @-2;
+
+  [NSNumber numberWithUnsignedInt:'a'];
+  [NSNumber numberWithUnsignedInt:L'a'];
+  @2U;
+  @2U;
+  @2u;
+  @2U;
+  @2u;
+  @2U;
+  @2u;
+  @2u;
+  @2u;
+  @2u;
+  @2u;
+  [NSNumber numberWithUnsignedInt:2.0];
+  [NSNumber numberWithUnsignedInt:2.0f];
+  [NSNumber numberWithUnsignedInt:2.0F];
+  [NSNumber numberWithUnsignedInt:2.0l];
+  [NSNumber numberWithUnsignedInt:2.0L];
+  @0x2fU;
+  @04U;
+  @0U;
+  [NSNumber numberWithUnsignedInt:0.0];
+  [NSNumber numberWithUnsignedInt:YES];
+  [NSNumber numberWithUnsignedInt:NO];
+  [NSNumber numberWithUnsignedInt:true];
+  [NSNumber numberWithUnsignedInt:false];
+  [NSNumber numberWithUnsignedInt:VAL_INT];
+  @VAL_UINT;
+
+  [NSNumber numberWithLong:'a'];
+  [NSNumber numberWithLong:L'a'];
+  @2L;
+  @2L;
+  @2l;
+  @2L;
+  @2l;
+  @2L;
+  @2l;
+  @2l;
+  @2l;
+  @2l;
+  @2l;
+  [NSNumber numberWithLong:2.0];
+  [NSNumber numberWithLong:2.0f];
+  [NSNumber numberWithLong:2.0F];
+  [NSNumber numberWithLong:2.0l];
+  [NSNumber numberWithLong:2.0L];
+  @0x2fL;
+  @04L;
+  @0L;
+  [NSNumber numberWithLong:0.0];
+  [NSNumber numberWithLong:YES];
+  [NSNumber numberWithLong:NO];
+  [NSNumber numberWithLong:true];
+  [NSNumber numberWithLong:false];
+  [NSNumber numberWithLong:VAL_INT];
+  [NSNumber numberWithLong:VAL_UINT];
+
+  [NSNumber numberWithUnsignedLong:'a'];
+  [NSNumber numberWithUnsignedLong:L'a'];
+  @2UL;
+  @2UL;
+  @2ul;
+  @2UL;
+  @2ul;
+  @2UL;
+  @2ul;
+  @2ul;
+  @2lu;
+  @2ul;
+  @2ul;
+  [NSNumber numberWithUnsignedLong:2.0];
+  [NSNumber numberWithUnsignedLong:2.0f];
+  [NSNumber numberWithUnsignedLong:2.0F];
+  [NSNumber numberWithUnsignedLong:2.0l];
+  [NSNumber numberWithUnsignedLong:2.0L];
+  @0x2fUL;
+  @04UL;
+  @0UL;
+  [NSNumber numberWithUnsignedLong:0.0];
+  [NSNumber numberWithUnsignedLong:YES];
+  [NSNumber numberWithUnsignedLong:NO];
+  [NSNumber numberWithUnsignedLong:true];
+  [NSNumber numberWithUnsignedLong:false];
+  [NSNumber numberWithUnsignedLong:VAL_INT];
+  [NSNumber numberWithUnsignedLong:VAL_UINT];
+
+  [NSNumber numberWithLongLong:'a'];
+  [NSNumber numberWithLongLong:L'a'];
+  @2LL;
+  @2LL;
+  @2ll;
+  @2LL;
+  @2ll;
+  @2LL;
+  @2ll;
+  @2ll;
+  @2ll;
+  @2ll;
+  @2ll;
+  [NSNumber numberWithLongLong:2.0];
+  [NSNumber numberWithLongLong:2.0f];
+  [NSNumber numberWithLongLong:2.0F];
+  [NSNumber numberWithLongLong:2.0l];
+  [NSNumber numberWithLongLong:2.0L];
+  @0x2fLL;
+  @04LL;
+  @0LL;
+  [NSNumber numberWithLongLong:0.0];
+  [NSNumber numberWithLongLong:YES];
+  [NSNumber numberWithLongLong:NO];
+  [NSNumber numberWithLongLong:true];
+  [NSNumber numberWithLongLong:false];
+  [NSNumber numberWithLongLong:VAL_INT];
+  [NSNumber numberWithLongLong:VAL_UINT];
+
+  [NSNumber numberWithUnsignedLongLong:'a'];
+  [NSNumber numberWithUnsignedLongLong:L'a'];
+  @2ULL;
+  @2ULL;
+  @2ull;
+  @2ULL;
+  @2ull;
+  @2ULL;
+  @2ull;
+  @2ull;
+  @2ull;
+  @2ull;
+  @2llu;
+  [NSNumber numberWithUnsignedLongLong:2.0];
+  [NSNumber numberWithUnsignedLongLong:2.0f];
+  [NSNumber numberWithUnsignedLongLong:2.0F];
+  [NSNumber numberWithUnsignedLongLong:2.0l];
+  [NSNumber numberWithUnsignedLongLong:2.0L];
+  @0x2fULL;
+  @04ULL;
+  @0ULL;
+  [NSNumber numberWithUnsignedLongLong:0.0];
+  [NSNumber numberWithUnsignedLongLong:YES];
+  [NSNumber numberWithUnsignedLongLong:NO];
+  [NSNumber numberWithUnsignedLongLong:true];
+  [NSNumber numberWithUnsignedLongLong:false];
+  [NSNumber numberWithUnsignedLongLong:VAL_INT];
+  [NSNumber numberWithUnsignedLongLong:VAL_UINT];
+
+  [NSNumber numberWithFloat:'a'];
+  [NSNumber numberWithFloat:L'a'];
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0f;
+  @2.0F;
+  @2.0f;
+  @2.0f;
+  [NSNumber numberWithFloat:0x2f];
+  [NSNumber numberWithFloat:04];
+  @0.0f;
+  @0.0f;
+  [NSNumber numberWithFloat:YES];
+  [NSNumber numberWithFloat:NO];
+  [NSNumber numberWithFloat:true];
+  [NSNumber numberWithFloat:false];
+  [NSNumber numberWithFloat:VAL_INT];
+  [NSNumber numberWithFloat:VAL_UINT];
+
+  [NSNumber numberWithDouble:'a'];
+  [NSNumber numberWithDouble:L'a'];
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  @2.0;
+  [NSNumber numberWithDouble:0x2f];
+  [NSNumber numberWithDouble:04];
+  @0.0;
+  @0.0;
+  [NSNumber numberWithDouble:YES];
+  [NSNumber numberWithDouble:NO];
+  [NSNumber numberWithDouble:true];
+  [NSNumber numberWithDouble:false];
+  [NSNumber numberWithDouble:VAL_INT];
+  [NSNumber numberWithDouble:VAL_UINT];
+
+  [NSNumber numberWithBool:'a'];
+  [NSNumber numberWithBool:L'a'];
+  [NSNumber numberWithBool:2];
+  [NSNumber numberWithBool:2U];
+  [NSNumber numberWithBool:2u];
+  [NSNumber numberWithBool:2L];
+  [NSNumber numberWithBool:2l];
+  [NSNumber numberWithBool:2LL];
+  [NSNumber numberWithBool:2ll];
+  [NSNumber numberWithBool:2ul];
+  [NSNumber numberWithBool:2lu];
+  [NSNumber numberWithBool:2ull];
+  [NSNumber numberWithBool:2llu];
+  [NSNumber numberWithBool:2.0];
+  [NSNumber numberWithBool:2.0f];
+  [NSNumber numberWithBool:2.0F];
+  [NSNumber numberWithBool:2.0l];
+  [NSNumber numberWithBool:2.0L];
+  [NSNumber numberWithBool:0x2f];
+  [NSNumber numberWithBool:04];
+  [NSNumber numberWithBool:0];
+  [NSNumber numberWithBool:0.0];
+  @YES;
+  @NO;
+  @true;
+  @false;
+  [NSNumber numberWithBool:VAL_INT];
+  [NSNumber numberWithBool:VAL_UINT];
+
+  [NSNumber numberWithInteger:'a'];
+  [NSNumber numberWithInteger:L'a'];
+  @2;
+  @2;
+  @2;
+  @2L;
+  @2l;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  @2;
+  [NSNumber numberWithInteger:2.0];
+  [NSNumber numberWithInteger:2.0f];
+  [NSNumber numberWithInteger:2.0F];
+  [NSNumber numberWithInteger:2.0l];
+  [NSNumber numberWithInteger:2.0L];
+  @0x2f;
+  @04;
+  @0;
+  [NSNumber numberWithInteger:0.0];
+  [NSNumber numberWithInteger:YES];
+  [NSNumber numberWithInteger:NO];
+  [NSNumber numberWithInteger:true];
+  [NSNumber numberWithInteger:false];
+  [NSNumber numberWithInteger:VAL_INT];
+  [NSNumber numberWithInteger:VAL_UINT];
+
+  [NSNumber numberWithUnsignedInteger:'a'];
+  [NSNumber numberWithUnsignedInteger:L'a'];
+  @2U;
+  @2U;
+  @2u;
+  @2U;
+  @2u;
+  @2U;
+  @2u;
+  @2ul;
+  @2lu;
+  @2u;
+  @2u;
+  [NSNumber numberWithUnsignedInteger:2.0];
+  [NSNumber numberWithUnsignedInteger:2.0f];
+  [NSNumber numberWithUnsignedInteger:2.0F];
+  [NSNumber numberWithUnsignedInteger:2.0l];
+  [NSNumber numberWithUnsignedInteger:2.0L];
+  @0x2fU;
+  @04U;
+  @0U;
+  [NSNumber numberWithUnsignedInteger:0.0];
+  [NSNumber numberWithUnsignedInteger:YES];
+  [NSNumber numberWithUnsignedInteger:NO];
+  [NSNumber numberWithUnsignedInteger:true];
+  [NSNumber numberWithUnsignedInteger:false];
+  [NSNumber numberWithUnsignedInteger:VAL_INT];
+  [NSNumber numberWithUnsignedInteger:VAL_UINT];
+}

Added: cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m?rev=152141&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m (added)
+++ cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m Tue Mar  6 14:06:33 2012
@@ -0,0 +1,137 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c 
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+
+typedef signed char BOOL;
+#define nil ((void*) 0)
+
+ at interface NSObject
++ (id)alloc;
+ at end
+
+ at interface NSString : NSObject
++ (id)stringWithString:(NSString *)string;
+- (id)initWithString:(NSString *)aString;
+ at end
+
+ at interface NSArray : NSObject
+- (id)objectAtIndex:(unsigned long)index;
+- (id)objectAtIndexedSubscript:(int)index;
+ at end
+
+ at interface NSArray (NSArrayCreation)
++ (id)array;
++ (id)arrayWithObject:(id)anObject;
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
++ (id)arrayWithObjects:(id)firstObj, ...;
++ (id)arrayWithArray:(NSArray *)array;
+
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(id)firstObj, ...;
+- (id)initWithArray:(NSArray *)array;
+
+- (id)objectAtIndex:(unsigned long)index;
+ at end
+
+ at interface NSMutableArray : NSArray
+- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject;
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+ at end
+
+ at interface NSDictionary : NSObject
+- (id)objectForKeyedSubscript:(id)key;
+ at end
+
+ at interface NSDictionary (NSDictionaryCreation)
++ (id)dictionary;
++ (id)dictionaryWithObject:(id)object forKey:(id)key;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
++ (id)dictionaryWithDictionary:(NSDictionary *)dict;
++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+- (id)initWithObjectsAndKeys:(id)firstObject, ...;
+- (id)initWithDictionary:(NSDictionary *)otherDictionary;
+- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)objectForKey:(id)aKey;
+ at end
+
+ at interface NSMutableDictionary : NSDictionary
+- (void)setObject:(id)anObject forKey:(id)aKey;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+ at end
+
+ at interface NSNumber : NSObject
+ at end
+
+ at interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithInt:(int)value;
+ at end
+
+#define M(x) (x)
+#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
+#define TWO(x) ((x), (x))
+
+ at interface I
+ at end
+ at implementation I
+-(void) foo {
+  NSString *str;
+  NSArray *arr;
+  NSDictionary *dict;
+
+  arr = [NSArray array];
+  arr = [NSArray arrayWithObject:str];
+  arr = [NSArray arrayWithObjects:str, str, nil];
+  dict = [NSDictionary dictionary];
+  dict = [NSDictionary dictionaryWithObject:arr forKey:str];
+  dict = [NSDictionary dictionaryWithObjectsAndKeys: @"value1", @"key1", @"value2", @"key2", nil];
+  dict = [NSDictionary dictionaryWithObjectsAndKeys: PAIR(1), PAIR(2), nil];
+  dict = [NSDictionary dictionaryWithObjectsAndKeys:
+                                               @"value1", @"key1",
+#ifdef BLAH
+                                               @"value2", @"key2",
+#else
+                                               @"value3", @"key3",
+#endif
+                                               nil ];
+
+  id o = [arr objectAtIndex:2];
+  o = [dict objectForKey:@"key"];
+  o = TWO([dict objectForKey:@"key"]);
+  o = [NSDictionary dictionaryWithObject:[NSDictionary dictionary] forKey:@"key"];
+  NSMutableArray *marr = 0;
+  NSMutableDictionary *mdict = 0;
+  [marr replaceObjectAtIndex:2 withObject:@"val"];
+  [mdict setObject:@"value" forKey:@"key"];
+  [marr replaceObjectAtIndex:2 withObject:[arr objectAtIndex:4]];
+  [mdict setObject:[dict objectForKey:@"key2"] forKey:@"key"];
+  [mdict setObject:[dict objectForKey:@"key2"] forKey:
+#if 1
+                     @"key1"
+#else
+                     @"key2"
+#endif
+                    ];
+  [mdict setObject:[dict objectForKey:
+#if 2
+                     @"key3"
+#else
+                     @"key4"
+#endif
+                   ] forKey:@"key"];
+  [mdict setObject:@"value" forKey:[dict objectForKey:
+#if 3
+                     @"key5"
+#else
+                     @"key6"
+#endif
+                   ] ];
+  [mdict setObject:@"val" forKey:[dict objectForKey:@"key2"]];
+  [mdict setObject:[dict objectForKey:@"key1"] forKey:[dict objectForKey:[NSArray arrayWithObject:@"arrkey"]]];
+  __strong NSArray **parr = 0;
+  o = [*parr objectAtIndex:2];
+}
+ at end

Added: cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result?rev=152141&view=auto
==============================================================================
--- cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result (added)
+++ cfe/trunk/test/ARCMT/objcmt-subscripting-literals.m.result Tue Mar  6 14:06:33 2012
@@ -0,0 +1,137 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -objcmt-migrate-literals -objcmt-migrate-subscripting -mt-migrate-directory %t %s -x objective-c 
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+
+typedef signed char BOOL;
+#define nil ((void*) 0)
+
+ at interface NSObject
++ (id)alloc;
+ at end
+
+ at interface NSString : NSObject
++ (id)stringWithString:(NSString *)string;
+- (id)initWithString:(NSString *)aString;
+ at end
+
+ at interface NSArray : NSObject
+- (id)objectAtIndex:(unsigned long)index;
+- (id)objectAtIndexedSubscript:(int)index;
+ at end
+
+ at interface NSArray (NSArrayCreation)
++ (id)array;
++ (id)arrayWithObject:(id)anObject;
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
++ (id)arrayWithObjects:(id)firstObj, ...;
++ (id)arrayWithArray:(NSArray *)array;
+
+- (id)initWithObjects:(const id [])objects count:(unsigned long)cnt;
+- (id)initWithObjects:(id)firstObj, ...;
+- (id)initWithArray:(NSArray *)array;
+
+- (id)objectAtIndex:(unsigned long)index;
+ at end
+
+ at interface NSMutableArray : NSArray
+- (void)replaceObjectAtIndex:(unsigned long)index withObject:(id)anObject;
+- (void)setObject:(id)object atIndexedSubscript:(int)index;
+ at end
+
+ at interface NSDictionary : NSObject
+- (id)objectForKeyedSubscript:(id)key;
+ at end
+
+ at interface NSDictionary (NSDictionaryCreation)
++ (id)dictionary;
++ (id)dictionaryWithObject:(id)object forKey:(id)key;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
++ (id)dictionaryWithObjectsAndKeys:(id)firstObject, ...;
++ (id)dictionaryWithDictionary:(NSDictionary *)dict;
++ (id)dictionaryWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)initWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
+- (id)initWithObjectsAndKeys:(id)firstObject, ...;
+- (id)initWithDictionary:(NSDictionary *)otherDictionary;
+- (id)initWithObjects:(NSArray *)objects forKeys:(NSArray *)keys;
+
+- (id)objectForKey:(id)aKey;
+ at end
+
+ at interface NSMutableDictionary : NSDictionary
+- (void)setObject:(id)anObject forKey:(id)aKey;
+- (void)setObject:(id)object forKeyedSubscript:(id)key;
+ at end
+
+ at interface NSNumber : NSObject
+ at end
+
+ at interface NSNumber (NSNumberCreation)
++ (NSNumber *)numberWithInt:(int)value;
+ at end
+
+#define M(x) (x)
+#define PAIR(x) @#x, [NSNumber numberWithInt:(x)]
+#define TWO(x) ((x), (x))
+
+ at interface I
+ at end
+ at implementation I
+-(void) foo {
+  NSString *str;
+  NSArray *arr;
+  NSDictionary *dict;
+
+  arr = @[];
+  arr = @[str];
+  arr = @[str, str];
+  dict = @{};
+  dict = @{str: arr};
+  dict = @{@"key1": @"value1", @"key2": @"value2"};
+  dict = [NSDictionary dictionaryWithObjectsAndKeys: PAIR(1), PAIR(2), nil];
+  dict = [NSDictionary dictionaryWithObjectsAndKeys:
+                                               @"value1", @"key1",
+#ifdef BLAH
+                                               @"value2", @"key2",
+#else
+                                               @"value3", @"key3",
+#endif
+                                               nil ];
+
+  id o = arr[2];
+  o = dict[@"key"];
+  o = TWO(dict[@"key"]);
+  o = @{@"key": @{}};
+  NSMutableArray *marr = 0;
+  NSMutableDictionary *mdict = 0;
+  marr[2] = @"val";
+  mdict[@"key"] = @"value";
+  marr[2] = arr[4];
+  mdict[@"key"] = dict[@"key2"];
+  [mdict setObject:dict[@"key2"] forKey:
+#if 1
+                     @"key1"
+#else
+                     @"key2"
+#endif
+                    ];
+  mdict[@"key"] = [dict objectForKey:
+#if 2
+                     @"key3"
+#else
+                     @"key4"
+#endif
+                   ];
+  mdict[[dict objectForKey:
+#if 3
+                     @"key5"
+#else
+                     @"key6"
+#endif
+                   ]] = @"value";
+  mdict[dict[@"key2"]] = @"val";
+  mdict[dict[@[@"arrkey"]]] = dict[@"key1"];
+  __strong NSArray **parr = 0;
+  o = (*parr)[2];
+}
+ at end

Modified: cfe/trunk/test/ARCMT/with-arc-mode-migrate.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/with-arc-mode-migrate.m?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/with-arc-mode-migrate.m (original)
+++ cfe/trunk/test/ARCMT/with-arc-mode-migrate.m Tue Mar  6 14:06:33 2012
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t -fsyntax-only -fobjc-arc %s
-// RUN: c-arcmt-test -arcmt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t -fsyntax-only -fobjc-arc %s
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
 // RUN: rm -rf %t
 
 @protocol NSObject

Modified: cfe/trunk/test/ARCMT/with-arc-mode-migrate.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ARCMT/with-arc-mode-migrate.m.result?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/test/ARCMT/with-arc-mode-migrate.m.result (original)
+++ cfe/trunk/test/ARCMT/with-arc-mode-migrate.m.result Tue Mar  6 14:06:33 2012
@@ -1,7 +1,7 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fsyntax-only -fobjc-arc -x objective-c %s.result
-// RUN: %clang_cc1 -arcmt-migrate -arcmt-migrate-directory %t -fsyntax-only -fobjc-arc %s
-// RUN: c-arcmt-test -arcmt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
+// RUN: %clang_cc1 -arcmt-migrate -mt-migrate-directory %t -fsyntax-only -fobjc-arc %s
+// RUN: c-arcmt-test -mt-migrate-directory %t | arcmt-test -verify-transformed-files %s.result
 // RUN: rm -rf %t
 
 @protocol NSObject

Modified: cfe/trunk/tools/arcmt-test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/arcmt-test/CMakeLists.txt?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/arcmt-test/CMakeLists.txt (original)
+++ cfe/trunk/tools/arcmt-test/CMakeLists.txt Tue Mar  6 14:06:33 2012
@@ -1,5 +1,6 @@
 set(LLVM_USED_LIBS
   clangARCMigrate
+  clangEdit
   clangRewrite
   )
 

Modified: cfe/trunk/tools/arcmt-test/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/arcmt-test/Makefile?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/arcmt-test/Makefile (original)
+++ cfe/trunk/tools/arcmt-test/Makefile Tue Mar  6 14:06:33 2012
@@ -19,6 +19,6 @@
 LINK_COMPONENTS := support mc
 USEDLIBS = clangIndex.a clangARCMigrate.a clangRewrite.a \
 		 clangFrontend.a clangDriver.a clangSerialization.a clangParse.a \
-		 clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
+		 clangSema.a clangEdit.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile

Modified: cfe/trunk/tools/arcmt-test/arcmt-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/arcmt-test/arcmt-test.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/arcmt-test/arcmt-test.cpp (original)
+++ cfe/trunk/tools/arcmt-test/arcmt-test.cpp Tue Mar  6 14:06:33 2012
@@ -135,9 +135,8 @@
 }
 
 static void printResult(FileRemapper &remapper, raw_ostream &OS) {
-  CompilerInvocation CI;
-  remapper.applyMappings(CI);
-  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+  PreprocessorOptions PPOpts;
+  remapper.applyMappings(PPOpts);
   // The changed files will be in memory buffers, print them.
   for (unsigned i = 0, e = PPOpts.RemappedFileBuffers.size(); i != e; ++i) {
     const llvm::MemoryBuffer *mem = PPOpts.RemappedFileBuffers[i].second;

Modified: cfe/trunk/tools/c-arcmt-test/c-arcmt-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-arcmt-test/c-arcmt-test.c?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/c-arcmt-test/c-arcmt-test.c (original)
+++ cfe/trunk/tools/c-arcmt-test/c-arcmt-test.c Tue Mar  6 14:06:33 2012
@@ -34,22 +34,51 @@
   return 0;
 }
 
+static int print_remappings_filelist(const char **files, unsigned numFiles) {
+  CXRemapping remap;
+  unsigned i, N;
+  CXString origFname;
+  CXString transFname;
+
+  remap = clang_getRemappingsFromFileList(files, numFiles);
+  if (!remap)
+    return 1;
+
+  N = clang_remap_getNumFiles(remap);
+  for (i = 0; i != N; ++i) {
+    clang_remap_getFilenames(remap, i, &origFname, &transFname);
+
+    fprintf(stdout, "%s\n", clang_getCString(origFname));
+    fprintf(stdout, "%s\n", clang_getCString(transFname));
+
+    clang_disposeString(origFname);
+    clang_disposeString(transFname);
+  }
+
+  clang_remap_dispose(remap);
+  return 0;
+}
+
 /******************************************************************************/
 /* Command line processing.                                                   */
 /******************************************************************************/
 
 static void print_usage(void) {
   fprintf(stderr,
-    "usage: c-arcmt-test -arcmt-migrate-directory <path>\n\n\n");
+    "usage: c-arcmt-test -mt-migrate-directory <path>\n"
+    "       c-arcmt-test <remap-file-path1> <remap-file-path2> ...\n\n\n");
 }
 
 /***/
 
 int carcmttest_main(int argc, const char **argv) {
   clang_enableStackTraces();
-  if (argc == 3 && strncmp(argv[1], "-arcmt-migrate-directory", 24) == 0)
+  if (argc == 3 && strncmp(argv[1], "-mt-migrate-directory", 21) == 0)
     return print_remappings(argv[2]);
 
+  if (argc > 1)
+    return print_remappings_filelist(argv+1, argc-1);
+  
   print_usage();
   return 1;
 }

Modified: cfe/trunk/tools/driver/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/CMakeLists.txt?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/driver/CMakeLists.txt (original)
+++ cfe/trunk/tools/driver/CMakeLists.txt Tue Mar  6 14:06:33 2012
@@ -5,10 +5,12 @@
   clangBasic
   clangCodeGen
   clangDriver
+  clangEdit
   clangFrontend
   clangIndex
   clangLex
   clangParse
+  clangEdit
   clangARCMigrate
   clangRewrite
   clangSema

Modified: cfe/trunk/tools/driver/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/Makefile?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/driver/Makefile (original)
+++ cfe/trunk/tools/driver/Makefile Tue Mar  6 14:06:33 2012
@@ -36,7 +36,7 @@
            clangStaticAnalyzerFrontend.a clangStaticAnalyzerCheckers.a \
            clangStaticAnalyzerCore.a \
            clangAnalysis.a clangIndex.a clangARCMigrate.a clangRewrite.a \
-           clangAST.a clangLex.a clangBasic.a
+           clangEdit.a clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile
 

Modified: cfe/trunk/tools/libclang/ARCMigrate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/ARCMigrate.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/ARCMigrate.cpp (original)
+++ cfe/trunk/tools/libclang/ARCMigrate.cpp Tue Mar  6 14:06:33 2012
@@ -74,6 +74,47 @@
   return remap.take();
 }
 
+CXRemapping clang_getRemappingsFromFileList(const char **filePaths,
+                                            unsigned numFiles) {
+  bool Logging = ::getenv("LIBCLANG_LOGGING");
+
+  OwningPtr<Remap> remap(new Remap());
+
+  if (numFiles == 0) {
+    if (Logging)
+      llvm::errs() << "clang_getRemappingsFromFileList was called with "
+                      "numFiles=0\n";
+    return remap.take();
+  }
+
+  if (!filePaths) {
+    if (Logging)
+      llvm::errs() << "clang_getRemappingsFromFileList was called with "
+                      "NULL filePaths\n";
+    return 0;
+  }
+
+  TextDiagnosticBuffer diagBuffer;
+  SmallVector<StringRef, 32> Files;
+  for (unsigned i = 0; i != numFiles; ++i)
+    Files.push_back(filePaths[i]);
+
+  bool err = arcmt::getFileRemappingsFromFileList(remap->Vec, Files,
+                                                  &diagBuffer);
+
+  if (err) {
+    if (Logging) {
+      llvm::errs() << "Error by clang_getRemappingsFromFileList\n";
+      for (TextDiagnosticBuffer::const_iterator
+             I = diagBuffer.err_begin(), E = diagBuffer.err_end(); I != E; ++I)
+        llvm::errs() << I->second << '\n';
+    }
+    return remap.take();
+  }
+
+  return remap.take();
+}
+
 unsigned clang_remap_getNumFiles(CXRemapping map) {
   return static_cast<Remap *>(map)->Vec.size();
   

Modified: cfe/trunk/tools/libclang/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CMakeLists.txt?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CMakeLists.txt (original)
+++ cfe/trunk/tools/libclang/CMakeLists.txt Tue Mar  6 14:06:33 2012
@@ -6,6 +6,7 @@
   clangSerialization
   clangIndex
   clangSema
+  clangEdit
   clangAST
   clangLex
   clangBasic)

Modified: cfe/trunk/tools/libclang/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Makefile?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/Makefile (original)
+++ cfe/trunk/tools/libclang/Makefile Tue Mar  6 14:06:33 2012
@@ -18,7 +18,8 @@
 LINK_COMPONENTS := support mc
 USEDLIBS = clangARCMigrate.a clangRewrite.a clangFrontend.a clangDriver.a \
      clangSerialization.a \
-		 clangParse.a clangSema.a clangAnalysis.a clangAST.a clangLex.a clangBasic.a
+		 clangParse.a clangSema.a clangEdit.a clangAnalysis.a \
+		 clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/Makefile
 

Modified: cfe/trunk/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/libclang.exports (original)
+++ cfe/trunk/tools/libclang/libclang.exports Tue Mar  6 14:06:33 2012
@@ -132,6 +132,7 @@
 clang_getRangeEnd
 clang_getRangeStart
 clang_getRemappings
+clang_getRemappingsFromFileList
 clang_getResultType
 clang_getSpecializedCursorTemplate
 clang_getSpellingLocation

Modified: cfe/trunk/unittests/Frontend/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Frontend/Makefile?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/unittests/Frontend/Makefile (original)
+++ cfe/trunk/unittests/Frontend/Makefile Tue Mar  6 14:06:33 2012
@@ -13,7 +13,7 @@
 USEDLIBS = clangFrontendTool.a clangFrontend.a clangDriver.a \
            clangSerialization.a clangCodeGen.a clangParse.a clangSema.a \
            clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
-           clangIndex.a clangARCMigrate.a clangRewrite.a \
+           clangIndex.a clangARCMigrate.a clangRewrite.a clangEdit.a \
            clangAnalysis.a clangAST.a clangLex.a clangBasic.a
 
 include $(CLANG_LEVEL)/unittests/Makefile

Modified: cfe/trunk/unittests/Lex/LexerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Lex/LexerTest.cpp?rev=152141&r1=152140&r2=152141&view=diff
==============================================================================
--- cfe/trunk/unittests/Lex/LexerTest.cpp (original)
+++ cfe/trunk/unittests/Lex/LexerTest.cpp Tue Mar  6 14:06:33 2012
@@ -66,10 +66,10 @@
     "N(INN(val)) N(NOF1) N(NOF2) N(val)";
 
   MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
-  SourceMgr.createMainFileIDForMemBuffer(buf);
+  FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf);
 
   VoidModuleLoader ModLoader;
-  HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target);
+  HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, Target.getPtr());
   Preprocessor PP(Diags, LangOpts,
                   Target.getPtr(),
                   SourceMgr, HeaderInfo, ModLoader,





More information about the cfe-commits mailing list