diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index 54a6d47..f53c614 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -57,7 +57,8 @@
         bool ShowColors = Out.has_colors();
         if (ShowColors)
           Out.changeColor(raw_ostream::BLUE);
-        Out << (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n";
+        Out << ((Dump || DumpLookups) ? "Dumping " : "Printing ") << getName(D)
+            << ":\n";
         if (ShowColors)
           Out.resetColor();
         print(D);
@@ -79,9 +80,13 @@
     }
     void print(Decl *D) {
       if (DumpLookups) {
-        if (DeclContext *DC = dyn_cast<DeclContext>(D))
-          DC->dumpLookups(Out);
-        else
+        if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
+          if (DC == DC->getPrimaryContext())
+            DC->dumpLookups(Out, Dump);
+          else
+            Out << "Lookup map is in primary DeclContext "
+                << DC->getPrimaryContext() << "\n";
+        } else
           Out << "Not a DeclContext\n";
       } else if (Dump)
         D->dump(Out);
@@ -118,17 +123,21 @@
   };
 } // end anonymous namespace
 
-ASTConsumer *clang::CreateASTPrinter(raw_ostream *Out,
-                                     StringRef FilterString) {
-  return new ASTPrinter(Out, /*Dump=*/ false, FilterString);
+std::unique_ptr<ASTConsumer> clang::CreateASTPrinter(raw_ostream *Out,
+                                                     StringRef FilterString) {
+  return llvm::make_unique<ASTPrinter>(Out, /*Dump=*/false, FilterString);
 }
 
-ASTConsumer *clang::CreateASTDumper(StringRef FilterString, bool DumpLookups) {
-  return new ASTPrinter(nullptr, /*Dump=*/true, FilterString, DumpLookups);
+std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,
+                                                    bool DumpDecls,
+                                                    bool DumpLookups) {
+  assert((DumpDecls || DumpLookups) && "nothing to dump");
+  return llvm::make_unique<ASTPrinter>(nullptr, DumpDecls, FilterString,
+                                       DumpLookups);
 }
 
-ASTConsumer *clang::CreateASTDeclNodeLister() {
-  return new ASTDeclNodeLister(nullptr);
+std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
+  return llvm::make_unique<ASTDeclNodeLister>(nullptr);
 }
 
 //===----------------------------------------------------------------------===//
@@ -164,8 +173,9 @@
   }
 }
 
-
-ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
+std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
+  return llvm::make_unique<ASTViewer>();
+}
 
 //===----------------------------------------------------------------------===//
 /// DeclContextPrinter - Decl and DeclContext Visualization
@@ -475,6 +485,6 @@
     }
   }
 }
-ASTConsumer *clang::CreateDeclContextPrinter() {
-  return new DeclContextPrinter();
+std::unique_ptr<ASTConsumer> clang::CreateDeclContextPrinter() {
+  return llvm::make_unique<DeclContextPrinter>();
 }
diff --git a/lib/Frontend/ASTMerge.cpp b/lib/Frontend/ASTMerge.cpp
index ff6434c..216ac6a 100644
--- a/lib/Frontend/ASTMerge.cpp
+++ b/lib/Frontend/ASTMerge.cpp
@@ -16,8 +16,8 @@
 
 using namespace clang;
 
-ASTConsumer *ASTMergeAction::CreateASTConsumer(CompilerInstance &CI,
-                                               StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+ASTMergeAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   return AdaptedAction->CreateASTConsumer(CI, InFile);
 }
 
@@ -45,8 +45,8 @@
                                     new ForwardingDiagnosticConsumer(
                                           *CI.getDiagnostics().getClient()),
                                     /*ShouldOwnClient=*/true));
-    ASTUnit *Unit = ASTUnit::LoadFromASTFile(ASTFiles[I], Diags,
-                                             CI.getFileSystemOpts(), false);
+    std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
+        ASTFiles[I], Diags, CI.getFileSystemOpts(), false);
     if (!Unit)
       continue;
 
@@ -66,8 +66,6 @@
       
       Importer.Import(D);
     }
-
-    delete Unit;
   }
 
   AdaptedAction->ExecuteAction();
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index fc44d9f..a3998fa 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -105,7 +105,8 @@
 
 static void cleanupOnDiskMapAtExit();
 
-typedef llvm::DenseMap<const ASTUnit *, OnDiskData *> OnDiskDataMap;
+typedef llvm::DenseMap<const ASTUnit *,
+                       std::unique_ptr<OnDiskData>> OnDiskDataMap;
 static OnDiskDataMap &getOnDiskDataMap() {
   static OnDiskDataMap M;
   static bool hasRegisteredAtExit = false;
@@ -132,9 +133,9 @@
   // DenseMap.
   llvm::MutexGuard Guard(getOnDiskMutex());
   OnDiskDataMap &M = getOnDiskDataMap();
-  OnDiskData *&D = M[AU];
+  auto &D = M[AU];
   if (!D)
-    D = new OnDiskData();
+    D = llvm::make_unique<OnDiskData>();
   return *D;
 }
 
@@ -150,7 +151,6 @@
   OnDiskDataMap::iterator I = M.find(AU);
   if (I != M.end()) {
     I->second->Cleanup();
-    delete I->second;
     M.erase(AU);
   }
 }
@@ -219,8 +219,8 @@
     TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")),
     OwnsRemappedFileBuffers(true),
     NumStoredDiagnosticsFromDriver(0),
-    PreambleRebuildCounter(0), SavedMainFileBuffer(nullptr),
-    PreambleBuffer(nullptr), NumWarningsInPreamble(0),
+    PreambleRebuildCounter(0),
+    NumWarningsInPreamble(0),
     ShouldCacheCodeCompletionResults(false),
     IncludeBriefCommentsInCodeCompletion(false), UserFilesAreVolatile(false),
     CompletionCacheTopLevelHashValue(0),
@@ -251,9 +251,6 @@
     for (const auto &RB : PPOpts.RemappedFileBuffers)
       delete RB.second;
   }
-  
-  delete SavedMainFileBuffer;
-  delete PreambleBuffer;
 
   ClearCachedCompletionResults();  
   
@@ -511,8 +508,8 @@
       : PP(PP), Context(Context), LangOpt(LangOpt), TargetOpts(TargetOpts),
         Target(Target), Counter(Counter), InitializedLanguage(false) {}
 
-  bool ReadLanguageOptions(const LangOptions &LangOpts,
-                           bool Complain) override {
+  bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                           bool AllowCompatibleDifferences) override {
     if (InitializedLanguage)
       return false;
     
@@ -592,6 +589,7 @@
   DiagnosticsEngine &Diags;
   StoredDiagnosticConsumer Client;
   DiagnosticConsumer *PreviousClient;
+  std::unique_ptr<DiagnosticConsumer> OwningPreviousClient;
 
 public:
   CaptureDroppedDiagnostics(bool RequestCapture, DiagnosticsEngine &Diags,
@@ -599,16 +597,15 @@
     : Diags(Diags), Client(StoredDiags), PreviousClient(nullptr)
   {
     if (RequestCapture || Diags.getClient() == nullptr) {
-      PreviousClient = Diags.takeClient();
-      Diags.setClient(&Client);
+      OwningPreviousClient = Diags.takeClient();
+      PreviousClient = Diags.getClient();
+      Diags.setClient(&Client, false);
     }
   }
 
   ~CaptureDroppedDiagnostics() {
-    if (Diags.getClient() == &Client) {
-      Diags.takeClient();
-      Diags.setClient(PreviousClient);
-    }
+    if (Diags.getClient() == &Client)
+      Diags.setClient(PreviousClient, !!OwningPreviousClient.release());
   }
 };
 
@@ -638,38 +635,30 @@
   return nullptr;
 }
 
-llvm::MemoryBuffer *ASTUnit::getBufferForFile(StringRef Filename,
-                                              std::string *ErrorStr) {
+std::unique_ptr<llvm::MemoryBuffer>
+ASTUnit::getBufferForFile(StringRef Filename, std::string *ErrorStr) {
   assert(FileMgr);
-  return FileMgr->getBufferForFile(Filename, ErrorStr);
+  auto Buffer = FileMgr->getBufferForFile(Filename);
+  if (Buffer)
+    return std::move(*Buffer);
+  if (ErrorStr)
+    *ErrorStr = Buffer.getError().message();
+  return nullptr;
 }
 
 /// \brief Configure the diagnostics object for use with ASTUnit.
-void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags,
-                             const char **ArgBegin, const char **ArgEnd,
+void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
                              ASTUnit &AST, bool CaptureDiagnostics) {
-  if (!Diags.get()) {
-    // No diagnostics engine was provided, so create our own diagnostics object
-    // with the default options.
-    DiagnosticConsumer *Client = nullptr;
-    if (CaptureDiagnostics)
-      Client = new StoredDiagnosticConsumer(AST.StoredDiagnostics);
-    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions(),
-                                                Client,
-                                                /*ShouldOwnClient=*/true);
-  } else if (CaptureDiagnostics) {
+  assert(Diags.get() && "no DiagnosticsEngine was provided");
+  if (CaptureDiagnostics)
     Diags->setClient(new StoredDiagnosticConsumer(AST.StoredDiagnostics));
-  }
 }
 
-ASTUnit *ASTUnit::LoadFromASTFile(const std::string &Filename,
-                              IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-                                  const FileSystemOptions &FileSystemOpts,
-                                  bool OnlyLocalDecls,
-                                  ArrayRef<RemappedFile> RemappedFiles,
-                                  bool CaptureDiagnostics,
-                                  bool AllowPCHWithCompilerErrors,
-                                  bool UserFilesAreVolatile) {
+std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
+    const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+    const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls,
+    ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics,
+    bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) {
   std::unique_ptr<ASTUnit> AST(new ASTUnit(true));
 
   // Recover resources if we crash before exiting this method.
@@ -679,7 +668,7 @@
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
     DiagCleanup(Diags.get());
 
-  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
+  ConfigureDiags(Diags, *AST, CaptureDiagnostics);
 
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
@@ -705,7 +694,7 @@
 
   // Gather Info for preprocessor construction later on.
 
-  HeaderSearch &HeaderInfo = *AST->HeaderInfo.get();
+  HeaderSearch &HeaderInfo = *AST->HeaderInfo;
   unsigned Counter;
 
   AST->PP =
@@ -728,10 +717,9 @@
                              /*DisableValidation=*/disableValid,
                              AllowPCHWithCompilerErrors);
 
-  AST->Reader->setListener(new ASTInfoCollector(*AST->PP, Context,
-                                           AST->ASTFileLangOpts,
-                                           AST->TargetOpts, AST->Target, 
-                                           Counter));
+  AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>(
+      *AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target,
+      Counter));
 
   switch (AST->Reader->ReadAST(Filename, serialization::MK_MainFile,
                           SourceLocation(), ASTReader::ARR_None)) {
@@ -768,7 +756,7 @@
   // Tell the diagnostic client that we have started a source file.
   AST->getDiagnostics().getClient()->BeginSourceFile(Context.getLangOpts(),&PP);
 
-  return AST.release();
+  return AST;
 }
 
 namespace {
@@ -891,12 +879,13 @@
 public:
   ASTUnit &Unit;
 
-  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                 StringRef InFile) override {
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override {
     CI.getPreprocessor().addPPCallbacks(
-     new MacroDefinitionTrackerPPCallbacks(Unit.getCurrentTopLevelHashValue()));
-    return new TopLevelDeclTrackerConsumer(Unit, 
-                                           Unit.getCurrentTopLevelHashValue());
+        llvm::make_unique<MacroDefinitionTrackerPPCallbacks>(
+                                           Unit.getCurrentTopLevelHashValue()));
+    return llvm::make_unique<TopLevelDeclTrackerConsumer>(
+        Unit, Unit.getCurrentTopLevelHashValue());
   }
 
 public:
@@ -916,8 +905,8 @@
   explicit PrecompilePreambleAction(ASTUnit &Unit)
       : Unit(Unit), HasEmittedPreamblePCH(false) {}
 
-  ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
-                                 StringRef InFile) override;
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override;
   bool hasEmittedPreamblePCH() const { return HasEmittedPreamblePCH; }
   void setHasEmittedPreamblePCH() { HasEmittedPreamblePCH = true; }
   bool shouldEraseOutputFiles() override { return !hasEmittedPreamblePCH(); }
@@ -979,8 +968,9 @@
 
 }
 
-ASTConsumer *PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
-                                                         StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+PrecompilePreambleAction::CreateASTConsumer(CompilerInstance &CI,
+                                            StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
   raw_ostream *OS = nullptr;
@@ -991,10 +981,11 @@
   if (!CI.getFrontendOpts().RelocatablePCH)
     Sysroot.clear();
 
-  CI.getPreprocessor().addPPCallbacks(new MacroDefinitionTrackerPPCallbacks(
-      Unit.getCurrentTopLevelHashValue()));
-  return new PrecompilePreambleConsumer(Unit, this, CI.getPreprocessor(),
-                                        Sysroot, OS);
+  CI.getPreprocessor().addPPCallbacks(
+      llvm::make_unique<MacroDefinitionTrackerPPCallbacks>(
+                                           Unit.getCurrentTopLevelHashValue()));
+  return llvm::make_unique<PrecompilePreambleConsumer>(
+      Unit, this, CI.getPreprocessor(), Sysroot, OS);
 }
 
 static bool isNonDriverDiag(const StoredDiagnostic &StoredDiag) {
@@ -1031,15 +1022,12 @@
 ///
 /// \returns True if a failure occurred that causes the ASTUnit not to
 /// contain any translation-unit information, false otherwise.
-bool ASTUnit::Parse(llvm::MemoryBuffer *OverrideMainBuffer) {
-  delete SavedMainFileBuffer;
-  SavedMainFileBuffer = nullptr;
+bool ASTUnit::Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) {
+  SavedMainFileBuffer.reset();
 
-  if (!Invocation) {
-    delete OverrideMainBuffer;
+  if (!Invocation)
     return true;
-  }
-  
+
   // Create the compiler instance to use for building the AST.
   std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
 
@@ -1060,10 +1048,8 @@
   // Create the target instance.
   Clang->setTarget(TargetInfo::CreateTargetInfo(
       Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
-  if (!Clang->hasTarget()) {
-    delete OverrideMainBuffer;
+  if (!Clang->hasTarget())
     return true;
-  }
 
   // Inform the target of the language options.
   //
@@ -1083,10 +1069,8 @@
   FileSystemOpts = Clang->getFileSystemOpts();
   IntrusiveRefCntPtr<vfs::FileSystem> VFS =
       createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics());
-  if (!VFS) {
-    delete OverrideMainBuffer;
+  if (!VFS)
     return true;
-  }
   FileMgr = new FileManager(FileSystemOpts, VFS);
   SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
                                 UserFilesAreVolatile);
@@ -1115,7 +1099,8 @@
   // make that override happen and introduce the preamble.
   PreprocessorOptions &PreprocessorOpts = Clang->getPreprocessorOpts();
   if (OverrideMainBuffer) {
-    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
+    PreprocessorOpts.addRemappedFile(OriginalSourceFile,
+                                     OverrideMainBuffer.get());
     PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
     PreprocessorOpts.PrecompiledPreambleBytes.second
                                                     = PreambleEndsAtStartOfLine;
@@ -1130,7 +1115,7 @@
     checkAndSanitizeDiags(StoredDiagnostics, getSourceManager());
 
     // Keep track of the override buffer;
-    SavedMainFileBuffer = OverrideMainBuffer;
+    SavedMainFileBuffer = std::move(OverrideMainBuffer);
   }
 
   std::unique_ptr<TopLevelDeclTrackerAction> Act(
@@ -1143,7 +1128,7 @@
   if (!Act->BeginSourceFile(*Clang.get(), Clang->getFrontendOpts().Inputs[0]))
     goto error;
 
-  if (OverrideMainBuffer) {
+  if (SavedMainFileBuffer) {
     std::string ModName = getPreambleFile(this);
     TranslateStoredDiagnostics(getFileManager(), getSourceManager(),
                                PreambleDiagnostics, StoredDiagnostics);
@@ -1162,10 +1147,7 @@
 
 error:
   // Remove the overridden buffer we used for the preamble.
-  if (OverrideMainBuffer) {
-    delete OverrideMainBuffer;
-    SavedMainFileBuffer = nullptr;
-  }
+  SavedMainFileBuffer = nullptr;
 
   // Keep the ownership of the data in the ASTUnit because the client may
   // want to see the diagnostics.
@@ -1194,17 +1176,16 @@
 /// \brief Compute the preamble for the main file, providing the source buffer
 /// that corresponds to the main file along with a pair (bytes, start-of-line)
 /// that describes the preamble.
-std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > 
-ASTUnit::ComputePreamble(CompilerInvocation &Invocation, 
-                         unsigned MaxLines, bool &CreatedBuffer) {
+ASTUnit::ComputedPreamble
+ASTUnit::ComputePreamble(CompilerInvocation &Invocation, unsigned MaxLines) {
   FrontendOptions &FrontendOpts = Invocation.getFrontendOpts();
   PreprocessorOptions &PreprocessorOpts = Invocation.getPreprocessorOpts();
-  CreatedBuffer = false;
   
   // Try to determine if the main file has been remapped, either from the 
   // command line (to another file) or directly through the compiler invocation
   // (to a memory buffer).
   llvm::MemoryBuffer *Buffer = nullptr;
+  std::unique_ptr<llvm::MemoryBuffer> BufferOwner;
   std::string MainFilePath(FrontendOpts.Inputs[0].getFile());
   llvm::sys::fs::UniqueID MainFileID;
   if (!llvm::sys::fs::getUniqueID(MainFilePath, MainFileID)) {
@@ -1215,15 +1196,9 @@
       if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
         if (MainFileID == MID) {
           // We found a remapping. Try to load the resulting, remapped source.
-          if (CreatedBuffer) {
-            delete Buffer;
-            CreatedBuffer = false;
-          }
-
-          Buffer = getBufferForFile(RF.second);
-          if (!Buffer)
-            return std::make_pair(nullptr, std::make_pair(0, true));
-          CreatedBuffer = true;
+          BufferOwner = getBufferForFile(RF.second);
+          if (!BufferOwner)
+            return ComputedPreamble(nullptr, nullptr, 0, true);
         }
       }
     }
@@ -1236,11 +1211,7 @@
       if (!llvm::sys::fs::getUniqueID(MPath, MID)) {
         if (MainFileID == MID) {
           // We found a remapping.
-          if (CreatedBuffer) {
-            delete Buffer;
-            CreatedBuffer = false;
-          }
-
+          BufferOwner.reset();
           Buffer = const_cast<llvm::MemoryBuffer *>(RB.second);
         }
       }
@@ -1248,17 +1219,18 @@
   }
   
   // If the main source file was not remapped, load it now.
-  if (!Buffer) {
-    Buffer = getBufferForFile(FrontendOpts.Inputs[0].getFile());
-    if (!Buffer)
-      return std::make_pair(nullptr, std::make_pair(0, true));
-
-    CreatedBuffer = true;
+  if (!Buffer && !BufferOwner) {
+    BufferOwner = getBufferForFile(FrontendOpts.Inputs[0].getFile());
+    if (!BufferOwner)
+      return ComputedPreamble(nullptr, nullptr, 0, true);
   }
-  
-  return std::make_pair(Buffer, Lexer::ComputePreamble(Buffer,
-                                                       *Invocation.getLangOpts(),
-                                                       MaxLines));
+
+  if (!Buffer)
+    Buffer = BufferOwner.get();
+  auto Pre = Lexer::ComputePreamble(Buffer->getBuffer(),
+                                    *Invocation.getLangOpts(), MaxLines);
+  return ComputedPreamble(Buffer, std::move(BufferOwner), Pre.first,
+                          Pre.second);
 }
 
 ASTUnit::PreambleFileHash
@@ -1300,42 +1272,44 @@
   return std::make_pair(Offset, EndOffset);
 }
 
-static void makeStandaloneFixIt(const SourceManager &SM,
-                                const LangOptions &LangOpts,
-                                const FixItHint &InFix,
-                                ASTUnit::StandaloneFixIt &OutFix) {
+static ASTUnit::StandaloneFixIt makeStandaloneFixIt(const SourceManager &SM,
+                                                    const LangOptions &LangOpts,
+                                                    const FixItHint &InFix) {
+  ASTUnit::StandaloneFixIt OutFix;
   OutFix.RemoveRange = makeStandaloneRange(InFix.RemoveRange, SM, LangOpts);
   OutFix.InsertFromRange = makeStandaloneRange(InFix.InsertFromRange, SM,
                                                LangOpts);
   OutFix.CodeToInsert = InFix.CodeToInsert;
   OutFix.BeforePreviousInsertions = InFix.BeforePreviousInsertions;
+  return OutFix;
 }
 
-static void makeStandaloneDiagnostic(const LangOptions &LangOpts,
-                                     const StoredDiagnostic &InDiag,
-                                     ASTUnit::StandaloneDiagnostic &OutDiag) {
+static ASTUnit::StandaloneDiagnostic
+makeStandaloneDiagnostic(const LangOptions &LangOpts,
+                         const StoredDiagnostic &InDiag) {
+  ASTUnit::StandaloneDiagnostic OutDiag;
   OutDiag.ID = InDiag.getID();
   OutDiag.Level = InDiag.getLevel();
   OutDiag.Message = InDiag.getMessage();
   OutDiag.LocOffset = 0;
   if (InDiag.getLocation().isInvalid())
-    return;
+    return OutDiag;
   const SourceManager &SM = InDiag.getLocation().getManager();
   SourceLocation FileLoc = SM.getFileLoc(InDiag.getLocation());
   OutDiag.Filename = SM.getFilename(FileLoc);
   if (OutDiag.Filename.empty())
-    return;
+    return OutDiag;
   OutDiag.LocOffset = SM.getFileOffset(FileLoc);
   for (StoredDiagnostic::range_iterator
          I = InDiag.range_begin(), E = InDiag.range_end(); I != E; ++I) {
     OutDiag.Ranges.push_back(makeStandaloneRange(*I, SM, LangOpts));
   }
-  for (StoredDiagnostic::fixit_iterator
-         I = InDiag.fixit_begin(), E = InDiag.fixit_end(); I != E; ++I) {
-    ASTUnit::StandaloneFixIt Fix;
-    makeStandaloneFixIt(SM, LangOpts, *I, Fix);
-    OutDiag.FixIts.push_back(Fix);
-  }
+  for (StoredDiagnostic::fixit_iterator I = InDiag.fixit_begin(),
+                                        E = InDiag.fixit_end();
+       I != E; ++I)
+    OutDiag.FixIts.push_back(makeStandaloneFixIt(SM, LangOpts, *I));
+
+  return OutDiag;
 }
 
 /// \brief Attempt to build or re-use a precompiled preamble when (re-)parsing
@@ -1358,27 +1332,20 @@
 /// \returns If the precompiled preamble can be used, returns a newly-allocated
 /// buffer that should be used in place of the main file when doing so.
 /// Otherwise, returns a NULL pointer.
-llvm::MemoryBuffer *ASTUnit::getMainBufferWithPrecompiledPreamble(
-                              const CompilerInvocation &PreambleInvocationIn,
-                                                           bool AllowRebuild,
-                                                           unsigned MaxLines) {
-  
+std::unique_ptr<llvm::MemoryBuffer>
+ASTUnit::getMainBufferWithPrecompiledPreamble(
+    const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild,
+    unsigned MaxLines) {
+
   IntrusiveRefCntPtr<CompilerInvocation>
     PreambleInvocation(new CompilerInvocation(PreambleInvocationIn));
   FrontendOptions &FrontendOpts = PreambleInvocation->getFrontendOpts();
   PreprocessorOptions &PreprocessorOpts
     = PreambleInvocation->getPreprocessorOpts();
 
-  bool CreatedPreambleBuffer = false;
-  std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > NewPreamble 
-    = ComputePreamble(*PreambleInvocation, MaxLines, CreatedPreambleBuffer);
+  ComputedPreamble NewPreamble = ComputePreamble(*PreambleInvocation, MaxLines);
 
-  // If ComputePreamble() Take ownership of the preamble buffer.
-  std::unique_ptr<llvm::MemoryBuffer> OwnedPreambleBuffer;
-  if (CreatedPreambleBuffer)
-    OwnedPreambleBuffer.reset(NewPreamble.first);
-
-  if (!NewPreamble.second.first) {
+  if (!NewPreamble.Size) {
     // We couldn't find a preamble in the main source. Clear out the current
     // preamble, if we have one. It's obviously no good any more.
     Preamble.clear();
@@ -1394,10 +1361,10 @@
     // preamble now that we did before, and that there's enough space in
     // the main-file buffer within the precompiled preamble to fit the
     // new main file.
-    if (Preamble.size() == NewPreamble.second.first &&
-        PreambleEndsAtStartOfLine == NewPreamble.second.second &&
-        memcmp(Preamble.getBufferStart(), NewPreamble.first->getBufferStart(),
-               NewPreamble.second.first) == 0) {
+    if (Preamble.size() == NewPreamble.Size &&
+        PreambleEndsAtStartOfLine == NewPreamble.PreambleEndsAtStartOfLine &&
+        memcmp(Preamble.getBufferStart(), NewPreamble.Buffer->getBufferStart(),
+               NewPreamble.Size) == 0) {
       // The preamble has not changed. We may be able to re-use the precompiled
       // preamble.
 
@@ -1467,7 +1434,7 @@
         getDiagnostics().setNumWarnings(NumWarningsInPreamble);
 
         return llvm::MemoryBuffer::getMemBufferCopy(
-            NewPreamble.first->getBuffer(), FrontendOpts.Inputs[0].getFile());
+            NewPreamble.Buffer->getBuffer(), FrontendOpts.Inputs[0].getFile());
       }
     }
 
@@ -1512,19 +1479,16 @@
   // subsequent reparses.
   StringRef MainFilename = FrontendOpts.Inputs[0].getFile();
   Preamble.assign(FileMgr->getFile(MainFilename),
-                  NewPreamble.first->getBufferStart(), 
-                  NewPreamble.first->getBufferStart() 
-                                                  + NewPreamble.second.first);
-  PreambleEndsAtStartOfLine = NewPreamble.second.second;
+                  NewPreamble.Buffer->getBufferStart(),
+                  NewPreamble.Buffer->getBufferStart() + NewPreamble.Size);
+  PreambleEndsAtStartOfLine = NewPreamble.PreambleEndsAtStartOfLine;
 
-  delete PreambleBuffer;
-  PreambleBuffer
-    = llvm::MemoryBuffer::getMemBufferCopy(
-        NewPreamble.first->getBuffer().slice(0, Preamble.size()), MainFilename);
+  PreambleBuffer = llvm::MemoryBuffer::getMemBufferCopy(
+      NewPreamble.Buffer->getBuffer().slice(0, Preamble.size()), MainFilename);
 
   // Remap the main source file to the preamble buffer.
   StringRef MainFilePath = FrontendOpts.Inputs[0].getFile();
-  PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer);
+  PreprocessorOpts.addRemappedFile(MainFilePath, PreambleBuffer.get());
 
   // Tell the compiler invocation to generate a temporary precompiled header.
   FrontendOpts.ProgramAction = frontend::GeneratePCH;
@@ -1607,13 +1571,11 @@
 
   // Transfer any diagnostics generated when parsing the preamble into the set
   // of preamble diagnostics.
-  for (stored_diag_iterator
-         I = stored_diag_afterDriver_begin(),
-         E = stored_diag_end(); I != E; ++I) {
-    StandaloneDiagnostic Diag;
-    makeStandaloneDiagnostic(Clang->getLangOpts(), *I, Diag);
-    PreambleDiagnostics.push_back(Diag);
-  }
+  for (stored_diag_iterator I = stored_diag_afterDriver_begin(),
+                            E = stored_diag_end();
+       I != E; ++I)
+    PreambleDiagnostics.push_back(
+        makeStandaloneDiagnostic(Clang->getLangOpts(), *I));
 
   Act->EndSourceFile();
 
@@ -1663,8 +1625,8 @@
     CompletionCacheTopLevelHashValue = 0;
     PreambleTopLevelHashValue = CurrentTopLevelHashValue;
   }
-  
-  return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.first->getBuffer(),
+
+  return llvm::MemoryBuffer::getMemBufferCopy(NewPreamble.Buffer->getBuffer(),
                                               MainFilename);
 }
 
@@ -1688,8 +1650,8 @@
   // created.
   assert(CI.hasInvocation() && "missing invocation");
   LangOpts = CI.getInvocation().LangOpts;
-  TheSema.reset(CI.takeSema());
-  Consumer.reset(CI.takeASTConsumer());
+  TheSema = CI.takeSema();
+  Consumer = CI.takeASTConsumer();
   if (CI.hasASTContext())
     Ctx = &CI.getASTContext();
   if (CI.hasPreprocessor())
@@ -1735,7 +1697,7 @@
                          bool UserFilesAreVolatile) {
   std::unique_ptr<ASTUnit> AST;
   AST.reset(new ASTUnit(false));
-  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
+  ConfigureDiags(Diags, *AST, CaptureDiagnostics);
   AST->Diagnostics = Diags;
   AST->Invocation = CI;
   AST->FileSystemOpts = CI->getFileSystemOpts();
@@ -1862,13 +1824,15 @@
 
   if (Persistent && !TrackerAct) {
     Clang->getPreprocessor().addPPCallbacks(
-     new MacroDefinitionTrackerPPCallbacks(AST->getCurrentTopLevelHashValue()));
-    std::vector<ASTConsumer*> Consumers;
+        llvm::make_unique<MacroDefinitionTrackerPPCallbacks>(
+                                           AST->getCurrentTopLevelHashValue()));
+    std::vector<std::unique_ptr<ASTConsumer>> Consumers;
     if (Clang->hasASTConsumer())
       Consumers.push_back(Clang->takeASTConsumer());
-    Consumers.push_back(new TopLevelDeclTrackerConsumer(*AST,
-                                           AST->getCurrentTopLevelHashValue()));
-    Clang->setASTConsumer(new MultiplexConsumer(Consumers));
+    Consumers.push_back(llvm::make_unique<TopLevelDeclTrackerConsumer>(
+        *AST, AST->getCurrentTopLevelHashValue()));
+    Clang->setASTConsumer(
+        llvm::make_unique<MultiplexConsumer>(std::move(Consumers)));
   }
   if (!Act->Execute()) {
     AST->transferASTDataFromCompilerInstance(*Clang);
@@ -1898,11 +1862,10 @@
   Invocation->getFrontendOpts().DisableFree = false;
   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
 
-  llvm::MemoryBuffer *OverrideMainBuffer = nullptr;
+  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (PrecompilePreamble) {
     PreambleRebuildCounter = 2;
-    OverrideMainBuffer
-      = getMainBufferWithPrecompiledPreamble(*Invocation);
+    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
   }
   
   SimpleTimer ParsingTimer(WantTiming);
@@ -1910,9 +1873,9 @@
   
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
-    MemBufferCleanup(OverrideMainBuffer);
-  
-  return Parse(OverrideMainBuffer);
+    MemBufferCleanup(OverrideMainBuffer.get());
+
+  return Parse(std::move(OverrideMainBuffer));
 }
 
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
@@ -1922,7 +1885,7 @@
     bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) {
   // Create the AST unit.
   std::unique_ptr<ASTUnit> AST(new ASTUnit(false));
-  ConfigureDiags(Diags, nullptr, nullptr, *AST, CaptureDiagnostics);
+  ConfigureDiags(Diags, *AST, CaptureDiagnostics);
   AST->Diagnostics = Diags;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
@@ -1961,11 +1924,7 @@
     bool AllowPCHWithCompilerErrors, bool SkipFunctionBodies,
     bool UserFilesAreVolatile, bool ForSerialization,
     std::unique_ptr<ASTUnit> *ErrAST) {
-  if (!Diags.get()) {
-    // No diagnostics engine was provided, so create our own diagnostics object
-    // with the default options.
-    Diags = CompilerInstance::createDiagnostics(new DiagnosticOptions());
-  }
+  assert(Diags.get() && "no DiagnosticsEngine was provided");
 
   SmallVector<StoredDiagnostic, 4> StoredDiagnostics;
   
@@ -2000,9 +1959,8 @@
   // Create the AST unit.
   std::unique_ptr<ASTUnit> AST;
   AST.reset(new ASTUnit(false));
-  ConfigureDiags(Diags, ArgBegin, ArgEnd, *AST, CaptureDiagnostics);
+  ConfigureDiags(Diags, *AST, CaptureDiagnostics);
   AST->Diagnostics = Diags;
-  Diags = nullptr; // Zero out now to ease cleanup during crash recovery.
   AST->FileSystemOpts = CI->getFileSystemOpts();
   IntrusiveRefCntPtr<vfs::FileSystem> VFS =
       createVFSFromCompilerInvocation(*CI, *Diags);
@@ -2021,7 +1979,9 @@
   AST->Invocation = CI;
   if (ForSerialization)
     AST->WriterData.reset(new ASTWriterData());
-  CI = nullptr; // Zero out now to ease cleanup during crash recovery.
+  // Zero out now to ease cleanup during crash recovery.
+  CI = nullptr;
+  Diags = nullptr;
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
@@ -2062,7 +2022,7 @@
 
   // If we have a preamble file lying around, or if we might try to
   // build a precompiled preamble, do so now.
-  llvm::MemoryBuffer *OverrideMainBuffer = nullptr;
+  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0)
     OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
     
@@ -2073,8 +2033,8 @@
     getDiagnostics().setNumWarnings(NumWarningsInPreamble);
 
   // Parse the sources
-  bool Result = Parse(OverrideMainBuffer);
-  
+  bool Result = Parse(std::move(OverrideMainBuffer));
+
   // If we're caching global code-completion results, and the top-level 
   // declarations have changed, clear out the code-completion cache.
   if (!Result && ShouldCacheCodeCompletionResults &&
@@ -2366,6 +2326,10 @@
   // Set the language options appropriately.
   LangOpts = *CCInvocation->getLangOpts();
 
+  // Spell-checking and warnings are wasteful during code-completion.
+  LangOpts.SpellChecking = false;
+  CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
+
   std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
 
   // Recover resources if we crash before exiting this method.
@@ -2427,7 +2391,7 @@
   // the use of the precompiled preamble if we're if the completion
   // point is within the main file, after the end of the precompiled
   // preamble.
-  llvm::MemoryBuffer *OverrideMainBuffer = nullptr;
+  std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (!getPreambleFile(this).empty()) {
     std::string CompleteFilePath(File);
     llvm::sys::fs::UniqueID CompleteFileID;
@@ -2437,9 +2401,8 @@
       llvm::sys::fs::UniqueID MainID;
       if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {
         if (CompleteFileID == MainID && Line > 1)
-          OverrideMainBuffer
-            = getMainBufferWithPrecompiledPreamble(*CCInvocation, false, 
-                                                   Line - 1);
+          OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
+              *CCInvocation, false, Line - 1);
       }
     }
   }
@@ -2447,14 +2410,15 @@
   // If the main file has been overridden due to the use of a preamble,
   // make that override happen and introduce the preamble.
   if (OverrideMainBuffer) {
-    PreprocessorOpts.addRemappedFile(OriginalSourceFile, OverrideMainBuffer);
+    PreprocessorOpts.addRemappedFile(OriginalSourceFile,
+                                     OverrideMainBuffer.get());
     PreprocessorOpts.PrecompiledPreambleBytes.first = Preamble.size();
     PreprocessorOpts.PrecompiledPreambleBytes.second
                                                     = PreambleEndsAtStartOfLine;
     PreprocessorOpts.ImplicitPCHInclude = getPreambleFile(this);
     PreprocessorOpts.DisablePCHValidation = true;
-    
-    OwnedBuffers.push_back(OverrideMainBuffer);
+
+    OwnedBuffers.push_back(OverrideMainBuffer.release());
   } else {
     PreprocessorOpts.PrecompiledPreambleBytes.first = 0;
     PreprocessorOpts.PrecompiledPreambleBytes.second = false;
@@ -2821,7 +2785,8 @@
 static bool PCHLocator(serialization::ModuleFile &M, void *UserData) {
   PCHLocatorInfo &Info = *static_cast<PCHLocatorInfo*>(UserData);
   switch (M.Kind) {
-  case serialization::MK_Module:
+  case serialization::MK_ImplicitModule:
+  case serialization::MK_ExplicitModule:
     return true; // skip dependencies.
   case serialization::MK_PCH:
     Info.Mod = &M;
diff --git a/lib/Frontend/Android.mk b/lib/Frontend/Android.mk
index 255da76..7e08621 100644
--- a/lib/Frontend/Android.mk
+++ b/lib/Frontend/Android.mk
@@ -26,6 +26,7 @@
   CacheTokens.cpp \
   ChainedDiagnosticConsumer.cpp \
   ChainedIncludesSource.cpp \
+  CodeGenOptions.cpp \
   CompilerInstance.cpp \
   CompilerInvocation.cpp \
   CreateInvocationFromCommandLine.cpp \
@@ -45,8 +46,9 @@
   MultiplexConsumer.cpp \
   PrintPreprocessedOutput.cpp \
   SerializedDiagnosticPrinter.cpp \
-  TextDiagnostic.cpp \
+  SerializedDiagnosticReader.cpp \
   TextDiagnosticBuffer.cpp \
+  TextDiagnostic.cpp \
   TextDiagnosticPrinter.cpp \
   VerifyDiagnosticConsumer.cpp
 
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index 3fa7a2c..7c5fca5 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -1,4 +1,7 @@
+add_subdirectory(Rewrite)
+
 set(LLVM_LINK_COMPONENTS
+  BitReader
   Option
   Support
   )
@@ -10,6 +13,7 @@
   CacheTokens.cpp
   ChainedDiagnosticConsumer.cpp
   ChainedIncludesSource.cpp
+  CodeGenOptions.cpp
   CompilerInstance.cpp
   CompilerInvocation.cpp
   CreateInvocationFromCommandLine.cpp
@@ -29,6 +33,7 @@
   MultiplexConsumer.cpp
   PrintPreprocessedOutput.cpp
   SerializedDiagnosticPrinter.cpp
+  SerializedDiagnosticReader.cpp
   TextDiagnostic.cpp
   TextDiagnosticBuffer.cpp
   TextDiagnosticPrinter.cpp
diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp
index 14f7027..d909d52 100644
--- a/lib/Frontend/CacheTokens.cpp
+++ b/lib/Frontend/CacheTokens.cpp
@@ -270,17 +270,17 @@
     StringRef s(T.getLiteralData(), T.getLength());
 
     // Get the string entry.
-    llvm::StringMapEntry<OffsetOpt> *E = &CachedStrs.GetOrCreateValue(s);
+    auto &E = *CachedStrs.insert(std::make_pair(s, OffsetOpt())).first;
 
     // If this is a new string entry, bump the PTH offset.
-    if (!E->getValue().hasOffset()) {
-      E->getValue().setOffset(CurStrOffset);
-      StrEntries.push_back(E);
+    if (!E.second.hasOffset()) {
+      E.second.setOffset(CurStrOffset);
+      StrEntries.push_back(&E);
       CurStrOffset += s.size() + 1;
     }
 
     // Emit the relative offset into the PTH file for the spelling string.
-    Emit32(E->getValue().getOffset());
+    Emit32(E.second.getOffset());
   }
 
   // Emit the offset into the original source file of this token so that we
@@ -572,8 +572,10 @@
   PTHWriter PW(*OS, PP);
 
   // Install the 'stat' system call listener in the FileManager.
-  StatListener *StatCache = new StatListener(PW.getPM());
-  PP.getFileManager().addStatCache(StatCache, /*AtBeginning=*/true);
+  auto StatCacheOwner = llvm::make_unique<StatListener>(PW.getPM());
+  StatListener *StatCache = StatCacheOwner.get();
+  PP.getFileManager().addStatCache(std::move(StatCacheOwner),
+                                   /*AtBeginning=*/true);
 
   // Lex through the entire file.  This will populate SourceManager with
   // all of the header information.
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index e6e73ac..cb260b4 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -74,7 +74,7 @@
 
 static ASTReader *
 createASTReader(CompilerInstance &CI, StringRef pchFile,
-                SmallVectorImpl<llvm::MemoryBuffer *> &memBufs,
+                SmallVectorImpl<std::unique_ptr<llvm::MemoryBuffer>> &MemBufs,
                 SmallVectorImpl<std::string> &bufNames,
                 ASTDeserializationListener *deserialListener = nullptr) {
   Preprocessor &PP = CI.getPreprocessor();
@@ -83,7 +83,7 @@
                              /*DisableValidation=*/true));
   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
     StringRef sr(bufNames[ti]);
-    Reader->addInMemoryBuffer(sr, memBufs[ti]);
+    Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
   }
   Reader->setDeserializationListener(deserialListener);
   switch (Reader->ReadAST(pchFile, serialization::MK_PCH, SourceLocation(),
@@ -118,7 +118,7 @@
   IntrusiveRefCntPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
   InputKind IK = CI.getFrontendOpts().Inputs[0].getKind();
 
-  SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
+  SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> SerialBufs;
   SmallVector<std::string, 4> serialBufNames;
 
   for (unsigned i = 0, e = includes.size(); i != e; ++i) {
@@ -158,12 +158,12 @@
 
     SmallVector<char, 256> serialAST;
     llvm::raw_svector_ostream OS(serialAST);
-    std::unique_ptr<ASTConsumer> consumer;
-    consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-", nullptr,
-                                    /*isysroot=*/"", &OS));
+    auto consumer =
+        llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr,
+                                        /*isysroot=*/"", &OS);
     Clang->getASTContext().setASTMutationListener(
                                             consumer->GetASTMutationListener());
-    Clang->setASTConsumer(consumer.release());
+    Clang->setASTConsumer(std::move(consumer));
     Clang->createSema(TU_Prefix, nullptr);
 
     if (firstInclude) {
@@ -171,20 +171,21 @@
       PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                              PP.getLangOpts());
     } else {
-      assert(!serialBufs.empty());
-      SmallVector<llvm::MemoryBuffer *, 4> bufs;
+      assert(!SerialBufs.empty());
+      SmallVector<std::unique_ptr<llvm::MemoryBuffer>, 4> Bufs;
       // TODO: Pass through the existing MemoryBuffer instances instead of
       // allocating new ones.
-      for (auto *SB : serialBufs)
-        bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
+      for (auto &SB : SerialBufs)
+        Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));
       std::string pchName = includes[i-1];
       llvm::raw_string_ostream os(pchName);
       os << ".pch" << i-1;
       serialBufNames.push_back(os.str());
 
       IntrusiveRefCntPtr<ASTReader> Reader;
-      Reader = createASTReader(*Clang, pchName, bufs, serialBufNames, 
-        Clang->getASTConsumer().GetASTDeserializationListener());
+      Reader = createASTReader(
+          *Clang, pchName, Bufs, serialBufNames,
+          Clang->getASTConsumer().GetASTDeserializationListener());
       if (!Reader)
         return nullptr;
       Clang->setModuleManager(Reader);
@@ -196,14 +197,14 @@
 
     ParseAST(Clang->getSema());
     Clang->getDiagnosticClient().EndSourceFile();
-    serialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
+    SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
     source->CIs.push_back(Clang.release());
   }
 
-  assert(!serialBufs.empty());
+  assert(!SerialBufs.empty());
   std::string pchName = includes.back() + ".pch-final";
   serialBufNames.push_back(pchName);
-  Reader = createASTReader(CI, pchName, serialBufs, serialBufNames);
+  Reader = createASTReader(CI, pchName, SerialBufs, serialBufNames);
   if (!Reader)
     return nullptr;
 
diff --git a/lib/Frontend/CodeGenOptions.cpp b/lib/Frontend/CodeGenOptions.cpp
new file mode 100644
index 0000000..4fa28b4
--- /dev/null
+++ b/lib/Frontend/CodeGenOptions.cpp
@@ -0,0 +1,24 @@
+//===--- CodeGenOptions.cpp -----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+#include "clang/Frontend/CodeGenOptions.h"
+
+namespace clang {
+
+CodeGenOptions::CodeGenOptions() {
+#define CODEGENOPT(Name, Bits, Default) Name = Default;
+#define ENUM_CODEGENOPT(Name, Type, Bits, Default) set##Name(Default);
+#include "clang/Frontend/CodeGenOptions.def"
+
+  RelocationModel = "pic";
+  memcpy(CoverageVersion, "402*", 4);
+}
+
+}  // end namespace clang
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index 7cea9e4..b059965 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -101,14 +101,18 @@
   TheSema.reset(S);
 }
 
-void CompilerInstance::setASTConsumer(ASTConsumer *Value) {
-  Consumer.reset(Value);
+void CompilerInstance::setASTConsumer(std::unique_ptr<ASTConsumer> Value) {
+  Consumer = std::move(Value);
 }
 
 void CompilerInstance::setCodeCompletionConsumer(CodeCompleteConsumer *Value) {
   CompletionConsumer.reset(Value);
 }
- 
+
+std::unique_ptr<Sema> CompilerInstance::takeSema() {
+  return std::move(TheSema);
+}
+
 IntrusiveRefCntPtr<ASTReader> CompilerInstance::getModuleManager() const {
   return ModuleManager;
 }
@@ -130,52 +134,48 @@
 static void SetUpDiagnosticLog(DiagnosticOptions *DiagOpts,
                                const CodeGenOptions *CodeGenOpts,
                                DiagnosticsEngine &Diags) {
-  std::string ErrorInfo;
-  bool OwnsStream = false;
+  std::error_code EC;
+  std::unique_ptr<raw_ostream> StreamOwner;
   raw_ostream *OS = &llvm::errs();
   if (DiagOpts->DiagnosticLogFile != "-") {
     // Create the output stream.
-    llvm::raw_fd_ostream *FileOS(new llvm::raw_fd_ostream(
-        DiagOpts->DiagnosticLogFile.c_str(), ErrorInfo,
-        llvm::sys::fs::F_Append | llvm::sys::fs::F_Text));
-    if (!ErrorInfo.empty()) {
+    auto FileOS = llvm::make_unique<llvm::raw_fd_ostream>(
+        DiagOpts->DiagnosticLogFile, EC,
+        llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
+    if (EC) {
       Diags.Report(diag::warn_fe_cc_log_diagnostics_failure)
-        << DiagOpts->DiagnosticLogFile << ErrorInfo;
+          << DiagOpts->DiagnosticLogFile << EC.message();
     } else {
       FileOS->SetUnbuffered();
       FileOS->SetUseAtomicWrites(true);
-      OS = FileOS;
-      OwnsStream = true;
+      OS = FileOS.get();
+      StreamOwner = std::move(FileOS);
     }
   }
 
   // Chain in the diagnostic client which will log the diagnostics.
-  LogDiagnosticPrinter *Logger = new LogDiagnosticPrinter(*OS, DiagOpts,
-                                                          OwnsStream);
+  auto Logger = llvm::make_unique<LogDiagnosticPrinter>(*OS, DiagOpts,
+                                                        std::move(StreamOwner));
   if (CodeGenOpts)
     Logger->setDwarfDebugFlags(CodeGenOpts->DwarfDebugFlags);
-  Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(), Logger));
+  assert(Diags.ownsClient());
+  Diags.setClient(
+      new ChainedDiagnosticConsumer(Diags.takeClient(), std::move(Logger)));
 }
 
 static void SetupSerializedDiagnostics(DiagnosticOptions *DiagOpts,
                                        DiagnosticsEngine &Diags,
                                        StringRef OutputFile) {
-  std::string ErrorInfo;
-  std::unique_ptr<llvm::raw_fd_ostream> OS;
-  OS.reset(new llvm::raw_fd_ostream(OutputFile.str().c_str(), ErrorInfo,
-                                    llvm::sys::fs::F_None));
+  auto SerializedConsumer =
+      clang::serialized_diags::create(OutputFile, DiagOpts);
 
-  if (!ErrorInfo.empty()) {
-    Diags.Report(diag::warn_fe_serialized_diag_failure)
-      << OutputFile << ErrorInfo;
-    return;
+  if (Diags.ownsClient()) {
+    Diags.setClient(new ChainedDiagnosticConsumer(
+        Diags.takeClient(), std::move(SerializedConsumer)));
+  } else {
+    Diags.setClient(new ChainedDiagnosticConsumer(
+        Diags.getClient(), std::move(SerializedConsumer)));
   }
-
-  DiagnosticConsumer *SerializedConsumer =
-      clang::serialized_diags::create(OS.release(), DiagOpts);
-
-  Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(),
-                                                SerializedConsumer));
 }
 
 void CompilerInstance::createDiagnostics(DiagnosticConsumer *Client,
@@ -569,17 +569,14 @@
                                    StringRef Extension,
                                    bool UseTemporary,
                                    bool CreateMissingDirectories) {
-  std::string Error, OutputPathName, TempPathName;
-  llvm::raw_fd_ostream *OS = createOutputFile(OutputPath, Error, Binary,
-                                              RemoveFileOnSignal,
-                                              InFile, Extension,
-                                              UseTemporary,
-                                              CreateMissingDirectories,
-                                              &OutputPathName,
-                                              &TempPathName);
+  std::string OutputPathName, TempPathName;
+  std::error_code EC;
+  llvm::raw_fd_ostream *OS = createOutputFile(
+      OutputPath, EC, Binary, RemoveFileOnSignal, InFile, Extension,
+      UseTemporary, CreateMissingDirectories, &OutputPathName, &TempPathName);
   if (!OS) {
-    getDiagnostics().Report(diag::err_fe_unable_to_open_output)
-      << OutputPath << Error;
+    getDiagnostics().Report(diag::err_fe_unable_to_open_output) << OutputPath
+                                                                << EC.message();
     return nullptr;
   }
 
@@ -591,17 +588,11 @@
   return OS;
 }
 
-llvm::raw_fd_ostream *
-CompilerInstance::createOutputFile(StringRef OutputPath,
-                                   std::string &Error,
-                                   bool Binary,
-                                   bool RemoveFileOnSignal,
-                                   StringRef InFile,
-                                   StringRef Extension,
-                                   bool UseTemporary,
-                                   bool CreateMissingDirectories,
-                                   std::string *ResultPathName,
-                                   std::string *TempPathName) {
+llvm::raw_fd_ostream *CompilerInstance::createOutputFile(
+    StringRef OutputPath, std::error_code &Error, bool Binary,
+    bool RemoveFileOnSignal, StringRef InFile, StringRef Extension,
+    bool UseTemporary, bool CreateMissingDirectories,
+    std::string *ResultPathName, std::string *TempPathName) {
   assert((!CreateMissingDirectories || UseTemporary) &&
          "CreateMissingDirectories is only allowed when using temporary files");
 
@@ -670,9 +661,9 @@
   if (!OS) {
     OSFile = OutFile;
     OS.reset(new llvm::raw_fd_ostream(
-        OSFile.c_str(), Error,
+        OSFile, Error,
         (Binary ? llvm::sys::fs::F_None : llvm::sys::fs::F_Text)));
-    if (!Error.empty())
+    if (Error)
       return nullptr;
   }
 
@@ -705,7 +696,8 @@
     Kind = Input.isSystem() ? SrcMgr::C_System : SrcMgr::C_User;
 
   if (Input.isBuffer()) {
-    SourceMgr.setMainFileID(SourceMgr.createFileID(Input.getBuffer(), Kind));
+    SourceMgr.setMainFileID(SourceMgr.createFileID(
+        std::unique_ptr<llvm::MemoryBuffer>(Input.getBuffer()), Kind));
     assert(!SourceMgr.getMainFileID().isInvalid() &&
            "Couldn't establish MainFileID!");
     return true;
@@ -727,14 +719,14 @@
     // pick up the correct size, and simply override their contents as we do for
     // STDIN.
     if (File->isNamedPipe()) {
-      std::string ErrorStr;
-      if (llvm::MemoryBuffer *MB =
-              FileMgr.getBufferForFile(File, &ErrorStr, /*isVolatile=*/true)) {
+      auto MB = FileMgr.getBufferForFile(File, /*isVolatile=*/true);
+      if (MB) {
         // Create a new virtual file that will have the correct size.
-        File = FileMgr.getVirtualFile(InputFile, MB->getBufferSize(), 0);
-        SourceMgr.overrideFileContents(File, MB);
+        File = FileMgr.getVirtualFile(InputFile, (*MB)->getBufferSize(), 0);
+        SourceMgr.overrideFileContents(File, std::move(*MB));
       } else {
-        Diags.Report(diag::err_cannot_open_file) << InputFile << ErrorStr;
+        Diags.Report(diag::err_cannot_open_file) << InputFile
+                                                 << MB.getError().message();
         return false;
       }
     }
@@ -754,7 +746,7 @@
                                                    SB->getBufferSize(), 0);
     SourceMgr.setMainFileID(
         SourceMgr.createFileID(File, SourceLocation(), Kind));
-    SourceMgr.overrideFileContents(File, SB.release());
+    SourceMgr.overrideFileContents(File, std::move(SB));
   }
 
   assert(!SourceMgr.getMainFileID().isInvalid() &&
@@ -802,8 +794,9 @@
     llvm::EnableStatistics();
 
   for (unsigned i = 0, e = getFrontendOpts().Inputs.size(); i != e; ++i) {
-    // Reset the ID tables if we are reusing the SourceManager.
-    if (hasSourceManager())
+    // Reset the ID tables if we are reusing the SourceManager and parsing
+    // regular files.
+    if (hasSourceManager() && !Act.isModelParsingAction())
       getSourceManager().clearIDTables();
 
     if (Act.BeginSourceFile(*this, getFrontendOpts().Inputs[i])) {
@@ -852,11 +845,12 @@
 }
 
 /// \brief Compile a module file for the given module, using the options 
-/// provided by the importing compiler instance.
-static void compileModuleImpl(CompilerInstance &ImportingInstance,
-                          SourceLocation ImportLoc,
-                          Module *Module,
-                          StringRef ModuleFileName) {
+/// provided by the importing compiler instance. Returns true if the module
+/// was built without errors.
+static bool compileModuleImpl(CompilerInstance &ImportingInstance,
+                              SourceLocation ImportLoc,
+                              Module *Module,
+                              StringRef ModuleFileName) {
   ModuleMap &ModMap 
     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
     
@@ -950,17 +944,22 @@
     FrontendOpts.Inputs.push_back(
         FrontendInputFile("__inferred_module.map", IK));
 
-    llvm::MemoryBuffer *ModuleMapBuffer =
+    std::unique_ptr<llvm::MemoryBuffer> ModuleMapBuffer =
         llvm::MemoryBuffer::getMemBuffer(InferredModuleMapContent);
     ModuleMapFile = Instance.getFileManager().getVirtualFile(
         "__inferred_module.map", InferredModuleMapContent.size(), 0);
-    SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer);
+    SourceMgr.overrideFileContents(ModuleMapFile, std::move(ModuleMapBuffer));
   }
 
-  // Construct a module-generating action. Passing through Module->ModuleMap is
+  // Construct a module-generating action. Passing through the module map is
   // safe because the FileManager is shared between the compiler instances.
-  GenerateModuleAction CreateModuleAction(Module->ModuleMap, Module->IsSystem);
-  
+  GenerateModuleAction CreateModuleAction(
+      ModMap.getModuleMapFileForUniquing(Module), Module->IsSystem);
+
+  ImportingInstance.getDiagnostics().Report(ImportLoc,
+                                            diag::remark_module_build)
+    << Module->Name << ModuleFileName;
+
   // Execute the action to actually build the module in-place. Use a separate
   // thread so that we get a stack large enough.
   const unsigned ThreadStackSize = 8 << 20;
@@ -968,6 +967,10 @@
   CRC.RunSafelyOnThread([&]() { Instance.ExecuteAction(CreateModuleAction); },
                         ThreadStackSize);
 
+  ImportingInstance.getDiagnostics().Report(ImportLoc,
+                                            diag::remark_module_build_done)
+    << Module->Name;
+
   // Delete the temporary module map file.
   // FIXME: Even though we're executing under crash protection, it would still
   // be nice to do this with RemoveFileOnSignal when we can. However, that
@@ -979,13 +982,21 @@
   if (ImportingInstance.getFrontendOpts().GenerateGlobalModuleIndex) {
     ImportingInstance.setBuildGlobalModuleIndex(true);
   }
+
+  return !Instance.getDiagnostics().hasErrorOccurred();
 }
 
 static bool compileAndLoadModule(CompilerInstance &ImportingInstance,
                                  SourceLocation ImportLoc,
-                                 SourceLocation ModuleNameLoc,
-                                 Module *Module,
+                                 SourceLocation ModuleNameLoc, Module *Module,
                                  StringRef ModuleFileName) {
+  DiagnosticsEngine &Diags = ImportingInstance.getDiagnostics();
+
+  auto diagnoseBuildFailure = [&] {
+    Diags.Report(ModuleNameLoc, diag::err_module_not_built)
+        << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
+  };
+
   // FIXME: have LockFileManager return an error_code so that we can
   // avoid the mkdir when the directory already exists.
   StringRef Dir = llvm::sys::path::parent_path(ModuleFileName);
@@ -996,13 +1007,17 @@
     llvm::LockFileManager Locked(ModuleFileName);
     switch (Locked) {
     case llvm::LockFileManager::LFS_Error:
+      Diags.Report(ModuleNameLoc, diag::err_module_lock_failure)
+          << Module->Name;
       return false;
 
     case llvm::LockFileManager::LFS_Owned:
       // We're responsible for building the module ourselves.
-      // FIXME: if there are errors, don't attempt to load the module.
-      compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
-                        ModuleFileName);
+      if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
+                             ModuleFileName)) {
+        diagnoseBuildFailure();
+        return false;
+      }
       break;
 
     case llvm::LockFileManager::LFS_Shared:
@@ -1017,7 +1032,7 @@
     // Try to read the module file, now that we've compiled it.
     ASTReader::ASTReadResult ReadResult =
         ImportingInstance.getModuleManager()->ReadAST(
-            ModuleFileName, serialization::MK_Module, ImportLoc,
+            ModuleFileName, serialization::MK_ImplicitModule, ImportLoc,
             ModuleLoadCapabilities);
 
     if (ReadResult == ASTReader::OutOfDate &&
@@ -1027,9 +1042,11 @@
       // consistent with this ImportingInstance.  Try again...
       continue;
     } else if (ReadResult == ASTReader::Missing) {
-      ImportingInstance.getDiagnostics().Report(ModuleNameLoc,
-                                                diag::err_module_not_built)
-          << Module->Name << SourceRange(ImportLoc, ModuleNameLoc);
+      diagnoseBuildFailure();
+    } else if (ReadResult != ASTReader::Success &&
+               !Diags.hasErrorOccurred()) {
+      // The ASTReader didn't diagnose the error, so conservatively report it.
+      diagnoseBuildFailure();
     }
     return ReadResult == ASTReader::Success;
   }
@@ -1123,9 +1140,8 @@
 
 /// \brief Write a new timestamp file with the given path.
 static void writeTimestampFile(StringRef TimestampFile) {
-  std::string ErrorInfo;
-  llvm::raw_fd_ostream Out(TimestampFile.str().c_str(), ErrorInfo,
-                           llvm::sys::fs::F_None);
+  std::error_code EC;
+  llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
 }
 
 /// \brief Prune the module cache of modules that haven't been accessed in
@@ -1243,6 +1259,63 @@
   }
 }
 
+bool CompilerInstance::loadModuleFile(StringRef FileName) {
+  // Helper to recursively read the module names for all modules we're adding.
+  // We mark these as known and redirect any attempt to load that module to
+  // the files we were handed.
+  struct ReadModuleNames : ASTReaderListener {
+    CompilerInstance &CI;
+    std::vector<StringRef> ModuleFileStack;
+    bool Failed;
+    bool TopFileIsModule;
+
+    ReadModuleNames(CompilerInstance &CI)
+        : CI(CI), Failed(false), TopFileIsModule(false) {}
+
+    bool needsImportVisitation() const override { return true; }
+
+    void visitImport(StringRef FileName) override {
+      ModuleFileStack.push_back(FileName);
+      if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
+                                             *this)) {
+        CI.getDiagnostics().Report(SourceLocation(),
+                                   diag::err_module_file_not_found)
+            << FileName;
+        // FIXME: Produce a note stack explaining how we got here.
+        Failed = true;
+      }
+      ModuleFileStack.pop_back();
+    }
+
+    void ReadModuleName(StringRef ModuleName) override {
+      if (ModuleFileStack.size() == 1)
+        TopFileIsModule = true;
+
+      auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
+      if (!ModuleFile.empty() && ModuleFile != ModuleFileStack.back())
+        CI.getDiagnostics().Report(SourceLocation(),
+                                   diag::err_conflicting_module_files)
+            << ModuleName << ModuleFile << ModuleFileStack.back();
+      ModuleFile = ModuleFileStack.back();
+    }
+  } RMN(*this);
+
+  RMN.visitImport(FileName);
+
+  if (RMN.Failed)
+    return false;
+
+  // If we never found a module name for the top file, then it's not a module,
+  // it's a PCH or preamble or something.
+  if (!RMN.TopFileIsModule) {
+    getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)
+      << FileName;
+    return false;
+  }
+
+  return true;
+}
+
 ModuleLoadResult
 CompilerInstance::loadModule(SourceLocation ImportLoc,
                              ModuleIdPath Path,
@@ -1257,7 +1330,8 @@
   // when both the preprocessor and parser see the same import declaration.
   if (!ImportLoc.isInvalid() && LastModuleImportLoc == ImportLoc) {
     // Make the named module visible.
-    if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule)
+    if (LastModuleImportResult && ModuleName != getLangOpts().CurrentModule &&
+        ModuleName != getLangOpts().ImplementationOfModule)
       ModuleManager->makeModuleVisible(LastModuleImportResult, Visibility,
                                        ImportLoc, /*Complain=*/false);
     return LastModuleImportResult;
@@ -1271,7 +1345,8 @@
   if (Known != KnownModules.end()) {
     // Retrieve the cached top-level module.
     Module = Known->second;    
-  } else if (ModuleName == getLangOpts().CurrentModule) {
+  } else if (ModuleName == getLangOpts().CurrentModule ||
+             ModuleName == getLangOpts().ImplementationOfModule) {
     // This is the module we're building. 
     Module = PP->getHeaderSearchInfo().lookupModule(ModuleName);
     Known = KnownModules.insert(std::make_pair(Path[0].first, Module)).first;
@@ -1286,8 +1361,12 @@
       return ModuleLoadResult();
     }
 
+    auto Override = ModuleFileOverrides.find(ModuleName);
+    bool Explicit = Override != ModuleFileOverrides.end();
+
     std::string ModuleFileName =
-        PP->getHeaderSearchInfo().getModuleFileName(Module);
+        Explicit ? Override->second
+                 : PP->getHeaderSearchInfo().getModuleFileName(Module);
 
     // If we don't already have an ASTReader, create one now.
     if (!ModuleManager)
@@ -1303,14 +1382,24 @@
       Listener->attachToASTReader(*ModuleManager);
 
     // Try to load the module file.
-    unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
-    switch (ModuleManager->ReadAST(ModuleFileName, serialization::MK_Module,
+    unsigned ARRFlags =
+        Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
+    switch (ModuleManager->ReadAST(ModuleFileName,
+                                   Explicit ? serialization::MK_ExplicitModule
+                                            : serialization::MK_ImplicitModule,
                                    ImportLoc, ARRFlags)) {
     case ASTReader::Success:
       break;
 
     case ASTReader::OutOfDate:
     case ASTReader::Missing: {
+      if (Explicit) {
+        // ReadAST has already complained for us.
+        ModuleLoader::HadFatalFailure = true;
+        KnownModules[Path[0].first] = nullptr;
+        return ModuleLoadResult();
+      }
+
       // The module file is missing or out-of-date. Build it.
       assert(Module && "missing module file");
       // Check whether there is a cycle in the module graph.
@@ -1334,9 +1423,6 @@
         return ModuleLoadResult();
       }
 
-      getDiagnostics().Report(ImportLoc, diag::remark_module_build)
-          << ModuleName << ModuleFileName;
-
       // Check whether we have already attempted to build this module (but
       // failed).
       if (getPreprocessorOpts().FailedModules &&
@@ -1351,6 +1437,8 @@
       // Try to compile and then load the module.
       if (!compileAndLoadModule(*this, ImportLoc, ModuleNameLoc, Module,
                                 ModuleFileName)) {
+        assert(getDiagnostics().hasErrorOccurred() &&
+               "undiagnosed error in compileAndLoadModule");
         if (getPreprocessorOpts().FailedModules)
           getPreprocessorOpts().FailedModules->addFailed(ModuleName);
         KnownModules[Path[0].first] = nullptr;
@@ -1440,6 +1528,10 @@
       Module = Sub;
     }
   }
+
+  // Don't make the module visible if we are in the implementation.
+  if (ModuleName == getLangOpts().ImplementationOfModule)
+    return ModuleLoadResult(Module, false);
   
   // Make the named module visible, if it's not already part of the module
   // we are parsing.
@@ -1594,3 +1686,4 @@
 
   return false;
 }
+void CompilerInstance::resetAndLeakSema() { BuryPointer(takeSema()); }
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 3d79ac7..f261c6c 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -111,25 +111,21 @@
   return 0;
 }
 
-static void addWarningArgs(ArgList &Args, std::vector<std::string> &Warnings) {
-  for (arg_iterator I = Args.filtered_begin(OPT_W_Group),
-         E = Args.filtered_end(); I != E; ++I) {
-    Arg *A = *I;
-    // If the argument is a pure flag, add its name (minus the "W" at the beginning)
-    // to the warning list. Else, add its value (for the OPT_W case).
+static void addDiagnosticArgs(ArgList &Args, OptSpecifier Group,
+                              OptSpecifier GroupWithValue,
+                              std::vector<std::string> &Diagnostics) {
+  for (Arg *A : Args.filtered(Group)) {
     if (A->getOption().getKind() == Option::FlagClass) {
-      Warnings.push_back(A->getOption().getName().substr(1));
+      // The argument is a pure flag (such as OPT_Wall or OPT_Wdeprecated). Add
+      // its name (minus the "W" or "R" at the beginning) to the warning list.
+      Diagnostics.push_back(A->getOption().getName().drop_front(1));
+    } else if (A->getOption().matches(GroupWithValue)) {
+      // This is -Wfoo= or -Rfoo=, where foo is the name of the diagnostic group.
+      Diagnostics.push_back(A->getOption().getName().drop_front(1).rtrim("=-"));
     } else {
-      for (unsigned Idx = 0, End = A->getNumValues();
-           Idx < End; ++Idx) {
-        StringRef V = A->getValue(Idx);
-        // "-Wl," and such are not warning options.
-        // FIXME: Should be handled by putting these in separate flags.
-        if (V.startswith("l,") || V.startswith("a,") || V.startswith("p,"))
-          continue;
-
-        Warnings.push_back(V);
-      }
+      // Otherwise, add its value (for OPT_W_Joined and similar).
+      for (const char *Arg : A->getValues())
+        Diagnostics.push_back(Arg);
     }
   }
 }
@@ -219,6 +215,8 @@
   }
 
   Opts.ShowCheckerHelp = Args.hasArg(OPT_analyzer_checker_help);
+  Opts.DisableAllChecks = Args.hasArg(OPT_analyzer_disable_all_checks);
+
   Opts.visualizeExplodedGraphWithGraphViz =
     Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
   Opts.visualizeExplodedGraphWithUbiGraph =
@@ -403,6 +401,8 @@
   Opts.SampleProfileFile = Args.getLastArgValue(OPT_fprofile_sample_use_EQ);
   Opts.ProfileInstrGenerate = Args.hasArg(OPT_fprofile_instr_generate);
   Opts.InstrProfileInput = Args.getLastArgValue(OPT_fprofile_instr_use_EQ);
+  Opts.CoverageMapping = Args.hasArg(OPT_fcoverage_mapping);
+  Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
   Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
   Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions);
   Opts.CUDAIsDevice = Args.hasArg(OPT_fcuda_is_device);
@@ -427,6 +427,7 @@
   Opts.NumRegisterParameters = getLastArgIntValue(Args, OPT_mregparm, 0, Diags);
   Opts.NoGlobalMerge = Args.hasArg(OPT_mno_global_merge);
   Opts.NoExecStack = Args.hasArg(OPT_mno_exec_stack);
+  Opts.FatalWarnings = Args.hasArg(OPT_massembler_fatal_warnings);
   Opts.EnableSegmentedStacks = Args.hasArg(OPT_split_stacks);
   Opts.RelaxAll = Args.hasArg(OPT_mrelax_all);
   Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer);
@@ -439,6 +440,11 @@
                       Args.hasArg(OPT_cl_fast_relaxed_math);
   Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
   Opts.RelocationModel = Args.getLastArgValue(OPT_mrelocation_model, "pic");
+  Opts.ThreadModel = Args.getLastArgValue(OPT_mthread_model, "posix");
+  if (Opts.ThreadModel != "posix" && Opts.ThreadModel != "single")
+    Diags.Report(diag::err_drv_invalid_value)
+        << Args.getLastArg(OPT_mthread_model)->getAsString(Args)
+        << Opts.ThreadModel;
   Opts.TrapFuncName = Args.getLastArgValue(OPT_ftrap_function_EQ);
   Opts.UseInitArray = Args.hasArg(OPT_fuse_init_array);
 
@@ -446,6 +452,7 @@
                                        OPT_fno_function_sections, false);
   Opts.DataSections = Args.hasFlag(OPT_fdata_sections,
                                    OPT_fno_data_sections, false);
+  Opts.MergeFunctions = Args.hasArg(OPT_fmerge_functions);
 
   Opts.VectorizeBB = Args.hasArg(OPT_vectorize_slp_aggressive);
   Opts.VectorizeLoop = Args.hasArg(OPT_vectorize_loops);
@@ -459,7 +466,7 @@
   Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data);
   Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes);
   if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) {
-  Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file);
+    Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file);
     Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
     Opts.CoverageNoFunctionNamesInData =
         Args.hasArg(OPT_coverage_no_function_names_in_data);
@@ -481,7 +488,8 @@
   Opts.CompressDebugSections = Args.hasArg(OPT_compress_debug_sections);
   Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir);
   Opts.LinkBitcodeFile = Args.getLastArgValue(OPT_mlink_bitcode_file);
-  Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
+  Opts.SanitizeCoverage =
+      getLastArgIntValue(Args, OPT_fsanitize_coverage, 0, Diags);
   Opts.SanitizeMemoryTrackOrigins =
       getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
   Opts.SanitizeUndefinedTrapOnError =
@@ -570,8 +578,14 @@
     NeedLocTracking = true;
   }
 
-  // If the user requested one of the flags in the -Rpass family, make sure
-  // that the backend tracks source location information.
+  // If the user requested to use a sample profile for PGO, then the
+  // backend will need to track source location information so the profile
+  // can be incorporated into the IR.
+  if (!Opts.SampleProfileFile.empty())
+    NeedLocTracking = true;
+
+  // If the user requested a flag that requires source locations available in
+  // the backend, make sure that the backend tracks source location information.
   if (NeedLocTracking && Opts.getDebugInfo() == CodeGenOptions::NoDebugInfo)
     Opts.setDebugInfo(CodeGenOptions::LocTrackingOnly);
 
@@ -601,8 +615,9 @@
   bool Success = true;
 
   Opts.DiagnosticLogFile = Args.getLastArgValue(OPT_diagnostic_log_file);
-  Opts.DiagnosticSerializationFile =
-    Args.getLastArgValue(OPT_diagnostic_serialized_file);
+  if (Arg *A =
+          Args.getLastArg(OPT_diagnostic_serialized_file, OPT__serialize_diags))
+    Opts.DiagnosticSerializationFile = A->getValue();
   Opts.IgnoreWarnings = Args.hasArg(OPT_w);
   Opts.NoRewriteMacros = Args.hasArg(OPT_Wno_rewrite_macros);
   Opts.Pedantic = Args.hasArg(OPT_pedantic);
@@ -699,7 +714,8 @@
       << Opts.TabStop << DiagnosticOptions::DefaultTabStop;
   }
   Opts.MessageLength = getLastArgIntValue(Args, OPT_fmessage_length, 0, Diags);
-  addWarningArgs(Args, Opts.Warnings);
+  addDiagnosticArgs(Args, OPT_W_Group, OPT_W_value_Group, Opts.Warnings);
+  addDiagnosticArgs(Args, OPT_R_Group, OPT_R_value_Group, Opts.Remarks);
 
   return Success;
 }
@@ -719,6 +735,7 @@
     case OPT_ast_list:
       Opts.ProgramAction = frontend::ASTDeclList; break;
     case OPT_ast_dump:
+    case OPT_ast_dump_lookups:
       Opts.ProgramAction = frontend::ASTDump; break;
     case OPT_ast_print:
       Opts.ProgramAction = frontend::ASTPrint; break;
@@ -826,11 +843,13 @@
   Opts.FixOnlyWarnings = Args.hasArg(OPT_fix_only_warnings);
   Opts.FixAndRecompile = Args.hasArg(OPT_fixit_recompile);
   Opts.FixToTemporaries = Args.hasArg(OPT_fixit_to_temp);
+  Opts.ASTDumpDecls = Args.hasArg(OPT_ast_dump);
   Opts.ASTDumpFilter = Args.getLastArgValue(OPT_ast_dump_filter);
   Opts.ASTDumpLookups = Args.hasArg(OPT_ast_dump_lookups);
   Opts.UseGlobalModuleIndex = !Args.hasArg(OPT_fno_modules_global_index);
   Opts.GenerateGlobalModuleIndex = Opts.UseGlobalModuleIndex;
-  
+  Opts.ModuleFiles = Args.getAllArgValues(OPT_fmodule_file);
+
   Opts.CodeCompleteOpts.IncludeMacros
     = Args.hasArg(OPT_code_completion_macros);
   Opts.CodeCompleteOpts.IncludeCodePatterns
@@ -869,6 +888,8 @@
     Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Literals;
   if (Args.hasArg(OPT_objcmt_migrate_subscripting))
     Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Subscripting;
+  if (Args.hasArg(OPT_objcmt_migrate_property_dot_syntax))
+    Opts.ObjCMTAction |= FrontendOptions::ObjCMT_PropertyDotSyntax;
   if (Args.hasArg(OPT_objcmt_migrate_property))
     Opts.ObjCMTAction |= FrontendOptions::ObjCMT_Property;
   if (Args.hasArg(OPT_objcmt_migrate_readonly_property))
@@ -1121,7 +1142,7 @@
     case IK_PreprocessedC:
     case IK_ObjC:
     case IK_PreprocessedObjC:
-      LangStd = LangStandard::lang_gnu99;
+      LangStd = LangStandard::lang_gnu11;
       break;
     case IK_CXX:
     case IK_PreprocessedCXX:
@@ -1138,7 +1159,7 @@
   Opts.C11 = Std.isC11();
   Opts.CPlusPlus = Std.isCPlusPlus();
   Opts.CPlusPlus11 = Std.isCPlusPlus11();
-  Opts.CPlusPlus1y = Std.isCPlusPlus1y();
+  Opts.CPlusPlus14 = Std.isCPlusPlus14();
   Opts.CPlusPlus1z = Std.isCPlusPlus1z();
   Opts.Digraphs = Std.hasDigraphs();
   Opts.GNUMode = Std.isGNUMode();
@@ -1151,10 +1172,12 @@
   if (LangStd == LangStandard::lang_opencl)
     Opts.OpenCLVersion = 100;
   else if (LangStd == LangStandard::lang_opencl11)
-      Opts.OpenCLVersion = 110;
+    Opts.OpenCLVersion = 110;
   else if (LangStd == LangStandard::lang_opencl12)
     Opts.OpenCLVersion = 120;
-  
+  else if (LangStd == LangStandard::lang_opencl20)
+    Opts.OpenCLVersion = 200;
+
   // OpenCL has some additional defaults.
   if (Opts.OpenCL) {
     Opts.AltiVec = 0;
@@ -1185,8 +1208,8 @@
 
   Opts.DollarIdents = !Opts.AsmPreprocessor;
 
-  // C++1y onwards has sized global deallocation functions.
-  Opts.SizedDeallocation = Opts.CPlusPlus1y;
+  // C++14 onwards has sized global deallocation functions.
+  Opts.SizedDeallocation = Opts.CPlusPlus14;
 }
 
 /// Attempt to parse a visibility value out of the given argument.
@@ -1208,7 +1231,7 @@
 }
 
 static unsigned parseMSCVersion(ArgList &Args, DiagnosticsEngine &Diags) {
-  auto Arg = Args.getLastArg(OPT_fmsc_version);
+  auto Arg = Args.getLastArg(OPT_fms_compatibility_version);
   if (!Arg)
     return 0;
 
@@ -1225,25 +1248,8 @@
   // Unfortunately, due to the bit-width limitations, we cannot currently encode
   // the value for the patch level.
 
-  StringRef Value = Arg->getValue();
-
-  // parse the compatible old form of _MSC_VER or the newer _MSC_FULL_VER
-  if (Value.find('.') == StringRef::npos) {
-    unsigned Version = 0;
-    if (Value.getAsInteger(10, Version)) {
-      Diags.Report(diag::err_drv_invalid_value)
-        << Arg->getAsString(Args) << Value;
-      return 0;
-    }
-    if (Version < 100)
-      Version = Version * 100;    // major -> major.minor
-    if (Version < 100000)
-      Version = Version * 100000; // major.minor -> major.minor.build
-    return Version;
-  }
-
-  // parse the dot-delimited component version
   unsigned VC[4] = {0};
+  StringRef Value = Arg->getValue();
   SmallVector<StringRef, 4> Components;
 
   Value.split(Components, ".", llvm::array_lengthof(VC));
@@ -1319,6 +1325,7 @@
     .Case("CL", LangStandard::lang_opencl)
     .Case("CL1.1", LangStandard::lang_opencl11)
     .Case("CL1.2", LangStandard::lang_opencl12)
+    .Case("CL2.0", LangStandard::lang_opencl20)
     .Default(LangStandard::lang_unspecified);
     
     if (OpenCLLangStd == LangStandard::lang_unspecified) {
@@ -1430,7 +1437,7 @@
   Opts.MSVCCompat = Args.hasArg(OPT_fms_compatibility);
   Opts.MicrosoftExt = Opts.MSVCCompat || Args.hasArg(OPT_fms_extensions);
   Opts.AsmBlocks = Args.hasArg(OPT_fasm_blocks) || Opts.MicrosoftExt;
-  Opts.MSCVersion = parseMSCVersion(Args, Diags);
+  Opts.MSCompatibilityVersion = parseMSCVersion(Args, Diags);
   Opts.VtorDispMode = getLastArgIntValue(Args, OPT_vtordisp_mode_EQ, 1, Diags);
   Opts.Borland = Args.hasArg(OPT_fborland_extensions);
   Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
@@ -1492,6 +1499,7 @@
     Args.hasArg(OPT_fencode_extended_block_signature);
   Opts.EmitAllDecls = Args.hasArg(OPT_femit_all_decls);
   Opts.PackStruct = getLastArgIntValue(Args, OPT_fpack_struct_EQ, 0, Diags);
+  Opts.MaxTypeAlign = getLastArgIntValue(Args, OPT_fmax_type_align_EQ, 0, Diags);
   Opts.PICLevel = getLastArgIntValue(Args, OPT_pic_level, 0, Diags);
   Opts.PIELevel = getLastArgIntValue(Args, OPT_pie_level, 0, Diags);
   Opts.Static = Args.hasArg(OPT_static_define);
@@ -1512,6 +1520,16 @@
   Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
   Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
   Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name);
+  Opts.ImplementationOfModule =
+      Args.getLastArgValue(OPT_fmodule_implementation_of);
+  Opts.NativeHalfType = Opts.NativeHalfType;
+  Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);
+
+  if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() &&
+      Opts.CurrentModule != Opts.ImplementationOfModule) {
+    Diags.Report(diag::err_conflicting_module_names)
+        << Opts.CurrentModule << Opts.ImplementationOfModule;
+  }
 
   if (Arg *A = Args.getLastArg(OPT_faddress_space_map_mangling_EQ)) {
     switch (llvm::StringSwitch<unsigned>(A->getValue())
@@ -1596,34 +1614,21 @@
 
   // Parse -fsanitize= arguments.
   std::vector<std::string> Sanitizers = Args.getAllArgValues(OPT_fsanitize_EQ);
-  for (unsigned I = 0, N = Sanitizers.size(); I != N; ++I) {
-    // Since the Opts.Sanitize* values are bitfields, it's a little tricky to
-    // efficiently map string values to them. Perform the mapping indirectly:
-    // convert strings to enumerated values, then switch over the enum to set
-    // the right bitfield value.
-    enum Sanitizer {
-#define SANITIZER(NAME, ID) \
-      ID,
+  for (const auto &Sanitizer : Sanitizers) {
+    SanitizerKind K = llvm::StringSwitch<SanitizerKind>(Sanitizer)
+#define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
 #include "clang/Basic/Sanitizers.def"
-      Unknown
-    };
-    switch (llvm::StringSwitch<unsigned>(Sanitizers[I])
-#define SANITIZER(NAME, ID) \
-              .Case(NAME, ID)
-#include "clang/Basic/Sanitizers.def"
-              .Default(Unknown)) {
-#define SANITIZER(NAME, ID) \
-    case ID: \
-      Opts.Sanitize.ID = true; \
-      break;
-#include "clang/Basic/Sanitizers.def"
-
-    case Unknown:
+        .Default(SanitizerKind::Unknown);
+    if (K == SanitizerKind::Unknown)
       Diags.Report(diag::err_drv_invalid_value)
-        << "-fsanitize=" << Sanitizers[I];
-      break;
-    }
+        << "-fsanitize=" << Sanitizer;
+    else
+      Opts.Sanitize.set(K, true);
   }
+  // -fsanitize-address-field-padding=N has to be a LangOpt, parse it here.
+  Opts.SanitizeAddressFieldPadding =
+      getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
+  Opts.SanitizerBlacklistFile = Args.getLastArgValue(OPT_fsanitize_blacklist);
 }
 
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
@@ -2041,7 +2046,7 @@
     }
 
     IntrusiveRefCntPtr<vfs::FileSystem> FS =
-        vfs::getVFSFromYAML(Buffer->release(), /*DiagHandler*/ nullptr);
+        vfs::getVFSFromYAML(std::move(Buffer.get()), /*DiagHandler*/ nullptr);
     if (!FS.get()) {
       Diags.Report(diag::err_invalid_vfs_overlay) << File;
       return IntrusiveRefCntPtr<vfs::FileSystem>();
diff --git a/lib/Frontend/CreateInvocationFromCommandLine.cpp b/lib/Frontend/CreateInvocationFromCommandLine.cpp
index f2f36e4..4a8a8a0 100644
--- a/lib/Frontend/CreateInvocationFromCommandLine.cpp
+++ b/lib/Frontend/CreateInvocationFromCommandLine.cpp
@@ -71,13 +71,13 @@
     return nullptr;
   }
 
-  const driver::Command *Cmd = cast<driver::Command>(*Jobs.begin());
-  if (StringRef(Cmd->getCreator().getName()) != "clang") {
+  const driver::Command &Cmd = cast<driver::Command>(*Jobs.begin());
+  if (StringRef(Cmd.getCreator().getName()) != "clang") {
     Diags->Report(diag::err_fe_expected_clang_command);
     return nullptr;
   }
 
-  const ArgStringList &CCArgs = Cmd->getArguments();
+  const ArgStringList &CCArgs = Cmd.getArguments();
   std::unique_ptr<CompilerInvocation> CI(new CompilerInvocation());
   if (!CompilerInvocation::CreateFromArgs(*CI,
                                      const_cast<const char **>(CCArgs.data()),
diff --git a/lib/Frontend/DependencyFile.cpp b/lib/Frontend/DependencyFile.cpp
index 0b9c0d4..6ea8f51 100644
--- a/lib/Frontend/DependencyFile.cpp
+++ b/lib/Frontend/DependencyFile.cpp
@@ -22,6 +22,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Serialization/ASTReader.h"
 #include "llvm/ADT/StringSet.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
@@ -108,23 +109,32 @@
 void DependencyCollector::maybeAddDependency(StringRef Filename, bool FromModule,
                                             bool IsSystem, bool IsModuleFile,
                                             bool IsMissing) {
-  if (Seen.insert(Filename) &&
+  if (Seen.insert(Filename).second &&
       sawDependency(Filename, FromModule, IsSystem, IsModuleFile, IsMissing))
     Dependencies.push_back(Filename);
 }
 
+static bool isSpecialFilename(StringRef Filename) {
+  return llvm::StringSwitch<bool>(Filename)
+      .Case("<built-in>", true)
+      .Case("<stdin>", true)
+      .Default(false);
+}
+
 bool DependencyCollector::sawDependency(StringRef Filename, bool FromModule,
                                        bool IsSystem, bool IsModuleFile,
                                        bool IsMissing) {
-  return Filename != "<built-in>" && (needSystemDependencies() || !IsSystem);
+  return !isSpecialFilename(Filename) &&
+         (needSystemDependencies() || !IsSystem);
 }
 
 DependencyCollector::~DependencyCollector() { }
 void DependencyCollector::attachToPreprocessor(Preprocessor &PP) {
-  PP.addPPCallbacks(new DepCollectorPPCallbacks(*this, PP.getSourceManager()));
+  PP.addPPCallbacks(
+      llvm::make_unique<DepCollectorPPCallbacks>(*this, PP.getSourceManager()));
 }
 void DependencyCollector::attachToASTReader(ASTReader &R) {
-  R.addListener(new DepCollectorASTListener(*this));
+  R.addListener(llvm::make_unique<DepCollectorASTListener>(*this));
 }
 
 namespace {
@@ -203,21 +213,21 @@
     PP.SetSuppressIncludeNotFoundError(true);
 
   DFGImpl *Callback = new DFGImpl(&PP, Opts);
-  PP.addPPCallbacks(Callback); // PP owns the Callback
+  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callback));
   return new DependencyFileGenerator(Callback);
 }
 
 void DependencyFileGenerator::AttachToASTReader(ASTReader &R) {
   DFGImpl *I = reinterpret_cast<DFGImpl *>(Impl);
   assert(I && "missing implementation");
-  R.addListener(new DFGASTReaderListener(*I));
+  R.addListener(llvm::make_unique<DFGASTReaderListener>(*I));
 }
 
 /// FileMatchesDepCriteria - Determine whether the given Filename should be
 /// considered as a dependency.
 bool DFGImpl::FileMatchesDepCriteria(const char *Filename,
                                      SrcMgr::CharacteristicKind FileType) {
-  if (strcmp("<built-in>", Filename) == 0)
+  if (isSpecialFilename(Filename))
     return false;
 
   if (IncludeSystemHeaders)
@@ -275,7 +285,7 @@
 }
 
 void DFGImpl::AddFilename(StringRef Filename) {
-  if (FilesSet.insert(Filename))
+  if (FilesSet.insert(Filename).second)
     Files.push_back(Filename);
 }
 
@@ -297,11 +307,11 @@
     return;
   }
 
-  std::string Err;
-  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text);
-  if (!Err.empty()) {
-    PP->getDiagnostics().Report(diag::err_fe_error_opening)
-      << OutputFile << Err;
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text);
+  if (EC) {
+    PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile
+                                                            << EC.message();
     return;
   }
 
diff --git a/lib/Frontend/DependencyGraph.cpp b/lib/Frontend/DependencyGraph.cpp
index 051b7f9..67a977e 100644
--- a/lib/Frontend/DependencyGraph.cpp
+++ b/lib/Frontend/DependencyGraph.cpp
@@ -61,7 +61,8 @@
 
 void clang::AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
                                      StringRef SysRoot) {
-  PP.addPPCallbacks(new DependencyGraphCallback(&PP, OutputFile, SysRoot));
+  PP.addPPCallbacks(llvm::make_unique<DependencyGraphCallback>(&PP, OutputFile,
+                                                               SysRoot));
 }
 
 void DependencyGraphCallback::InclusionDirective(SourceLocation HashLoc,
@@ -96,11 +97,11 @@
 }
 
 void DependencyGraphCallback::OutputGraphFile() {
-  std::string Err;
-  llvm::raw_fd_ostream OS(OutputFile.c_str(), Err, llvm::sys::fs::F_Text);
-  if (!Err.empty()) {
-    PP->getDiagnostics().Report(diag::err_fe_error_opening)
-      << OutputFile << Err;
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_Text);
+  if (EC) {
+    PP->getDiagnostics().Report(diag::err_fe_error_opening) << OutputFile
+                                                            << EC.message();
     return;
   }
 
diff --git a/lib/Frontend/DiagnosticRenderer.cpp b/lib/Frontend/DiagnosticRenderer.cpp
index cff32b8..c63e98d 100644
--- a/lib/Frontend/DiagnosticRenderer.cpp
+++ b/lib/Frontend/DiagnosticRenderer.cpp
@@ -193,7 +193,7 @@
 void DiagnosticRenderer::emitBasicNote(StringRef Message) {
   emitDiagnosticMessage(
       SourceLocation(), PresumedLoc(), DiagnosticsEngine::Note, Message,
-      ArrayRef<CharSourceRange>(), nullptr, DiagOrStoredDiag());
+      None, nullptr, DiagOrStoredDiag());
 }
 
 /// \brief Prints an include stack when appropriate for a particular
@@ -509,6 +509,6 @@
     Message << "while building module '" << ModuleName << "' imported from "
             << PLoc.getFilename() << ':' << PLoc.getLine() << ":";
   else
-    Message << "while building module '" << ModuleName << ":";
+    Message << "while building module '" << ModuleName << "':";
   emitNote(Loc, Message.str(), &SM);
 }
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index c274ba7..c81c81a 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -32,6 +32,8 @@
 #include <system_error>
 using namespace clang;
 
+template class llvm::Registry<clang::PluginASTAction>;
+
 namespace {
 
 class DelegatingDeserializationListener : public ASTDeserializationListener {
@@ -127,14 +129,15 @@
 FrontendAction::~FrontendAction() {}
 
 void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
-                                     ASTUnit *AST) {
+                                     std::unique_ptr<ASTUnit> AST) {
   this->CurrentInput = CurrentInput;
-  CurrentASTUnit.reset(AST);
+  CurrentASTUnit = std::move(AST);
 }
 
-ASTConsumer* FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
-                                                      StringRef InFile) {
-  ASTConsumer* Consumer = CreateASTConsumer(CI, InFile);
+std::unique_ptr<ASTConsumer>
+FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) {
+  std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
   if (!Consumer)
     return nullptr;
 
@@ -143,7 +146,8 @@
 
   // Make sure the non-plugin consumer is first, so that plugins can't
   // modifiy the AST.
-  std::vector<ASTConsumer*> Consumers(1, Consumer);
+  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+  Consumers.push_back(std::move(Consumer));
 
   for (size_t i = 0, e = CI.getFrontendOpts().AddPluginActions.size();
        i != e; ++i) { 
@@ -153,16 +157,15 @@
         it = FrontendPluginRegistry::begin(),
         ie = FrontendPluginRegistry::end();
         it != ie; ++it) {
-      if (it->getName() == CI.getFrontendOpts().AddPluginActions[i]) {
-        std::unique_ptr<PluginASTAction> P(it->instantiate());
-        FrontendAction* c = P.get();
-        if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i]))
-          Consumers.push_back(c->CreateASTConsumer(CI, InFile));
-      }
+      if (it->getName() != CI.getFrontendOpts().AddPluginActions[i])
+        continue;
+      std::unique_ptr<PluginASTAction> P = it->instantiate();
+      if (P->ParseArgs(CI, CI.getFrontendOpts().AddPluginArgs[i]))
+        Consumers.push_back(P->CreateASTConsumer(CI, InFile));
     }
   }
 
-  return new MultiplexConsumer(Consumers);
+  return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
 bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
@@ -187,13 +190,12 @@
 
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
 
-    ASTUnit *AST = ASTUnit::LoadFromASTFile(InputFile, Diags,
-                                            CI.getFileSystemOpts());
+    std::unique_ptr<ASTUnit> AST =
+        ASTUnit::LoadFromASTFile(InputFile, Diags, CI.getFileSystemOpts());
+
     if (!AST)
       goto failure;
 
-    setCurrentInput(Input, AST);
-
     // Inform the diagnostic client we are processing a source file.
     CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
     HasBegunSourceFile = true;
@@ -205,6 +207,8 @@
     CI.setPreprocessor(&AST->getPreprocessor());
     CI.setASTContext(&AST->getASTContext());
 
+    setCurrentInput(Input, std::move(AST));
+
     // Initialize the action.
     if (!BeginSourceFileAction(CI, InputFile))
       goto failure;
@@ -283,8 +287,10 @@
     }
   }
 
-  // Set up the preprocessor.
-  CI.createPreprocessor(getTranslationUnitKind());
+  // Set up the preprocessor if needed. When parsing model files the
+  // preprocessor of the original source is reused.
+  if (!isModelParsingAction())
+    CI.createPreprocessor(getTranslationUnitKind());
 
   // Inform the diagnostic client we are processing a source file.
   CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
@@ -303,15 +309,19 @@
   // Create the AST context and consumer unless this is a preprocessor only
   // action.
   if (!usesPreprocessorOnly()) {
-    CI.createASTContext();
+    // Parsing a model file should reuse the existing ASTContext.
+    if (!isModelParsingAction())
+      CI.createASTContext();
 
-    std::unique_ptr<ASTConsumer> Consumer(
-        CreateWrappedASTConsumer(CI, InputFile));
+    std::unique_ptr<ASTConsumer> Consumer =
+        CreateWrappedASTConsumer(CI, InputFile);
     if (!Consumer)
       goto failure;
 
-    CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
-    
+    // FIXME: should not overwrite ASTMutationListener when parsing model files?
+    if (!isModelParsingAction())
+      CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
+
     if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
       // Convert headers to PCH and chain them.
       IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
@@ -347,7 +357,7 @@
         goto failure;
     }
 
-    CI.setASTConsumer(Consumer.release());
+    CI.setASTConsumer(std::move(Consumer));
     if (!CI.hasASTConsumer())
       goto failure;
   }
@@ -373,6 +383,11 @@
            "doesn't support modules");
   }
 
+  // If we were asked to load any module files, do so now.
+  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
+    if (!CI.loadModuleFile(ModuleFile))
+      goto failure;
+
   // If there is a layout overrides file, attach an external AST source that
   // provides the layouts from that file.
   if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() && 
@@ -430,6 +445,10 @@
   // Inform the diagnostic client we are done with this source file.
   CI.getDiagnosticClient().EndSourceFile();
 
+  // Inform the preprocessor we are done.
+  if (CI.hasPreprocessor())
+    CI.getPreprocessor().EndSourceFile();
+
   // Finalize the action.
   EndSourceFileAction();
 
@@ -442,7 +461,7 @@
       CI.resetAndLeakSema();
       CI.resetAndLeakASTContext();
     }
-    BuryPointer(CI.takeASTConsumer());
+    BuryPointer(CI.takeASTConsumer().get());
   } else {
     if (!isCurrentFileAST()) {
       CI.setSema(nullptr);
@@ -451,10 +470,6 @@
     CI.setASTConsumer(nullptr);
   }
 
-  // Inform the preprocessor we are done.
-  if (CI.hasPreprocessor())
-    CI.getPreprocessor().EndSourceFile();
-
   if (CI.getFrontendOpts().ShowStats) {
     llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFile() << "':\n";
     CI.getPreprocessor().PrintStats();
@@ -514,14 +529,15 @@
 
 void PluginASTAction::anchor() { }
 
-ASTConsumer *
+std::unique_ptr<ASTConsumer>
 PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
                                               StringRef InFile) {
   llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
 }
 
-ASTConsumer *WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
-                                                      StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
+                                         StringRef InFile) {
   return WrappedAction->CreateASTConsumer(CI, InFile);
 }
 bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index ef6bfec..6a2ac60 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -33,9 +33,9 @@
 // Custom Actions
 //===----------------------------------------------------------------------===//
 
-ASTConsumer *InitOnlyAction::CreateASTConsumer(CompilerInstance &CI,
-                                               StringRef InFile) {
-  return new ASTConsumer();
+std::unique_ptr<ASTConsumer>
+InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  return llvm::make_unique<ASTConsumer>();
 }
 
 void InitOnlyAction::ExecuteAction() {
@@ -45,36 +45,38 @@
 // AST Consumer Actions
 //===----------------------------------------------------------------------===//
 
-ASTConsumer *ASTPrintAction::CreateASTConsumer(CompilerInstance &CI,
-                                               StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
     return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter);
   return nullptr;
 }
 
-ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI,
-                                              StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter,
+                         CI.getFrontendOpts().ASTDumpDecls,
                          CI.getFrontendOpts().ASTDumpLookups);
 }
 
-ASTConsumer *ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI,
-                                                  StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   return CreateASTDeclNodeLister();
 }
 
-ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI,
-                                              StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   return CreateASTViewer();
 }
 
-ASTConsumer *DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
-                                                       StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
+                                          StringRef InFile) {
   return CreateDeclContextPrinter();
 }
 
-ASTConsumer *GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI,
-                                                  StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
   raw_ostream *OS = nullptr;
@@ -83,8 +85,8 @@
 
   if (!CI.getFrontendOpts().RelocatablePCH)
     Sysroot.clear();
-  return new PCHGenerator(CI.getPreprocessor(), OutputFile, nullptr, Sysroot,
-                          OS);
+  return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile,
+                                         nullptr, Sysroot, OS);
 }
 
 bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
@@ -111,16 +113,17 @@
   return false;
 }
 
-ASTConsumer *GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
-                                                     StringRef InFile) {
+std::unique_ptr<ASTConsumer>
+GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
+                                        StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
   raw_ostream *OS = nullptr;
   if (ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile, OS))
     return nullptr;
 
-  return new PCHGenerator(CI.getPreprocessor(), OutputFile, Module, 
-                          Sysroot, OS);
+  return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile,
+                                         Module, Sysroot, OS);
 }
 
 static SmallVectorImpl<char> &
@@ -301,10 +304,12 @@
     return false;
   }
 
-  if (!ModuleMapForUniquing)
+  if (ModuleMapForUniquing && ModuleMapForUniquing != ModuleMap) {
+    Module->IsInferred = true;
+    HS.getModuleMap().setInferredModuleAllowedBy(Module, ModuleMapForUniquing);
+  } else {
     ModuleMapForUniquing = ModuleMap;
-  Module->ModuleMap = ModuleMapForUniquing;
-  assert(Module->ModuleMap && "missing module map file");
+  }
 
   FileManager &FileMgr = CI.getFileManager();
 
@@ -326,11 +331,11 @@
     return false;
   }
 
-  llvm::MemoryBuffer *InputBuffer =
+  std::unique_ptr<llvm::MemoryBuffer> InputBuffer =
       llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
                                            Module::getModuleInputBufferName());
   // Ownership of InputBuffer will be transferred to the SourceManager.
-  setCurrentInput(FrontendInputFile(InputBuffer, getCurrentFileKind(),
+  setCurrentInput(FrontendInputFile(InputBuffer.release(), getCurrentFileKind(),
                                     Module->IsSystem));
   return true;
 }
@@ -363,19 +368,20 @@
   return false;
 }
 
-ASTConsumer *SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI,
-                                                 StringRef InFile) {
-  return new ASTConsumer();
+std::unique_ptr<ASTConsumer>
+SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  return llvm::make_unique<ASTConsumer>();
 }
 
-ASTConsumer *DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
-                                                     StringRef InFile) {
-  return new ASTConsumer();
+std::unique_ptr<ASTConsumer>
+DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
+                                        StringRef InFile) {
+  return llvm::make_unique<ASTConsumer>();
 }
 
-ASTConsumer *VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI,
-                                                StringRef InFile) {
-  return new ASTConsumer();
+std::unique_ptr<ASTConsumer>
+VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  return llvm::make_unique<ASTConsumer>();
 }
 
 void VerifyPCHAction::ExecuteAction() {
@@ -425,8 +431,8 @@
       Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
     }
 
-    bool ReadLanguageOptions(const LangOptions &LangOpts,
-                             bool Complain) override {
+    bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
+                             bool AllowCompatibleDifferences) override {
       Out.indent(2) << "Language options:\n";
 #define LANGOPT(Name, Bits, Default, Description) \
       DUMP_BOOLEAN(LangOpts.Name, Description);
@@ -470,10 +476,11 @@
       Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
 #include "clang/Basic/DiagnosticOptions.def"
 
-      Out.indent(4) << "Warning options:\n";
-      for (const std::string &Warning : DiagOpts->Warnings) {
+      Out.indent(4) << "Diagnostic flags:\n";
+      for (const std::string &Warning : DiagOpts->Warnings)
         Out.indent(6) << "-W" << Warning << "\n";
-      }
+      for (const std::string &Remark : DiagOpts->Remarks)
+        Out.indent(6) << "-R" << Remark << "\n";
 
       return false;
     }
@@ -527,9 +534,9 @@
   std::unique_ptr<llvm::raw_fd_ostream> OutFile;
   StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile;
   if (!OutputFileName.empty() && OutputFileName != "-") {
-    std::string ErrorInfo;
-    OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str().c_str(),
-                                           ErrorInfo, llvm::sys::fs::F_Text));
+    std::error_code EC;
+    OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC,
+                                           llvm::sys::fs::F_Text));
   }
   llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
 
@@ -674,13 +681,12 @@
     // We can't do anything with these.
     return;
   }
-  
+
   CompilerInstance &CI = getCompilerInstance();
-  llvm::MemoryBuffer *Buffer
-      = CI.getFileManager().getBufferForFile(getCurrentFile());
+  auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
   if (Buffer) {
-    unsigned Preamble = Lexer::ComputePreamble(Buffer, CI.getLangOpts()).first;
-    llvm::outs().write(Buffer->getBufferStart(), Preamble);
-    delete Buffer;
+    unsigned Preamble =
+        Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).first;
+    llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
   }
 }
diff --git a/lib/Frontend/HeaderIncludeGen.cpp b/lib/Frontend/HeaderIncludeGen.cpp
index 8b2435b..2701194 100644
--- a/lib/Frontend/HeaderIncludeGen.cpp
+++ b/lib/Frontend/HeaderIncludeGen.cpp
@@ -54,13 +54,12 @@
 
   // Open the output file, if used.
   if (!OutputPath.empty()) {
-    std::string Error;
+    std::error_code EC;
     llvm::raw_fd_ostream *OS = new llvm::raw_fd_ostream(
-        OutputPath.str().c_str(), Error,
-        llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
-    if (!Error.empty()) {
-      PP.getDiagnostics().Report(
-        clang::diag::warn_fe_cc_print_header_failure) << Error;
+        OutputPath.str(), EC, llvm::sys::fs::F_Append | llvm::sys::fs::F_Text);
+    if (EC) {
+      PP.getDiagnostics().Report(clang::diag::warn_fe_cc_print_header_failure)
+          << EC.message();
       delete OS;
     } else {
       OS->SetUnbuffered();
@@ -70,9 +69,12 @@
     }
   }
 
-  PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders,
-                                               OutputFile, OwnsOutputFile,
-                                               ShowDepth, MSStyle));
+  PP.addPPCallbacks(llvm::make_unique<HeaderIncludesCallback>(&PP,
+                                                              ShowAllHeaders,
+                                                              OutputFile,
+                                                              OwnsOutputFile,
+                                                              ShowDepth,
+                                                              MSStyle));
 }
 
 void HeaderIncludesCallback::FileChanged(SourceLocation Loc,
@@ -131,5 +133,6 @@
     Msg += '\n';
 
     OutputFile->write(Msg.data(), Msg.size());
+    OutputFile->flush();
   }
 }
diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index d2edc94..5e89c8c 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -380,7 +380,6 @@
       break;
 
     case llvm::Triple::aarch64:
-    case llvm::Triple::arm64:
       AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.2.1",
                                   "arm64-apple-darwin10", "", "", triple);
       break;
@@ -391,7 +390,7 @@
   switch (os) {
   case llvm::Triple::Linux:
     llvm_unreachable("Include management is handled in the driver.");
-
+    break;
   case llvm::Triple::Win32:
     switch (triple.getEnvironment()) {
     default: llvm_unreachable("Include management is handled in the driver.");
@@ -445,11 +444,6 @@
   case llvm::Triple::Solaris:
     AddGnuCPlusPlusIncludePaths("/usr/gcc/4.5/include/c++/4.5.2/",
                                 "i386-pc-solaris2.11", "", "", triple);
-    // Solaris - Fall though..
-  case llvm::Triple::AuroraUX:
-    // AuroraUX
-    AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4",
-                                "i386-pc-solaris2.11", "", "", triple);
     break;
   default:
     break;
@@ -535,16 +529,16 @@
 
     if (CurEntry.isNormalDir()) {
       // If this isn't the first time we've seen this dir, remove it.
-      if (SeenDirs.insert(CurEntry.getDir()))
+      if (SeenDirs.insert(CurEntry.getDir()).second)
         continue;
     } else if (CurEntry.isFramework()) {
       // If this isn't the first time we've seen this framework dir, remove it.
-      if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()))
+      if (SeenFrameworkDirs.insert(CurEntry.getFrameworkDir()).second)
         continue;
     } else {
       assert(CurEntry.isHeaderMap() && "Not a headermap or normal dir?");
       // If this isn't the first time we've seen this headermap, remove it.
-      if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()))
+      if (SeenHeaderMaps.insert(CurEntry.getHeaderMap()).second)
         continue;
     }
 
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index f03348d..f671a2f 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -65,17 +65,14 @@
 
 /// AddImplicitInclude - Add an implicit \#include of the specified file to the
 /// predefines buffer.
-static void AddImplicitInclude(MacroBuilder &Builder, StringRef File,
-                               FileManager &FileMgr) {
-  Builder.append(Twine("#include \"") +
-                 HeaderSearch::NormalizeDashIncludePath(File, FileMgr) + "\"");
+/// As these includes are generated by -include arguments the header search
+/// logic is going to search relatively to the current working directory.
+static void AddImplicitInclude(MacroBuilder &Builder, StringRef File) {
+  Builder.append(Twine("#include \"") + File + "\"");
 }
 
-static void AddImplicitIncludeMacros(MacroBuilder &Builder,
-                                     StringRef File,
-                                     FileManager &FileMgr) {
-  Builder.append(Twine("#__include_macros \"") +
-                 HeaderSearch::NormalizeDashIncludePath(File, FileMgr) + "\"");
+static void AddImplicitIncludeMacros(MacroBuilder &Builder, StringRef File) {
+  Builder.append(Twine("#__include_macros \"") + File + "\"");
   // Marker token to stop the __include_macros fetch loop.
   Builder.append("##"); // ##?
 }
@@ -94,7 +91,7 @@
     return;
   }
 
-  AddImplicitInclude(Builder, OriginalFile, PP.getFileManager());
+  AddImplicitInclude(Builder, OriginalFile);
 }
 
 /// \brief Add an implicit \#include using the original file used to generate
@@ -107,7 +104,7 @@
   if (OriginalFile.empty())
     return;
 
-  AddImplicitInclude(Builder, OriginalFile, PP.getFileManager());
+  AddImplicitInclude(Builder, OriginalFile);
 }
 
 /// PickFP - This is used to pick a value based on the FP semantics of the
@@ -196,6 +193,16 @@
                  TI.isTypeSigned(Ty), Builder);
 }
 
+static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty,
+                      const TargetInfo &TI, MacroBuilder &Builder) {
+  bool IsSigned = TI.isTypeSigned(Ty);
+  StringRef FmtModifier = TI.getTypeFormatModifier(Ty);
+  for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) {
+    Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__",
+                        Twine("\"") + FmtModifier + Twine(*Fmt) + "\"");
+  }
+}
+
 static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty,
                        MacroBuilder &Builder) {
   Builder.defineMacro(MacroName, TargetInfo::getTypeName(Ty));
@@ -221,16 +228,15 @@
   // Use the target specified int64 type, when appropriate, so that [u]int64_t
   // ends up being defined in terms of the correct type.
   if (TypeWidth == 64)
-    Ty = IsSigned ? TI.getInt64Type() : TI.getIntTypeByWidth(64, false);
+    Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();
 
   const char *Prefix = IsSigned ? "__INT" : "__UINT";
 
   DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
+  DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
 
-  StringRef ConstSuffix(TargetInfo::getTypeConstantSuffix(Ty));
-  if (!ConstSuffix.empty())
-    Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
-
+  StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
+  Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
 }
 
 static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
@@ -242,7 +248,7 @@
   // Use the target specified int64 type, when appropriate, so that [u]int64_t
   // ends up being defined in terms of the correct type.
   if (TypeWidth == 64)
-    Ty = IsSigned ? TI.getInt64Type() : TI.getIntTypeByWidth(64, false);
+    Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();
 
   const char *Prefix = IsSigned ? "__INT" : "__UINT";
   DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
@@ -258,6 +264,7 @@
   const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST";
   DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
   DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+  DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
 }
 
 static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
@@ -271,6 +278,8 @@
   const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST";
   DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
   DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+
+  DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
 }
 
 
@@ -366,7 +375,7 @@
     // C++1y [cpp.predefined]p1:
     //   The name __cplusplus is defined to the value 201402L when compiling a
     //   C++ translation unit.
-    else if (LangOpts.CPlusPlus1y)
+    else if (LangOpts.CPlusPlus14)
       Builder.defineMacro("__cplusplus", "201402L");
     // C++11 [cpp.predefined]p1:
     //   The name __cplusplus is defined to the value 201103L when compiling a
@@ -400,6 +409,12 @@
 /// ISO/IEC JTC1/SC22/WG21 (C++) SD-6: "SG10 Feature Test Recommendations".
 static void InitializeCPlusPlusFeatureTestMacros(const LangOptions &LangOpts,
                                                  MacroBuilder &Builder) {
+  // C++98 features.
+  if (LangOpts.RTTI)
+    Builder.defineMacro("__cpp_rtti", "199711");
+  if (LangOpts.CXXExceptions)
+    Builder.defineMacro("__cpp_exceptions", "199711");
+
   // C++11 features.
   if (LangOpts.CPlusPlus11) {
     Builder.defineMacro("__cpp_unicode_characters", "200704");
@@ -408,17 +423,25 @@
     Builder.defineMacro("__cpp_user_defined_literals", "200809");
     Builder.defineMacro("__cpp_lambdas", "200907");
     Builder.defineMacro("__cpp_constexpr",
-                        LangOpts.CPlusPlus1y ? "201304" : "200704");
+                        LangOpts.CPlusPlus14 ? "201304" : "200704");
+    Builder.defineMacro("__cpp_range_based_for", "200907");
     Builder.defineMacro("__cpp_static_assert", "200410");
     Builder.defineMacro("__cpp_decltype", "200707");
     Builder.defineMacro("__cpp_attributes", "200809");
     Builder.defineMacro("__cpp_rvalue_references", "200610");
     Builder.defineMacro("__cpp_variadic_templates", "200704");
+    Builder.defineMacro("__cpp_initializer_lists", "200806");
+    Builder.defineMacro("__cpp_delegating_constructors", "200604");
+    Builder.defineMacro("__cpp_nsdmi", "200809");
+    Builder.defineMacro("__cpp_inheriting_constructors", "200802");
+    Builder.defineMacro("__cpp_ref_qualifiers", "200710");
+    Builder.defineMacro("__cpp_alias_templates", "200704");
   }
 
   // C++14 features.
-  if (LangOpts.CPlusPlus1y) {
+  if (LangOpts.CPlusPlus14) {
     Builder.defineMacro("__cpp_binary_literals", "201304");
+    Builder.defineMacro("__cpp_digit_separators", "201309");
     Builder.defineMacro("__cpp_init_captures", "201304");
     Builder.defineMacro("__cpp_generic_lambdas", "201304");
     Builder.defineMacro("__cpp_decltype_auto", "201304");
@@ -426,6 +449,8 @@
     Builder.defineMacro("__cpp_aggregate_nsdmi", "201304");
     Builder.defineMacro("__cpp_variable_templates", "201304");
   }
+  if (LangOpts.SizedDeallocation)
+    Builder.defineMacro("__cpp_sized_deallocation", "201309");
 }
 
 static void InitializePredefinedMacros(const TargetInfo &TI,
@@ -481,7 +506,7 @@
   if (!LangOpts.GNUMode && !LangOpts.MSVCCompat)
     Builder.defineMacro("__STRICT_ANSI__");
 
-  if (LangOpts.CPlusPlus11)
+  if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus11)
     Builder.defineMacro("__GXX_EXPERIMENTAL_CXX0X__");
 
   if (LangOpts.ObjC1) {
@@ -518,6 +543,8 @@
     Builder.defineMacro("IBOutletCollection(ClassName)",
                         "__attribute__((iboutletcollection(ClassName)))");
     Builder.defineMacro("IBAction", "void)__attribute__((ibaction)");
+    Builder.defineMacro("IBInspectable", "");
+    Builder.defineMacro("IB_DESIGNABLE", "");
   }
 
   if (LangOpts.CPlusPlus)
@@ -539,9 +566,9 @@
     Builder.defineMacro("__BLOCKS__");
   }
 
-  if (!LangOpts.MSVCCompat && LangOpts.CXXExceptions)
+  if (!LangOpts.MSVCCompat && LangOpts.Exceptions)
     Builder.defineMacro("__EXCEPTIONS");
-  if (LangOpts.RTTI)
+  if (!LangOpts.MSVCCompat && LangOpts.RTTI)
     Builder.defineMacro("__GXX_RTTI");
   if (LangOpts.SjLjExceptions)
     Builder.defineMacro("__USING_SJLJ_EXCEPTIONS__");
@@ -549,7 +576,7 @@
   if (LangOpts.Deprecated)
     Builder.defineMacro("__DEPRECATED");
 
-  if (LangOpts.CPlusPlus) {
+  if (!LangOpts.MSVCCompat && LangOpts.CPlusPlus) {
     Builder.defineMacro("__GNUG__", "4");
     Builder.defineMacro("__GXX_WEAK__");
     Builder.defineMacro("__private_extern__", "extern");
@@ -595,6 +622,12 @@
     Builder.defineMacro("__LP64__");
   }
 
+  if (TI.getPointerWidth(0) == 32 && TI.getLongWidth() == 32
+      && TI.getIntWidth() == 32) {
+    Builder.defineMacro("_ILP32");
+    Builder.defineMacro("__ILP32__");
+  }
+
   // Define type sizing macros based on the target properties.
   assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
   Builder.defineMacro("__CHAR_BIT__", "8");
@@ -608,12 +641,10 @@
   DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
   DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder);
 
-  if (!LangOpts.MSVCCompat) {
-    DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder);
-    DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder);
-    DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder);
-    DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder);
-  }
+  DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder);
+  DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder);
+  DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder);
+  DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder);
 
   DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder);
   DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder);
@@ -635,27 +666,36 @@
     DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder);
 
   DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
+  DefineFmt("__INTMAX", TI.getIntMaxType(), TI, Builder);
+  Builder.defineMacro("__INTMAX_C_SUFFIX__",
+                      TI.getTypeConstantSuffix(TI.getIntMaxType()));
   DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
+  DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
+  Builder.defineMacro("__UINTMAX_C_SUFFIX__",
+                      TI.getTypeConstantSuffix(TI.getUIntMaxType()));
   DefineTypeWidth("__INTMAX_WIDTH__",  TI.getIntMaxType(), TI, Builder);
   DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder);
+  DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder);
   DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder);
   DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
+  DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
   DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder);
   DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
+  DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
   DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder);
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
   DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
   DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder);
   DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder);
+  DefineTypeSize("__SIG_ATOMIC_MAX__", TI.getSigAtomicType(), TI, Builder);
   DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
   DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
 
-  if (!LangOpts.MSVCCompat) {
-    DefineTypeWidth("__UINTMAX_WIDTH__",  TI.getUIntMaxType(), TI, Builder);
-    DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
-    DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);
-  }
+  DefineTypeWidth("__UINTMAX_WIDTH__",  TI.getUIntMaxType(), TI, Builder);
+  DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
+  DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
+  DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);
 
   DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
   DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
@@ -675,8 +715,7 @@
     Builder.defineMacro("__WINT_UNSIGNED__");
 
   // Define exact-width integer types for stdint.h
-  Builder.defineMacro("__INT" + Twine(TI.getCharWidth()) + "_TYPE__",
-                      "char");
+  DefineExactWidthIntType(TargetInfo::SignedChar, TI, Builder);
 
   if (TI.getShortWidth() > TI.getCharWidth())
     DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder);
@@ -690,54 +729,52 @@
   if (TI.getLongLongWidth() > TI.getLongWidth())
     DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder);
 
-  if (!LangOpts.MSVCCompat) {
-    DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder);
-    DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
-    DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);
+  DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder);
+  DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
+  DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);
 
-    if (TI.getShortWidth() > TI.getCharWidth()) {
-      DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
-    }
-
-    if (TI.getIntWidth() > TI.getShortWidth()) {
-      DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
-    }
-
-    if (TI.getLongWidth() > TI.getIntWidth()) {
-      DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
-    }
-
-    if (TI.getLongLongWidth() > TI.getLongWidth()) {
-      DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
-      DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
-    }
-
-    DefineLeastWidthIntType(8, true, TI, Builder);
-    DefineLeastWidthIntType(8, false, TI, Builder);
-    DefineLeastWidthIntType(16, true, TI, Builder);
-    DefineLeastWidthIntType(16, false, TI, Builder);
-    DefineLeastWidthIntType(32, true, TI, Builder);
-    DefineLeastWidthIntType(32, false, TI, Builder);
-    DefineLeastWidthIntType(64, true, TI, Builder);
-    DefineLeastWidthIntType(64, false, TI, Builder);
-
-    DefineFastIntType(8, true, TI, Builder);
-    DefineFastIntType(8, false, TI, Builder);
-    DefineFastIntType(16, true, TI, Builder);
-    DefineFastIntType(16, false, TI, Builder);
-    DefineFastIntType(32, true, TI, Builder);
-    DefineFastIntType(32, false, TI, Builder);
-    DefineFastIntType(64, true, TI, Builder);
-    DefineFastIntType(64, false, TI, Builder);
+  if (TI.getShortWidth() > TI.getCharWidth()) {
+    DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
   }
 
+  if (TI.getIntWidth() > TI.getShortWidth()) {
+    DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
+  }
+
+  if (TI.getLongWidth() > TI.getIntWidth()) {
+    DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
+  }
+
+  if (TI.getLongLongWidth() > TI.getLongWidth()) {
+    DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
+    DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
+  }
+
+  DefineLeastWidthIntType(8, true, TI, Builder);
+  DefineLeastWidthIntType(8, false, TI, Builder);
+  DefineLeastWidthIntType(16, true, TI, Builder);
+  DefineLeastWidthIntType(16, false, TI, Builder);
+  DefineLeastWidthIntType(32, true, TI, Builder);
+  DefineLeastWidthIntType(32, false, TI, Builder);
+  DefineLeastWidthIntType(64, true, TI, Builder);
+  DefineLeastWidthIntType(64, false, TI, Builder);
+
+  DefineFastIntType(8, true, TI, Builder);
+  DefineFastIntType(8, false, TI, Builder);
+  DefineFastIntType(16, true, TI, Builder);
+  DefineFastIntType(16, false, TI, Builder);
+  DefineFastIntType(32, true, TI, Builder);
+  DefineFastIntType(32, false, TI, Builder);
+  DefineFastIntType(64, true, TI, Builder);
+  DefineFastIntType(64, false, TI, Builder);
+
   if (const char *Prefix = TI.getUserLabelPrefix())
     Builder.defineMacro("__USER_LABEL_PREFIX__", Prefix);
 
@@ -746,36 +783,38 @@
   else
     Builder.defineMacro("__FINITE_MATH_ONLY__", "0");
 
-  if (LangOpts.GNUInline)
-    Builder.defineMacro("__GNUC_GNU_INLINE__");
-  else
-    Builder.defineMacro("__GNUC_STDC_INLINE__");
+  if (!LangOpts.MSVCCompat) {
+    if (LangOpts.GNUInline)
+      Builder.defineMacro("__GNUC_GNU_INLINE__");
+    else
+      Builder.defineMacro("__GNUC_STDC_INLINE__");
 
-  // The value written by __atomic_test_and_set.
-  // FIXME: This is target-dependent.
-  Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1");
+    // The value written by __atomic_test_and_set.
+    // FIXME: This is target-dependent.
+    Builder.defineMacro("__GCC_ATOMIC_TEST_AND_SET_TRUEVAL", "1");
 
-  // Used by libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
-  unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth();
+    // Used by libstdc++ to implement ATOMIC_<foo>_LOCK_FREE.
+    unsigned InlineWidthBits = TI.getMaxAtomicInlineWidth();
 #define DEFINE_LOCK_FREE_MACRO(TYPE, Type) \
-  Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
-                      getLockFreeValue(TI.get##Type##Width(), \
-                                       TI.get##Type##Align(), \
-                                       InlineWidthBits));
-  DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
-  DEFINE_LOCK_FREE_MACRO(CHAR, Char);
-  DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
-  DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
-  DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
-  DEFINE_LOCK_FREE_MACRO(SHORT, Short);
-  DEFINE_LOCK_FREE_MACRO(INT, Int);
-  DEFINE_LOCK_FREE_MACRO(LONG, Long);
-  DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
-  Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE",
-                      getLockFreeValue(TI.getPointerWidth(0),
-                                       TI.getPointerAlign(0),
-                                       InlineWidthBits));
+    Builder.defineMacro("__GCC_ATOMIC_" #TYPE "_LOCK_FREE", \
+                        getLockFreeValue(TI.get##Type##Width(), \
+                                         TI.get##Type##Align(), \
+                                         InlineWidthBits));
+    DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
+    DEFINE_LOCK_FREE_MACRO(CHAR, Char);
+    DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
+    DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
+    DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
+    DEFINE_LOCK_FREE_MACRO(SHORT, Short);
+    DEFINE_LOCK_FREE_MACRO(INT, Int);
+    DEFINE_LOCK_FREE_MACRO(LONG, Long);
+    DEFINE_LOCK_FREE_MACRO(LLONG, LongLong);
+    Builder.defineMacro("__GCC_ATOMIC_POINTER_LOCK_FREE",
+                        getLockFreeValue(TI.getPointerWidth(0),
+                                         TI.getPointerAlign(0),
+                                         InlineWidthBits));
 #undef DEFINE_LOCK_FREE_MACRO
+  }
 
   if (LangOpts.NoInlineDefine)
     Builder.defineMacro("__NO_INLINE__");
@@ -895,8 +934,7 @@
   // If -imacros are specified, include them now.  These are processed before
   // any -include directives.
   for (unsigned i = 0, e = InitOpts.MacroIncludes.size(); i != e; ++i)
-    AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i],
-                             PP.getFileManager());
+    AddImplicitIncludeMacros(Builder, InitOpts.MacroIncludes[i]);
 
   // Process -include-pch/-include-pth directives.
   if (!InitOpts.ImplicitPCHInclude.empty())
@@ -907,7 +945,7 @@
   // Process -include directives.
   for (unsigned i = 0, e = InitOpts.Includes.size(); i != e; ++i) {
     const std::string &Path = InitOpts.Includes[i];
-    AddImplicitInclude(Builder, Path, PP.getFileManager());
+    AddImplicitInclude(Builder, Path);
   }
 
   // Exit the command line and go back to <built-in> (2 is LC_LEAVE).
diff --git a/lib/Frontend/LogDiagnosticPrinter.cpp b/lib/Frontend/LogDiagnosticPrinter.cpp
index 19539e0..c6a18e0 100644
--- a/lib/Frontend/LogDiagnosticPrinter.cpp
+++ b/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -18,17 +18,11 @@
 using namespace clang;
 using namespace markup;
 
-LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os,
-                                           DiagnosticOptions *diags,
-                                           bool _OwnsOutputStream)
-  : OS(os), LangOpts(nullptr), DiagOpts(diags),
-    OwnsOutputStream(_OwnsOutputStream) {
-}
-
-LogDiagnosticPrinter::~LogDiagnosticPrinter() {
-  if (OwnsOutputStream)
-    delete &OS;
-}
+LogDiagnosticPrinter::LogDiagnosticPrinter(
+    raw_ostream &os, DiagnosticOptions *diags,
+    std::unique_ptr<raw_ostream> StreamOwner)
+    : OS(os), StreamOwner(std::move(StreamOwner)), LangOpts(nullptr),
+      DiagOpts(diags) {}
 
 static StringRef getLevelName(DiagnosticsEngine::Level Level) {
   switch (Level) {
@@ -69,6 +63,14 @@
        << "      ";
     EmitString(OS, DE.Message) << '\n';
   }
+  OS << "      <key>ID</key>\n"
+     << "      ";
+  EmitInteger(OS, DE.DiagnosticID) << '\n';
+  if (!DE.WarningOption.empty()) {
+    OS << "      <key>WarningOption</key>\n"
+       << "      ";
+    EmitString(OS, DE.WarningOption) << '\n';
+  }
   OS << "    </dict>\n";
 }
 
@@ -128,6 +130,8 @@
   DE.DiagnosticID = Info.getID();
   DE.DiagnosticLevel = Level;
 
+  DE.WarningOption = DiagnosticIDs::getWarningOptionForDiag(DE.DiagnosticID);
+
   // Format the message.
   SmallString<100> MessageStr;
   Info.FormatDiagnostic(MessageStr);
diff --git a/lib/Frontend/Makefile b/lib/Frontend/Makefile
index 3c13ad6..8554b76 100644
--- a/lib/Frontend/Makefile
+++ b/lib/Frontend/Makefile
@@ -8,7 +8,7 @@
 ##===----------------------------------------------------------------------===##
 
 CLANG_LEVEL := ../..
+DIRS := Rewrite
 LIBRARYNAME := clangFrontend
 
 include $(CLANG_LEVEL)/Makefile
-
diff --git a/lib/Frontend/ModuleDependencyCollector.cpp b/lib/Frontend/ModuleDependencyCollector.cpp
index d30f921..882bf8e 100644
--- a/lib/Frontend/ModuleDependencyCollector.cpp
+++ b/lib/Frontend/ModuleDependencyCollector.cpp
@@ -38,7 +38,7 @@
 }
 
 void ModuleDependencyCollector::attachToASTReader(ASTReader &R) {
-  R.addListener(new ModuleDependencyListener(*this));
+  R.addListener(llvm::make_unique<ModuleDependencyListener>(*this));
 }
 
 void ModuleDependencyCollector::writeFileMap() {
@@ -48,9 +48,9 @@
   SmallString<256> Dest = getDest();
   llvm::sys::path::append(Dest, "vfs.yaml");
 
-  std::string ErrorInfo;
-  llvm::raw_fd_ostream OS(Dest.c_str(), ErrorInfo, llvm::sys::fs::F_Text);
-  if (!ErrorInfo.empty()) {
+  std::error_code EC;
+  llvm::raw_fd_ostream OS(Dest, EC, llvm::sys::fs::F_Text);
+  if (EC) {
     setHasErrors();
     return;
   }
diff --git a/lib/Frontend/MultiplexConsumer.cpp b/lib/Frontend/MultiplexConsumer.cpp
index 058cee8..0198828 100644
--- a/lib/Frontend/MultiplexConsumer.cpp
+++ b/lib/Frontend/MultiplexConsumer.cpp
@@ -107,6 +107,7 @@
                                     const ObjCPropertyDecl *OrigProp,
                                     const ObjCCategoryDecl *ClassExt) override;
   void DeclarationMarkedUsed(const Decl *D) override;
+  void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override;
 
 private:
   std::vector<ASTMutationListener*> Listeners;
@@ -180,96 +181,121 @@
   for (size_t i = 0, e = Listeners.size(); i != e; ++i)
     Listeners[i]->DeclarationMarkedUsed(D);
 }
+void MultiplexASTMutationListener::DeclarationMarkedOpenMPThreadPrivate(
+    const Decl *D) {
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
+    Listeners[i]->DeclarationMarkedOpenMPThreadPrivate(D);
+}
 
 }  // end namespace clang
 
-MultiplexConsumer::MultiplexConsumer(ArrayRef<ASTConsumer *> C)
-    : Consumers(C.begin(), C.end()), MutationListener(),
-      DeserializationListener() {
+MultiplexConsumer::MultiplexConsumer(
+    std::vector<std::unique_ptr<ASTConsumer>> C)
+    : Consumers(std::move(C)), MutationListener(), DeserializationListener() {
   // Collect the mutation listeners and deserialization listeners of all
   // children, and create a multiplex listener each if so.
   std::vector<ASTMutationListener*> mutationListeners;
   std::vector<ASTDeserializationListener*> serializationListeners;
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i) {
-    ASTMutationListener* mutationListener =
-        Consumers[i]->GetASTMutationListener();
-    if (mutationListener)
+  for (auto &Consumer : Consumers) {
+    if (auto *mutationListener = Consumer->GetASTMutationListener())
       mutationListeners.push_back(mutationListener);
-    ASTDeserializationListener* serializationListener =
-        Consumers[i]->GetASTDeserializationListener();
-    if (serializationListener)
+    if (auto *serializationListener = Consumer->GetASTDeserializationListener())
       serializationListeners.push_back(serializationListener);
   }
-  if (mutationListeners.size()) {
-    MutationListener.reset(new MultiplexASTMutationListener(mutationListeners));
+  if (!mutationListeners.empty()) {
+    MutationListener =
+        llvm::make_unique<MultiplexASTMutationListener>(mutationListeners);
   }
-  if (serializationListeners.size()) {
-    DeserializationListener.reset(
-        new MultiplexASTDeserializationListener(serializationListeners));
+  if (!serializationListeners.empty()) {
+    DeserializationListener =
+        llvm::make_unique<MultiplexASTDeserializationListener>(
+            serializationListeners);
   }
 }
 
-MultiplexConsumer::~MultiplexConsumer() {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    delete Consumers[i];
-}
+MultiplexConsumer::~MultiplexConsumer() {}
 
 void MultiplexConsumer::Initialize(ASTContext &Context) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->Initialize(Context);
+  for (auto &Consumer : Consumers)
+    Consumer->Initialize(Context);
 }
 
 bool MultiplexConsumer::HandleTopLevelDecl(DeclGroupRef D) {
   bool Continue = true;
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Continue = Continue && Consumers[i]->HandleTopLevelDecl(D);
+  for (auto &Consumer : Consumers)
+    Continue = Continue && Consumer->HandleTopLevelDecl(D);
   return Continue;
 }
 
 void MultiplexConsumer::HandleInlineMethodDefinition(CXXMethodDecl *D) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleInlineMethodDefinition(D);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleInlineMethodDefinition(D);
 }
 
-void  MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleCXXStaticMemberVarInstantiation(VD);
+void MultiplexConsumer::HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
+  for (auto &Consumer : Consumers)
+    Consumer->HandleCXXStaticMemberVarInstantiation(VD);
 }
 
 void MultiplexConsumer::HandleInterestingDecl(DeclGroupRef D) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleInterestingDecl(D);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleInterestingDecl(D);
 }
 
 void MultiplexConsumer::HandleTranslationUnit(ASTContext &Ctx) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleTranslationUnit(Ctx);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleTranslationUnit(Ctx);
 }
 
 void MultiplexConsumer::HandleTagDeclDefinition(TagDecl *D) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleTagDeclDefinition(D);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleTagDeclDefinition(D);
+}
+
+void MultiplexConsumer::HandleTagDeclRequiredDefinition(const TagDecl *D) {
+  for (auto &Consumer : Consumers)
+    Consumer->HandleTagDeclRequiredDefinition(D);
 }
 
 void MultiplexConsumer::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D){
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleCXXImplicitFunctionInstantiation(D);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleCXXImplicitFunctionInstantiation(D);
 }
 
 void MultiplexConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleTopLevelDeclInObjCContainer(D);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleTopLevelDeclInObjCContainer(D);
+}
+
+void MultiplexConsumer::HandleImplicitImportDecl(ImportDecl *D) {
+  for (auto &Consumer : Consumers)
+    Consumer->HandleImplicitImportDecl(D);
+}
+
+void MultiplexConsumer::HandleLinkerOptionPragma(llvm::StringRef Opts) {
+  for (auto &Consumer : Consumers)
+    Consumer->HandleLinkerOptionPragma(Opts);
+}
+
+void MultiplexConsumer::HandleDetectMismatch(llvm::StringRef Name, llvm::StringRef Value) {
+  for (auto &Consumer : Consumers)
+    Consumer->HandleDetectMismatch(Name, Value);
+}
+
+void MultiplexConsumer::HandleDependentLibrary(llvm::StringRef Lib) {
+  for (auto &Consumer : Consumers)
+    Consumer->HandleDependentLibrary(Lib);
 }
 
 void MultiplexConsumer::CompleteTentativeDefinition(VarDecl *D) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->CompleteTentativeDefinition(D);
+  for (auto &Consumer : Consumers)
+    Consumer->CompleteTentativeDefinition(D);
 }
 
 void MultiplexConsumer::HandleVTable(
     CXXRecordDecl *RD, bool DefinitionRequired) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->HandleVTable(RD, DefinitionRequired);
+  for (auto &Consumer : Consumers)
+    Consumer->HandleVTable(RD, DefinitionRequired);
 }
 
 ASTMutationListener *MultiplexConsumer::GetASTMutationListener() {
@@ -281,18 +307,18 @@
 }
 
 void MultiplexConsumer::PrintStats() {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    Consumers[i]->PrintStats();
+  for (auto &Consumer : Consumers)
+    Consumer->PrintStats();
 }
 
 void MultiplexConsumer::InitializeSema(Sema &S) {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
+  for (auto &Consumer : Consumers)
+    if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get()))
       SC->InitializeSema(S);
 }
 
 void MultiplexConsumer::ForgetSema() {
-  for (size_t i = 0, e = Consumers.size(); i != e; ++i)
-    if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumers[i]))
+  for (auto &Consumer : Consumers)
+    if (SemaConsumer *SC = dyn_cast<SemaConsumer>(Consumer.get()))
       SC->ForgetSema();
 }
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 4a6f8db..7c1d9a5 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -332,7 +332,10 @@
     MoveToLine(HashLoc);
     OS << "@import " << Imported->getFullModuleName() << ";"
        << " /* clang -E: implicit import for \"" << File->getName() << "\" */";
+    // Since we want a newline after the @import, but not a #<line>, start a new
+    // line immediately.
     EmittedTokensOnThisLine = true;
+    startNewLineIfNeeded();
   }
 }
 
@@ -724,7 +727,7 @@
   PP.AddPragmaHandler("clang",
                       new UnknownPragmaHandler("#pragma clang", Callbacks));
 
-  PP.addPPCallbacks(Callbacks);
+  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Callbacks));
 
   // After we have configured the preprocessor, enter the main file.
   PP.EnterMainSourceFile();
diff --git a/lib/Frontend/Rewrite/Android.mk b/lib/Frontend/Rewrite/Android.mk
new file mode 100644
index 0000000..f23e746
--- /dev/null
+++ b/lib/Frontend/Rewrite/Android.mk
@@ -0,0 +1,48 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_TBLGEN_VARS)
+
+TBLGEN_TABLES := \
+  AttrList.inc \
+  Attrs.inc \
+  AttrParsedAttrList.inc \
+  CommentCommandList.inc \
+  CommentNodes.inc \
+  DeclNodes.inc \
+  DiagnosticCommonKinds.inc \
+  DiagnosticFrontendKinds.inc \
+  StmtNodes.inc
+
+clang_rewrite_frontend_SRC_FILES := \
+  FixItRewriter.cpp \
+  FrontendActions.cpp \
+  HTMLPrint.cpp \
+  InclusionRewriter.cpp \
+  RewriteMacros.cpp \
+  RewriteModernObjC.cpp \
+  RewriteObjC.cpp \
+  RewriteTest.cpp
+
+# For the host
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(clang_rewrite_frontend_SRC_FILES)
+LOCAL_MODULE:= libclangRewriteFrontend
+LOCAL_MODULE_TAGS := optional
+
+include $(CLANG_HOST_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# For the target
+# =====================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(clang_rewrite_frontend_SRC_FILES)
+LOCAL_MODULE:= libclangRewriteFrontend
+LOCAL_MODULE_TAGS := optional
+
+include $(CLANG_DEVICE_BUILD_MK)
+include $(CLANG_TBLGEN_RULES_MK)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/lib/Frontend/Rewrite/CMakeLists.txt b/lib/Frontend/Rewrite/CMakeLists.txt
new file mode 100644
index 0000000..924bf5d
--- /dev/null
+++ b/lib/Frontend/Rewrite/CMakeLists.txt
@@ -0,0 +1,22 @@
+set(LLVM_LINK_COMPONENTS
+  Support
+  )
+
+add_clang_library(clangRewriteFrontend
+  FixItRewriter.cpp
+  FrontendActions.cpp
+  HTMLPrint.cpp
+  InclusionRewriter.cpp
+  RewriteMacros.cpp
+  RewriteModernObjC.cpp
+  RewriteObjC.cpp
+  RewriteTest.cpp
+
+  LINK_LIBS
+  clangAST
+  clangBasic
+  clangEdit
+  clangFrontend
+  clangLex
+  clangRewrite
+  )
diff --git a/lib/Frontend/Rewrite/FixItRewriter.cpp b/lib/Frontend/Rewrite/FixItRewriter.cpp
new file mode 100644
index 0000000..a3e14f9
--- /dev/null
+++ b/lib/Frontend/Rewrite/FixItRewriter.cpp
@@ -0,0 +1,196 @@
+//===--- FixItRewriter.cpp - Fix-It Rewriter Diagnostic Client --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a diagnostic client adaptor that performs rewrites as
+// suggested by code modification hints attached to diagnostics. It
+// then forwards any diagnostics to the adapted diagnostic client.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/FixItRewriter.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Edit/Commit.h"
+#include "clang/Edit/EditsReceiver.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+#include <memory>
+
+using namespace clang;
+
+FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
+                             const LangOptions &LangOpts,
+                             FixItOptions *FixItOpts)
+  : Diags(Diags),
+    Editor(SourceMgr, LangOpts),
+    Rewrite(SourceMgr, LangOpts),
+    FixItOpts(FixItOpts),
+    NumFailures(0),
+    PrevDiagSilenced(false) {
+  Owner = Diags.takeClient();
+  Client = Diags.getClient();
+  Diags.setClient(this, false);
+}
+
+FixItRewriter::~FixItRewriter() {
+  Diags.setClient(Client, Owner.release() != nullptr);
+}
+
+bool FixItRewriter::WriteFixedFile(FileID ID, raw_ostream &OS) {
+  const RewriteBuffer *RewriteBuf = Rewrite.getRewriteBufferFor(ID);
+  if (!RewriteBuf) return true;
+  RewriteBuf->write(OS);
+  OS.flush();
+  return false;
+}
+
+namespace {
+
+class RewritesReceiver : public edit::EditsReceiver {
+  Rewriter &Rewrite;
+
+public:
+  RewritesReceiver(Rewriter &Rewrite) : Rewrite(Rewrite) { }
+
+  void insert(SourceLocation loc, StringRef text) override {
+    Rewrite.InsertText(loc, text);
+  }
+  void replace(CharSourceRange range, StringRef text) override {
+    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) {
+    Diag(FullSourceLoc(), diag::warn_fixit_no_changes);
+    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;
+    std::string Filename = FixItOpts->RewriteFilename(Entry->getName(), fd);
+    std::error_code EC;
+    std::unique_ptr<llvm::raw_fd_ostream> OS;
+    if (fd != -1) {
+      OS.reset(new llvm::raw_fd_ostream(fd, /*shouldClose=*/true));
+    } else {
+      OS.reset(new llvm::raw_fd_ostream(Filename, EC, llvm::sys::fs::F_None));
+    }
+    if (EC) {
+      Diags.Report(clang::diag::err_fe_unable_to_open_output) << Filename
+                                                              << EC.message();
+      continue;
+    }
+    RewriteBuffer &RewriteBuf = I->second;
+    RewriteBuf.write(*OS);
+    OS->flush();
+
+    if (RewrittenFiles)
+      RewrittenFiles->push_back(std::make_pair(Entry->getName(), Filename));
+  }
+
+  return false;
+}
+
+bool FixItRewriter::IncludeInDiagnosticCounts() const {
+  return Client ? Client->IncludeInDiagnosticCounts() : true;
+}
+
+void FixItRewriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+                                     const Diagnostic &Info) {
+  // Default implementation (Warnings/errors count).
+  DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info);
+
+  if (!FixItOpts->Silent ||
+      DiagLevel >= DiagnosticsEngine::Error ||
+      (DiagLevel == DiagnosticsEngine::Note && !PrevDiagSilenced) ||
+      (DiagLevel > DiagnosticsEngine::Note && Info.getNumFixItHints())) {
+    Client->HandleDiagnostic(DiagLevel, Info);
+    PrevDiagSilenced = false;
+  } else {
+    PrevDiagSilenced = true;
+  }
+
+  // Skip over any diagnostics that are ignored or notes.
+  if (DiagLevel <= DiagnosticsEngine::Note)
+    return;
+  // Skip over errors if we are only fixing warnings.
+  if (DiagLevel >= DiagnosticsEngine::Error && FixItOpts->FixOnlyWarnings) {
+    ++NumFailures;
+    return;
+  }
+
+  // Make sure that we can perform all of the modifications we
+  // in this diagnostic.
+  edit::Commit commit(Editor);
+  for (unsigned Idx = 0, Last = Info.getNumFixItHints();
+       Idx < Last; ++Idx) {
+    const FixItHint &Hint = Info.getFixItHint(Idx);
+
+    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)
+      Diag(Info.getLocation(), diag::note_fixit_in_macro);
+
+    // If this was an error, refuse to perform any rewriting.
+    if (DiagLevel >= DiagnosticsEngine::Error) {
+      if (++NumFailures == 1)
+        Diag(Info.getLocation(), diag::note_fixit_unfixed_error);
+    }
+    return;
+  }
+  
+  if (!Editor.commit(commit)) {
+    ++NumFailures;
+    Diag(Info.getLocation(), diag::note_fixit_failed);
+    return;
+  }
+
+  Diag(Info.getLocation(), diag::note_fixit_applied);
+}
+
+/// \brief Emit a diagnostic via the adapted diagnostic client.
+void FixItRewriter::Diag(SourceLocation Loc, unsigned DiagID) {
+  // When producing this diagnostic, we temporarily bypass ourselves,
+  // clear out any current diagnostic, and let the downstream client
+  // format the diagnostic.
+  Diags.setClient(Client, false);
+  Diags.Clear();
+  Diags.Report(Loc, DiagID);
+  Diags.setClient(this, false);
+}
+
+FixItOptions::~FixItOptions() {}
diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp
new file mode 100644
index 0000000..1b5eb28
--- /dev/null
+++ b/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -0,0 +1,196 @@
+//===--- FrontendActions.cpp ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/FrontendActions.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Parse/Parser.h"
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/Rewrite/Frontend/FixItRewriter.h"
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// AST Consumer Actions
+//===----------------------------------------------------------------------===//
+
+std::unique_ptr<ASTConsumer>
+HTMLPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
+    return CreateHTMLPrinter(OS, CI.getPreprocessor());
+  return nullptr;
+}
+
+FixItAction::FixItAction() {}
+FixItAction::~FixItAction() {}
+
+std::unique_ptr<ASTConsumer>
+FixItAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  return llvm::make_unique<ASTConsumer>();
+}
+
+namespace {
+class FixItRewriteInPlace : public FixItOptions {
+public:
+  std::string RewriteFilename(const std::string &Filename, int &fd) override {
+    fd = -1;
+    return Filename;
+  }
+};
+
+class FixItActionSuffixInserter : public FixItOptions {
+  std::string NewSuffix;
+
+public:
+  FixItActionSuffixInserter(std::string NewSuffix, bool FixWhatYouCan)
+    : NewSuffix(NewSuffix) {
+      this->FixWhatYouCan = FixWhatYouCan;
+  }
+
+  std::string RewriteFilename(const std::string &Filename, int &fd) override {
+    fd = -1;
+    SmallString<128> Path(Filename);
+    llvm::sys::path::replace_extension(Path,
+      NewSuffix + llvm::sys::path::extension(Path));
+    return Path.str();
+  }
+};
+
+class FixItRewriteToTemp : public FixItOptions {
+public:
+  std::string RewriteFilename(const std::string &Filename, int &fd) override {
+    SmallString<128> Path;
+    llvm::sys::fs::createTemporaryFile(llvm::sys::path::filename(Filename),
+                                       llvm::sys::path::extension(Filename), fd,
+                                       Path);
+    return Path.str();
+  }
+};
+} // end anonymous namespace
+
+bool FixItAction::BeginSourceFileAction(CompilerInstance &CI,
+                                        StringRef Filename) {
+  const FrontendOptions &FEOpts = getCompilerInstance().getFrontendOpts();
+  if (!FEOpts.FixItSuffix.empty()) {
+    FixItOpts.reset(new FixItActionSuffixInserter(FEOpts.FixItSuffix,
+                                                  FEOpts.FixWhatYouCan));
+  } else {
+    FixItOpts.reset(new FixItRewriteInPlace);
+    FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
+  }
+  Rewriter.reset(new FixItRewriter(CI.getDiagnostics(), CI.getSourceManager(),
+                                   CI.getLangOpts(), FixItOpts.get()));
+  return true;
+}
+
+void FixItAction::EndSourceFileAction() {
+  // Otherwise rewrite all files.
+  Rewriter->WriteFixedFiles();
+}
+
+bool FixItRecompile::BeginInvocation(CompilerInstance &CI) {
+
+  std::vector<std::pair<std::string, std::string> > RewrittenFiles;
+  bool err = false;
+  {
+    const FrontendOptions &FEOpts = CI.getFrontendOpts();
+    std::unique_ptr<FrontendAction> FixAction(new SyntaxOnlyAction());
+    if (FixAction->BeginSourceFile(CI, FEOpts.Inputs[0])) {
+      std::unique_ptr<FixItOptions> FixItOpts;
+      if (FEOpts.FixToTemporaries)
+        FixItOpts.reset(new FixItRewriteToTemp());
+      else
+        FixItOpts.reset(new FixItRewriteInPlace());
+      FixItOpts->Silent = true;
+      FixItOpts->FixWhatYouCan = FEOpts.FixWhatYouCan;
+      FixItOpts->FixOnlyWarnings = FEOpts.FixOnlyWarnings;
+      FixItRewriter Rewriter(CI.getDiagnostics(), CI.getSourceManager(),
+                             CI.getLangOpts(), FixItOpts.get());
+      FixAction->Execute();
+  
+      err = Rewriter.WriteFixedFiles(&RewrittenFiles);
+    
+      FixAction->EndSourceFile();
+      CI.setSourceManager(nullptr);
+      CI.setFileManager(nullptr);
+    } else {
+      err = true;
+    }
+  }
+  if (err)
+    return false;
+  CI.getDiagnosticClient().clear();
+  CI.getDiagnostics().Reset();
+
+  PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
+  PPOpts.RemappedFiles.insert(PPOpts.RemappedFiles.end(),
+                              RewrittenFiles.begin(), RewrittenFiles.end());
+  PPOpts.RemappedFilesKeepOriginalName = false;
+
+  return true;
+}
+
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+
+std::unique_ptr<ASTConsumer>
+RewriteObjCAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile, "cpp")) {
+    if (CI.getLangOpts().ObjCRuntime.isNonFragile())
+      return CreateModernObjCRewriter(InFile, OS,
+                                CI.getDiagnostics(), CI.getLangOpts(),
+                                CI.getDiagnosticOpts().NoRewriteMacros,
+                                (CI.getCodeGenOpts().getDebugInfo() !=
+                                 CodeGenOptions::NoDebugInfo));
+    return CreateObjCRewriter(InFile, OS,
+                              CI.getDiagnostics(), CI.getLangOpts(),
+                              CI.getDiagnosticOpts().NoRewriteMacros);
+  }
+  return nullptr;
+}
+
+#endif
+
+//===----------------------------------------------------------------------===//
+// Preprocessor Actions
+//===----------------------------------------------------------------------===//
+
+void RewriteMacrosAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  RewriteMacrosInInput(CI.getPreprocessor(), OS);
+}
+
+void RewriteTestAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(false, getCurrentFile());
+  if (!OS) return;
+
+  DoRewriteTest(CI.getPreprocessor(), OS);
+}
+
+void RewriteIncludesAction::ExecuteAction() {
+  CompilerInstance &CI = getCompilerInstance();
+  raw_ostream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
+  if (!OS) return;
+
+  RewriteIncludesInInput(CI.getPreprocessor(), OS,
+                         CI.getPreprocessorOutputOpts());
+}
diff --git a/lib/Frontend/Rewrite/HTMLPrint.cpp b/lib/Frontend/Rewrite/HTMLPrint.cpp
new file mode 100644
index 0000000..22ccfe6
--- /dev/null
+++ b/lib/Frontend/Rewrite/HTMLPrint.cpp
@@ -0,0 +1,95 @@
+//===--- HTMLPrint.cpp - Source code -> HTML pretty-printing --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Pretty-printing of source code to HTML.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/HTMLRewrite.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// Functional HTML pretty-printing.
+//===----------------------------------------------------------------------===//
+
+namespace {
+  class HTMLPrinter : public ASTConsumer {
+    Rewriter R;
+    raw_ostream *Out;
+    Preprocessor &PP;
+    bool SyntaxHighlight, HighlightMacros;
+
+  public:
+    HTMLPrinter(raw_ostream *OS, Preprocessor &pp,
+                bool _SyntaxHighlight, bool _HighlightMacros)
+      : Out(OS), PP(pp), SyntaxHighlight(_SyntaxHighlight),
+        HighlightMacros(_HighlightMacros) {}
+
+    void Initialize(ASTContext &context) override;
+    void HandleTranslationUnit(ASTContext &Ctx) override;
+  };
+}
+
+std::unique_ptr<ASTConsumer> clang::CreateHTMLPrinter(raw_ostream *OS,
+                                                      Preprocessor &PP,
+                                                      bool SyntaxHighlight,
+                                                      bool HighlightMacros) {
+  return llvm::make_unique<HTMLPrinter>(OS, PP, SyntaxHighlight,
+                                        HighlightMacros);
+}
+
+void HTMLPrinter::Initialize(ASTContext &context) {
+  R.setSourceMgr(context.getSourceManager(), context.getLangOpts());
+}
+
+void HTMLPrinter::HandleTranslationUnit(ASTContext &Ctx) {
+  if (PP.getDiagnostics().hasErrorOccurred())
+    return;
+
+  // Format the file.
+  FileID FID = R.getSourceMgr().getMainFileID();
+  const FileEntry* Entry = R.getSourceMgr().getFileEntryForID(FID);
+  const char* Name;
+  // In some cases, in particular the case where the input is from stdin,
+  // there is no entry.  Fall back to the memory buffer for a name in those
+  // cases.
+  if (Entry)
+    Name = Entry->getName();
+  else
+    Name = R.getSourceMgr().getBuffer(FID)->getBufferIdentifier();
+
+  html::AddLineNumbers(R, FID);
+  html::AddHeaderFooterInternalBuiltinCSS(R, FID, Name);
+
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
+
+  if (SyntaxHighlight) html::SyntaxHighlight(R, FID, PP);
+  if (HighlightMacros) html::HighlightMacros(R, FID, PP);
+  html::EscapeText(R, FID, false, true);
+
+  // Emit the HTML.
+  const RewriteBuffer &RewriteBuf = R.getEditBuffer(FID);
+  char *Buffer = (char*)malloc(RewriteBuf.size());
+  std::copy(RewriteBuf.begin(), RewriteBuf.end(), Buffer);
+  Out->write(Buffer, RewriteBuf.size());
+  free(Buffer);
+}
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
new file mode 100644
index 0000000..1400557
--- /dev/null
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -0,0 +1,588 @@
+//===--- InclusionRewriter.cpp - Rewrite includes into their expansions ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code rewrites include invocations into their expansions.  This gives you
+// a file with all included files merged into it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/PreprocessorOutputOptions.h"
+#include "clang/Lex/HeaderSearch.h"
+#include "clang/Lex/Pragma.h"
+#include "clang/Lex/Preprocessor.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace llvm;
+
+namespace {
+
+class InclusionRewriter : public PPCallbacks {
+  /// Information about which #includes were actually performed,
+  /// created by preprocessor callbacks.
+  struct FileChange {
+    const Module *Mod;
+    SourceLocation From;
+    FileID Id;
+    SrcMgr::CharacteristicKind FileType;
+    FileChange(SourceLocation From, const Module *Mod) : Mod(Mod), From(From) {
+    }
+  };
+  Preprocessor &PP; ///< Used to find inclusion directives.
+  SourceManager &SM; ///< Used to read and manage source files.
+  raw_ostream &OS; ///< The destination stream for rewritten contents.
+  StringRef MainEOL; ///< The line ending marker to use.
+  const llvm::MemoryBuffer *PredefinesBuffer; ///< The preprocessor predefines.
+  bool ShowLineMarkers; ///< Show #line markers.
+  bool UseLineDirective; ///< Use of line directives or line markers.
+  typedef std::map<unsigned, FileChange> FileChangeMap;
+  FileChangeMap FileChanges; ///< Tracks which files were included where.
+  /// Used transitively for building up the FileChanges mapping over the
+  /// various \c PPCallbacks callbacks.
+  FileChangeMap::iterator LastInsertedFileChange;
+public:
+  InclusionRewriter(Preprocessor &PP, raw_ostream &OS, bool ShowLineMarkers);
+  bool Process(FileID FileId, SrcMgr::CharacteristicKind FileType);
+  void setPredefinesBuffer(const llvm::MemoryBuffer *Buf) {
+    PredefinesBuffer = Buf;
+  }
+  void detectMainFileEOL();
+private:
+  void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+                   SrcMgr::CharacteristicKind FileType,
+                   FileID PrevFID) override;
+  void FileSkipped(const FileEntry &ParentFile, const Token &FilenameTok,
+                   SrcMgr::CharacteristicKind FileType) override;
+  void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
+                          StringRef FileName, bool IsAngled,
+                          CharSourceRange FilenameRange, const FileEntry *File,
+                          StringRef SearchPath, StringRef RelativePath,
+                          const Module *Imported) override;
+  void WriteLineInfo(const char *Filename, int Line,
+                     SrcMgr::CharacteristicKind FileType,
+                     StringRef Extra = StringRef());
+  void WriteImplicitModuleImport(const Module *Mod);
+  void OutputContentUpTo(const MemoryBuffer &FromFile,
+                         unsigned &WriteFrom, unsigned WriteTo,
+                         StringRef EOL, int &lines,
+                         bool EnsureNewline);
+  void CommentOutDirective(Lexer &DirectivesLex, const Token &StartToken,
+                           const MemoryBuffer &FromFile, StringRef EOL,
+                           unsigned &NextToWrite, int &Lines);
+  bool HandleHasInclude(FileID FileId, Lexer &RawLex,
+                        const DirectoryLookup *Lookup, Token &Tok,
+                        bool &FileExists);
+  const FileChange *FindFileChangeLocation(SourceLocation Loc) const;
+  StringRef NextIdentifierName(Lexer &RawLex, Token &RawToken);
+};
+
+}  // end anonymous namespace
+
+/// Initializes an InclusionRewriter with a \p PP source and \p OS destination.
+InclusionRewriter::InclusionRewriter(Preprocessor &PP, raw_ostream &OS,
+                                     bool ShowLineMarkers)
+    : PP(PP), SM(PP.getSourceManager()), OS(OS), MainEOL("\n"),
+      PredefinesBuffer(nullptr), ShowLineMarkers(ShowLineMarkers),
+      LastInsertedFileChange(FileChanges.end()) {
+  // If we're in microsoft mode, use normal #line instead of line markers.
+  UseLineDirective = PP.getLangOpts().MicrosoftExt;
+}
+
+/// Write appropriate line information as either #line directives or GNU line
+/// markers depending on what mode we're in, including the \p Filename and
+/// \p Line we are located at, using the specified \p EOL line separator, and
+/// any \p Extra context specifiers in GNU line directives.
+void InclusionRewriter::WriteLineInfo(const char *Filename, int Line,
+                                      SrcMgr::CharacteristicKind FileType,
+                                      StringRef Extra) {
+  if (!ShowLineMarkers)
+    return;
+  if (UseLineDirective) {
+    OS << "#line" << ' ' << Line << ' ' << '"';
+    OS.write_escaped(Filename);
+    OS << '"';
+  } else {
+    // Use GNU linemarkers as described here:
+    // http://gcc.gnu.org/onlinedocs/cpp/Preprocessor-Output.html
+    OS << '#' << ' ' << Line << ' ' << '"';
+    OS.write_escaped(Filename);
+    OS << '"';
+    if (!Extra.empty())
+      OS << Extra;
+    if (FileType == SrcMgr::C_System)
+      // "`3' This indicates that the following text comes from a system header
+      // file, so certain warnings should be suppressed."
+      OS << " 3";
+    else if (FileType == SrcMgr::C_ExternCSystem)
+      // as above for `3', plus "`4' This indicates that the following text
+      // should be treated as being wrapped in an implicit extern "C" block."
+      OS << " 3 4";
+  }
+  OS << MainEOL;
+}
+
+void InclusionRewriter::WriteImplicitModuleImport(const Module *Mod) {
+  OS << "@import " << Mod->getFullModuleName() << ";"
+     << " /* clang -frewrite-includes: implicit import */" << MainEOL;
+}
+
+/// FileChanged - Whenever the preprocessor enters or exits a #include file
+/// it invokes this handler.
+void InclusionRewriter::FileChanged(SourceLocation Loc,
+                                    FileChangeReason Reason,
+                                    SrcMgr::CharacteristicKind NewFileType,
+                                    FileID) {
+  if (Reason != EnterFile)
+    return;
+  if (LastInsertedFileChange == FileChanges.end())
+    // we didn't reach this file (eg: the main file) via an inclusion directive
+    return;
+  LastInsertedFileChange->second.Id = FullSourceLoc(Loc, SM).getFileID();
+  LastInsertedFileChange->second.FileType = NewFileType;
+  LastInsertedFileChange = FileChanges.end();
+}
+
+/// Called whenever an inclusion is skipped due to canonical header protection
+/// macros.
+void InclusionRewriter::FileSkipped(const FileEntry &/*ParentFile*/,
+                                    const Token &/*FilenameTok*/,
+                                    SrcMgr::CharacteristicKind /*FileType*/) {
+  assert(LastInsertedFileChange != FileChanges.end() && "A file, that wasn't "
+    "found via an inclusion directive, was skipped");
+  FileChanges.erase(LastInsertedFileChange);
+  LastInsertedFileChange = FileChanges.end();
+}
+
+/// This should be called whenever the preprocessor encounters include
+/// directives. It does not say whether the file has been included, but it
+/// provides more information about the directive (hash location instead
+/// of location inside the included file). It is assumed that the matching
+/// FileChanged() or FileSkipped() is called after this.
+void InclusionRewriter::InclusionDirective(SourceLocation HashLoc,
+                                           const Token &/*IncludeTok*/,
+                                           StringRef /*FileName*/,
+                                           bool /*IsAngled*/,
+                                           CharSourceRange /*FilenameRange*/,
+                                           const FileEntry * /*File*/,
+                                           StringRef /*SearchPath*/,
+                                           StringRef /*RelativePath*/,
+                                           const Module *Imported) {
+  assert(LastInsertedFileChange == FileChanges.end() && "Another inclusion "
+    "directive was found before the previous one was processed");
+  std::pair<FileChangeMap::iterator, bool> p = FileChanges.insert(
+    std::make_pair(HashLoc.getRawEncoding(), FileChange(HashLoc, Imported)));
+  assert(p.second && "Unexpected revisitation of the same include directive");
+  if (!Imported)
+    LastInsertedFileChange = p.first;
+}
+
+/// Simple lookup for a SourceLocation (specifically one denoting the hash in
+/// an inclusion directive) in the map of inclusion information, FileChanges.
+const InclusionRewriter::FileChange *
+InclusionRewriter::FindFileChangeLocation(SourceLocation Loc) const {
+  FileChangeMap::const_iterator I = FileChanges.find(Loc.getRawEncoding());
+  if (I != FileChanges.end())
+    return &I->second;
+  return nullptr;
+}
+
+/// Detect the likely line ending style of \p FromFile by examining the first
+/// newline found within it.
+static StringRef DetectEOL(const MemoryBuffer &FromFile) {
+  // Detect what line endings the file uses, so that added content does not mix
+  // the style. We need to check for "\r\n" first because "\n\r" will match
+  // "\r\n\r\n".
+  const char *Pos = strchr(FromFile.getBufferStart(), '\n');
+  if (!Pos)
+    return "\n";
+  if (Pos - 1 >= FromFile.getBufferStart() && Pos[-1] == '\r')
+    return "\r\n";
+  if (Pos + 1 < FromFile.getBufferEnd() && Pos[1] == '\r')
+    return "\n\r";
+  return "\n";
+}
+
+void InclusionRewriter::detectMainFileEOL() {
+  bool Invalid;
+  const MemoryBuffer &FromFile = *SM.getBuffer(SM.getMainFileID(), &Invalid);
+  assert(!Invalid);
+  if (Invalid)
+    return; // Should never happen, but whatever.
+  MainEOL = DetectEOL(FromFile);
+}
+
+/// Writes out bytes from \p FromFile, starting at \p NextToWrite and ending at
+/// \p WriteTo - 1.
+void InclusionRewriter::OutputContentUpTo(const MemoryBuffer &FromFile,
+                                          unsigned &WriteFrom, unsigned WriteTo,
+                                          StringRef LocalEOL, int &Line,
+                                          bool EnsureNewline) {
+  if (WriteTo <= WriteFrom)
+    return;
+  if (&FromFile == PredefinesBuffer) {
+    // Ignore the #defines of the predefines buffer.
+    WriteFrom = WriteTo;
+    return;
+  }
+
+  // If we would output half of a line ending, advance one character to output
+  // the whole line ending.  All buffers are null terminated, so looking ahead
+  // one byte is safe.
+  if (LocalEOL.size() == 2 &&
+      LocalEOL[0] == (FromFile.getBufferStart() + WriteTo)[-1] &&
+      LocalEOL[1] == (FromFile.getBufferStart() + WriteTo)[0])
+    WriteTo++;
+
+  StringRef TextToWrite(FromFile.getBufferStart() + WriteFrom,
+                        WriteTo - WriteFrom);
+
+  if (MainEOL == LocalEOL) {
+    OS << TextToWrite;
+    // count lines manually, it's faster than getPresumedLoc()
+    Line += TextToWrite.count(LocalEOL);
+    if (EnsureNewline && !TextToWrite.endswith(LocalEOL))
+      OS << MainEOL;
+  } else {
+    // Output the file one line at a time, rewriting the line endings as we go.
+    StringRef Rest = TextToWrite;
+    while (!Rest.empty()) {
+      StringRef LineText;
+      std::tie(LineText, Rest) = Rest.split(LocalEOL);
+      OS << LineText;
+      Line++;
+      if (!Rest.empty())
+        OS << MainEOL;
+    }
+    if (TextToWrite.endswith(LocalEOL) || EnsureNewline)
+      OS << MainEOL;
+  }
+  WriteFrom = WriteTo;
+}
+
+/// Print characters from \p FromFile starting at \p NextToWrite up until the
+/// inclusion directive at \p StartToken, then print out the inclusion
+/// inclusion directive disabled by a #if directive, updating \p NextToWrite
+/// and \p Line to track the number of source lines visited and the progress
+/// through the \p FromFile buffer.
+void InclusionRewriter::CommentOutDirective(Lexer &DirectiveLex,
+                                            const Token &StartToken,
+                                            const MemoryBuffer &FromFile,
+                                            StringRef LocalEOL,
+                                            unsigned &NextToWrite, int &Line) {
+  OutputContentUpTo(FromFile, NextToWrite,
+                    SM.getFileOffset(StartToken.getLocation()), LocalEOL, Line,
+                    false);
+  Token DirectiveToken;
+  do {
+    DirectiveLex.LexFromRawLexer(DirectiveToken);
+  } while (!DirectiveToken.is(tok::eod) && DirectiveToken.isNot(tok::eof));
+  if (&FromFile == PredefinesBuffer) {
+    // OutputContentUpTo() would not output anything anyway.
+    return;
+  }
+  OS << "#if 0 /* expanded by -frewrite-includes */" << MainEOL;
+  OutputContentUpTo(FromFile, NextToWrite,
+                    SM.getFileOffset(DirectiveToken.getLocation()) +
+                        DirectiveToken.getLength(),
+                    LocalEOL, Line, true);
+  OS << "#endif /* expanded by -frewrite-includes */" << MainEOL;
+}
+
+/// Find the next identifier in the pragma directive specified by \p RawToken.
+StringRef InclusionRewriter::NextIdentifierName(Lexer &RawLex,
+                                                Token &RawToken) {
+  RawLex.LexFromRawLexer(RawToken);
+  if (RawToken.is(tok::raw_identifier))
+    PP.LookUpIdentifierInfo(RawToken);
+  if (RawToken.is(tok::identifier))
+    return RawToken.getIdentifierInfo()->getName();
+  return StringRef();
+}
+
+// Expand __has_include and __has_include_next if possible. If there's no
+// definitive answer return false.
+bool InclusionRewriter::HandleHasInclude(
+    FileID FileId, Lexer &RawLex, const DirectoryLookup *Lookup, Token &Tok,
+    bool &FileExists) {
+  // Lex the opening paren.
+  RawLex.LexFromRawLexer(Tok);
+  if (Tok.isNot(tok::l_paren))
+    return false;
+
+  RawLex.LexFromRawLexer(Tok);
+
+  SmallString<128> FilenameBuffer;
+  StringRef Filename;
+  // Since the raw lexer doesn't give us angle_literals we have to parse them
+  // ourselves.
+  // FIXME: What to do if the file name is a macro?
+  if (Tok.is(tok::less)) {
+    RawLex.LexFromRawLexer(Tok);
+
+    FilenameBuffer += '<';
+    do {
+      if (Tok.is(tok::eod)) // Sanity check.
+        return false;
+
+      if (Tok.is(tok::raw_identifier))
+        PP.LookUpIdentifierInfo(Tok);
+
+      // Get the string piece.
+      SmallVector<char, 128> TmpBuffer;
+      bool Invalid = false;
+      StringRef TmpName = PP.getSpelling(Tok, TmpBuffer, &Invalid);
+      if (Invalid)
+        return false;
+
+      FilenameBuffer += TmpName;
+
+      RawLex.LexFromRawLexer(Tok);
+    } while (Tok.isNot(tok::greater));
+
+    FilenameBuffer += '>';
+    Filename = FilenameBuffer;
+  } else {
+    if (Tok.isNot(tok::string_literal))
+      return false;
+
+    bool Invalid = false;
+    Filename = PP.getSpelling(Tok, FilenameBuffer, &Invalid);
+    if (Invalid)
+      return false;
+  }
+
+  // Lex the closing paren.
+  RawLex.LexFromRawLexer(Tok);
+  if (Tok.isNot(tok::r_paren))
+    return false;
+
+  // Now ask HeaderInfo if it knows about the header.
+  // FIXME: Subframeworks aren't handled here. Do we care?
+  bool isAngled = PP.GetIncludeFilenameSpelling(Tok.getLocation(), Filename);
+  const DirectoryLookup *CurDir;
+  const FileEntry *FileEnt = PP.getSourceManager().getFileEntryForID(FileId);
+  SmallVector<std::pair<const FileEntry *, const DirectoryEntry *>, 1>
+      Includers;
+  Includers.push_back(std::make_pair(FileEnt, FileEnt->getDir()));
+  const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
+      Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr,
+      nullptr, nullptr, false);
+
+  FileExists = File != nullptr;
+  return true;
+}
+
+/// Use a raw lexer to analyze \p FileId, incrementally copying parts of it
+/// and including content of included files recursively.
+bool InclusionRewriter::Process(FileID FileId,
+                                SrcMgr::CharacteristicKind FileType)
+{
+  bool Invalid;
+  const MemoryBuffer &FromFile = *SM.getBuffer(FileId, &Invalid);
+  if (Invalid) // invalid inclusion
+    return false;
+  const char *FileName = FromFile.getBufferIdentifier();
+  Lexer RawLex(FileId, &FromFile, PP.getSourceManager(), PP.getLangOpts());
+  RawLex.SetCommentRetentionState(false);
+
+  StringRef LocalEOL = DetectEOL(FromFile);
+
+  // Per the GNU docs: "1" indicates entering a new file.
+  if (FileId == SM.getMainFileID() || FileId == PP.getPredefinesFileID())
+    WriteLineInfo(FileName, 1, FileType, "");
+  else
+    WriteLineInfo(FileName, 1, FileType, " 1");
+
+  if (SM.getFileIDSize(FileId) == 0)
+    return false;
+
+  // The next byte to be copied from the source file, which may be non-zero if
+  // the lexer handled a BOM.
+  unsigned NextToWrite = SM.getFileOffset(RawLex.getSourceLocation());
+  assert(SM.getLineNumber(FileId, NextToWrite) == 1);
+  int Line = 1; // The current input file line number.
+
+  Token RawToken;
+  RawLex.LexFromRawLexer(RawToken);
+
+  // TODO: Consider adding a switch that strips possibly unimportant content,
+  // such as comments, to reduce the size of repro files.
+  while (RawToken.isNot(tok::eof)) {
+    if (RawToken.is(tok::hash) && RawToken.isAtStartOfLine()) {
+      RawLex.setParsingPreprocessorDirective(true);
+      Token HashToken = RawToken;
+      RawLex.LexFromRawLexer(RawToken);
+      if (RawToken.is(tok::raw_identifier))
+        PP.LookUpIdentifierInfo(RawToken);
+      if (RawToken.getIdentifierInfo() != nullptr) {
+        switch (RawToken.getIdentifierInfo()->getPPKeywordID()) {
+          case tok::pp_include:
+          case tok::pp_include_next:
+          case tok::pp_import: {
+            CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL, NextToWrite,
+              Line);
+            if (FileId != PP.getPredefinesFileID())
+              WriteLineInfo(FileName, Line - 1, FileType, "");
+            StringRef LineInfoExtra;
+            if (const FileChange *Change = FindFileChangeLocation(
+                HashToken.getLocation())) {
+              if (Change->Mod) {
+                WriteImplicitModuleImport(Change->Mod);
+
+              // else now include and recursively process the file
+              } else if (Process(Change->Id, Change->FileType)) {
+                // and set lineinfo back to this file, if the nested one was
+                // actually included
+                // `2' indicates returning to a file (after having included
+                // another file.
+                LineInfoExtra = " 2";
+              }
+            }
+            // fix up lineinfo (since commented out directive changed line
+            // numbers) for inclusions that were skipped due to header guards
+            WriteLineInfo(FileName, Line, FileType, LineInfoExtra);
+            break;
+          }
+          case tok::pp_pragma: {
+            StringRef Identifier = NextIdentifierName(RawLex, RawToken);
+            if (Identifier == "clang" || Identifier == "GCC") {
+              if (NextIdentifierName(RawLex, RawToken) == "system_header") {
+                // keep the directive in, commented out
+                CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL,
+                  NextToWrite, Line);
+                // update our own type
+                FileType = SM.getFileCharacteristic(RawToken.getLocation());
+                WriteLineInfo(FileName, Line, FileType);
+              }
+            } else if (Identifier == "once") {
+              // keep the directive in, commented out
+              CommentOutDirective(RawLex, HashToken, FromFile, LocalEOL,
+                NextToWrite, Line);
+              WriteLineInfo(FileName, Line, FileType);
+            }
+            break;
+          }
+          case tok::pp_if:
+          case tok::pp_elif: {
+            bool elif = (RawToken.getIdentifierInfo()->getPPKeywordID() ==
+                         tok::pp_elif);
+            // Rewrite special builtin macros to avoid pulling in host details.
+            do {
+              // Walk over the directive.
+              RawLex.LexFromRawLexer(RawToken);
+              if (RawToken.is(tok::raw_identifier))
+                PP.LookUpIdentifierInfo(RawToken);
+
+              if (RawToken.is(tok::identifier)) {
+                bool HasFile;
+                SourceLocation Loc = RawToken.getLocation();
+
+                // Rewrite __has_include(x)
+                if (RawToken.getIdentifierInfo()->isStr("__has_include")) {
+                  if (!HandleHasInclude(FileId, RawLex, nullptr, RawToken,
+                                        HasFile))
+                    continue;
+                  // Rewrite __has_include_next(x)
+                } else if (RawToken.getIdentifierInfo()->isStr(
+                               "__has_include_next")) {
+                  const DirectoryLookup *Lookup = PP.GetCurDirLookup();
+                  if (Lookup)
+                    ++Lookup;
+
+                  if (!HandleHasInclude(FileId, RawLex, Lookup, RawToken,
+                                        HasFile))
+                    continue;
+                } else {
+                  continue;
+                }
+                // Replace the macro with (0) or (1), followed by the commented
+                // out macro for reference.
+                OutputContentUpTo(FromFile, NextToWrite, SM.getFileOffset(Loc),
+                                  LocalEOL, Line, false);
+                OS << '(' << (int) HasFile << ")/*";
+                OutputContentUpTo(FromFile, NextToWrite,
+                                  SM.getFileOffset(RawToken.getLocation()) +
+                                      RawToken.getLength(),
+                                  LocalEOL, Line, false);
+                OS << "*/";
+              }
+            } while (RawToken.isNot(tok::eod));
+            if (elif) {
+              OutputContentUpTo(FromFile, NextToWrite,
+                                SM.getFileOffset(RawToken.getLocation()) +
+                                    RawToken.getLength(),
+                                LocalEOL, Line, /*EnsureNewline=*/ true);
+              WriteLineInfo(FileName, Line, FileType);
+            }
+            break;
+          }
+          case tok::pp_endif:
+          case tok::pp_else: {
+            // We surround every #include by #if 0 to comment it out, but that
+            // changes line numbers. These are fixed up right after that, but
+            // the whole #include could be inside a preprocessor conditional
+            // that is not processed. So it is necessary to fix the line
+            // numbers one the next line after each #else/#endif as well.
+            RawLex.SetKeepWhitespaceMode(true);
+            do {
+              RawLex.LexFromRawLexer(RawToken);
+            } while (RawToken.isNot(tok::eod) && RawToken.isNot(tok::eof));
+            OutputContentUpTo(FromFile, NextToWrite,
+                              SM.getFileOffset(RawToken.getLocation()) +
+                                  RawToken.getLength(),
+                              LocalEOL, Line, /*EnsureNewline=*/ true);
+            WriteLineInfo(FileName, Line, FileType);
+            RawLex.SetKeepWhitespaceMode(false);
+          }
+          default:
+            break;
+        }
+      }
+      RawLex.setParsingPreprocessorDirective(false);
+    }
+    RawLex.LexFromRawLexer(RawToken);
+  }
+  OutputContentUpTo(FromFile, NextToWrite,
+                    SM.getFileOffset(SM.getLocForEndOfFile(FileId)), LocalEOL,
+                    Line, /*EnsureNewline=*/true);
+  return true;
+}
+
+/// InclusionRewriterInInput - Implement -frewrite-includes mode.
+void clang::RewriteIncludesInInput(Preprocessor &PP, raw_ostream *OS,
+                                   const PreprocessorOutputOptions &Opts) {
+  SourceManager &SM = PP.getSourceManager();
+  InclusionRewriter *Rewrite = new InclusionRewriter(PP, *OS,
+                                                     Opts.ShowLineMarkers);
+  Rewrite->detectMainFileEOL();
+
+  PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(Rewrite));
+  PP.IgnorePragmas();
+
+  // First let the preprocessor process the entire file and call callbacks.
+  // Callbacks will record which #include's were actually performed.
+  PP.EnterMainSourceFile();
+  Token Tok;
+  // Only preprocessor directives matter here, so disable macro expansion
+  // everywhere else as an optimization.
+  // TODO: It would be even faster if the preprocessor could be switched
+  // to a mode where it would parse only preprocessor directives and comments,
+  // nothing else matters for parsing or processing.
+  PP.SetMacroExpansionOnlyInDirectives();
+  do {
+    PP.Lex(Tok);
+  } while (Tok.isNot(tok::eof));
+  Rewrite->setPredefinesBuffer(SM.getBuffer(PP.getPredefinesFileID()));
+  Rewrite->Process(PP.getPredefinesFileID(), SrcMgr::C_User);
+  Rewrite->Process(SM.getMainFileID(), SrcMgr::C_User);
+  OS->flush();
+}
diff --git a/lib/Frontend/Rewrite/Makefile b/lib/Frontend/Rewrite/Makefile
new file mode 100644
index 0000000..1d56547
--- /dev/null
+++ b/lib/Frontend/Rewrite/Makefile
@@ -0,0 +1,22 @@
+##===- clang/lib/Rewrite/Makefile --------------------------*- Makefile -*-===##
+# 
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+# 
+##===----------------------------------------------------------------------===##
+#
+# This implements code transformation / rewriting facilities.
+#
+##===----------------------------------------------------------------------===##
+
+CLANG_LEVEL := ../../..
+LIBRARYNAME := clangRewriteFrontend
+
+include $(CLANG_LEVEL)/Makefile
+
+ifeq ($(ENABLE_CLANG_ARCMT),1)
+  CXX.Flags += -DCLANG_ENABLE_OBJC_REWRITER
+endif
+
diff --git a/lib/Frontend/Rewrite/RewriteMacros.cpp b/lib/Frontend/Rewrite/RewriteMacros.cpp
new file mode 100644
index 0000000..0d0a991
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteMacros.cpp
@@ -0,0 +1,217 @@
+//===--- RewriteMacros.cpp - Rewrite macros into their expansions ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This code rewrites macro invocations into their expansions.  This gives you
+// a macro expanded file that retains comments and #includes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdio>
+#include <memory>
+
+using namespace clang;
+
+/// isSameToken - Return true if the two specified tokens start have the same
+/// content.
+static bool isSameToken(Token &RawTok, Token &PPTok) {
+  // If two tokens have the same kind and the same identifier info, they are
+  // obviously the same.
+  if (PPTok.getKind() == RawTok.getKind() &&
+      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
+    return true;
+
+  // Otherwise, if they are different but have the same identifier info, they
+  // are also considered to be the same.  This allows keywords and raw lexed
+  // identifiers with the same name to be treated the same.
+  if (PPTok.getIdentifierInfo() &&
+      PPTok.getIdentifierInfo() == RawTok.getIdentifierInfo())
+    return true;
+
+  return false;
+}
+
+
+/// GetNextRawTok - Return the next raw token in the stream, skipping over
+/// comments if ReturnComment is false.
+static const Token &GetNextRawTok(const std::vector<Token> &RawTokens,
+                                  unsigned &CurTok, bool ReturnComment) {
+  assert(CurTok < RawTokens.size() && "Overran eof!");
+
+  // If the client doesn't want comments and we have one, skip it.
+  if (!ReturnComment && RawTokens[CurTok].is(tok::comment))
+    ++CurTok;
+
+  return RawTokens[CurTok++];
+}
+
+
+/// LexRawTokensFromMainFile - Lets all the raw tokens from the main file into
+/// the specified vector.
+static void LexRawTokensFromMainFile(Preprocessor &PP,
+                                     std::vector<Token> &RawTokens) {
+  SourceManager &SM = PP.getSourceManager();
+
+  // Create a lexer to lex all the tokens of the main file in raw mode.  Even
+  // though it is in raw mode, it will not return comments.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
+  Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
+
+  // Switch on comment lexing because we really do want them.
+  RawLex.SetCommentRetentionState(true);
+
+  Token RawTok;
+  do {
+    RawLex.LexFromRawLexer(RawTok);
+
+    // If we have an identifier with no identifier info for our raw token, look
+    // up the indentifier info.  This is important for equality comparison of
+    // identifier tokens.
+    if (RawTok.is(tok::raw_identifier))
+      PP.LookUpIdentifierInfo(RawTok);
+
+    RawTokens.push_back(RawTok);
+  } while (RawTok.isNot(tok::eof));
+}
+
+
+/// RewriteMacrosInInput - Implement -rewrite-macros mode.
+void clang::RewriteMacrosInInput(Preprocessor &PP, raw_ostream *OS) {
+  SourceManager &SM = PP.getSourceManager();
+
+  Rewriter Rewrite;
+  Rewrite.setSourceMgr(SM, PP.getLangOpts());
+  RewriteBuffer &RB = Rewrite.getEditBuffer(SM.getMainFileID());
+
+  std::vector<Token> RawTokens;
+  LexRawTokensFromMainFile(PP, RawTokens);
+  unsigned CurRawTok = 0;
+  Token RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+
+
+  // Get the first preprocessing token.
+  PP.EnterMainSourceFile();
+  Token PPTok;
+  PP.Lex(PPTok);
+
+  // Preprocess the input file in parallel with raw lexing the main file. Ignore
+  // all tokens that are preprocessed from a file other than the main file (e.g.
+  // a header).  If we see tokens that are in the preprocessed file but not the
+  // lexed file, we have a macro expansion.  If we see tokens in the lexed file
+  // that aren't in the preprocessed view, we have macros that expand to no
+  // tokens, or macro arguments etc.
+  while (RawTok.isNot(tok::eof) || PPTok.isNot(tok::eof)) {
+    SourceLocation PPLoc = SM.getExpansionLoc(PPTok.getLocation());
+
+    // If PPTok is from a different source file, ignore it.
+    if (!SM.isWrittenInMainFile(PPLoc)) {
+      PP.Lex(PPTok);
+      continue;
+    }
+
+    // If the raw file hits a preprocessor directive, they will be extra tokens
+    // in the raw file that don't exist in the preprocsesed file.  However, we
+    // choose to preserve them in the output file and otherwise handle them
+    // specially.
+    if (RawTok.is(tok::hash) && RawTok.isAtStartOfLine()) {
+      // If this is a #warning directive or #pragma mark (GNU extensions),
+      // comment the line out.
+      if (RawTokens[CurRawTok].is(tok::identifier)) {
+        const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo();
+        if (II->getName() == "warning") {
+          // Comment out #warning.
+          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
+        } else if (II->getName() == "pragma" &&
+                   RawTokens[CurRawTok+1].is(tok::identifier) &&
+                   (RawTokens[CurRawTok+1].getIdentifierInfo()->getName() ==
+                    "mark")) {
+          // Comment out #pragma mark.
+          RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");
+        }
+      }
+
+      // Otherwise, if this is a #include or some other directive, just leave it
+      // in the file by skipping over the line.
+      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      while (!RawTok.isAtStartOfLine() && RawTok.isNot(tok::eof))
+        RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      continue;
+    }
+
+    // Okay, both tokens are from the same file.  Get their offsets from the
+    // start of the file.
+    unsigned PPOffs = SM.getFileOffset(PPLoc);
+    unsigned RawOffs = SM.getFileOffset(RawTok.getLocation());
+
+    // If the offsets are the same and the token kind is the same, ignore them.
+    if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) {
+      RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+      PP.Lex(PPTok);
+      continue;
+    }
+
+    // If the PP token is farther along than the raw token, something was
+    // deleted.  Comment out the raw token.
+    if (RawOffs <= PPOffs) {
+      // Comment out a whole run of tokens instead of bracketing each one with
+      // comments.  Add a leading space if RawTok didn't have one.
+      bool HasSpace = RawTok.hasLeadingSpace();
+      RB.InsertTextAfter(RawOffs, &" /*"[HasSpace]);
+      unsigned EndPos;
+
+      do {
+        EndPos = RawOffs+RawTok.getLength();
+
+        RawTok = GetNextRawTok(RawTokens, CurRawTok, true);
+        RawOffs = SM.getFileOffset(RawTok.getLocation());
+
+        if (RawTok.is(tok::comment)) {
+          // Skip past the comment.
+          RawTok = GetNextRawTok(RawTokens, CurRawTok, false);
+          break;
+        }
+
+      } while (RawOffs <= PPOffs && !RawTok.isAtStartOfLine() &&
+               (PPOffs != RawOffs || !isSameToken(RawTok, PPTok)));
+
+      RB.InsertTextBefore(EndPos, "*/");
+      continue;
+    }
+
+    // Otherwise, there was a replacement an expansion.  Insert the new token
+    // in the output buffer.  Insert the whole run of new tokens at once to get
+    // them in the right order.
+    unsigned InsertPos = PPOffs;
+    std::string Expansion;
+    while (PPOffs < RawOffs) {
+      Expansion += ' ' + PP.getSpelling(PPTok);
+      PP.Lex(PPTok);
+      PPLoc = SM.getExpansionLoc(PPTok.getLocation());
+      PPOffs = SM.getFileOffset(PPLoc);
+    }
+    Expansion += ' ';
+    RB.InsertTextBefore(InsertPos, Expansion);
+  }
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(SM.getMainFileID())) {
+    //printf("Changed:\n");
+    *OS << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    fprintf(stderr, "No changes\n");
+  }
+  OS->flush();
+}
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
new file mode 100644
index 0000000..ffac51e
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -0,0 +1,7743 @@
+//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the code rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TargetInfo.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+  class RewriteModernObjC : public ASTConsumer {
+  protected:
+    
+    enum {
+      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
+                                        block, ... */
+      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
+      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
+                                        __block variable */
+      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
+                                        helpers */
+      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
+                                        support routines */
+      BLOCK_BYREF_CURRENT_MAX = 256
+    };
+    
+    enum {
+      BLOCK_NEEDS_FREE =        (1 << 24),
+      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+      BLOCK_HAS_CXX_OBJ =       (1 << 26),
+      BLOCK_IS_GC =             (1 << 27),
+      BLOCK_IS_GLOBAL =         (1 << 28),
+      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+    };
+    
+    Rewriter Rewrite;
+    DiagnosticsEngine &Diags;
+    const LangOptions &LangOpts;
+    ASTContext *Context;
+    SourceManager *SM;
+    TranslationUnitDecl *TUDecl;
+    FileID MainFileID;
+    const char *MainFileStart, *MainFileEnd;
+    Stmt *CurrentBody;
+    ParentMap *PropParentMap; // created lazily.
+    std::string InFileName;
+    raw_ostream* OutFile;
+    std::string Preamble;
+    
+    TypeDecl *ProtocolTypeDecl;
+    VarDecl *GlobalVarDecl;
+    Expr *GlobalConstructionExp;
+    unsigned RewriteFailedDiag;
+    unsigned GlobalBlockRewriteFailedDiag;
+    // ObjC string constant support.
+    unsigned NumObjCStringLiterals;
+    VarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+
+    // ObjC foreach break/continue generation support.
+    int BcLabelCount;
+    
+    unsigned TryFinallyContainsReturnDiag;
+    // Needed for super.
+    ObjCMethodDecl *CurMethodDef;
+    RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
+    
+    FunctionDecl *MsgSendFunctionDecl;
+    FunctionDecl *MsgSendSuperFunctionDecl;
+    FunctionDecl *MsgSendStretFunctionDecl;
+    FunctionDecl *MsgSendSuperStretFunctionDecl;
+    FunctionDecl *MsgSendFpretFunctionDecl;
+    FunctionDecl *GetClassFunctionDecl;
+    FunctionDecl *GetMetaClassFunctionDecl;
+    FunctionDecl *GetSuperClassFunctionDecl;
+    FunctionDecl *SelGetUidFunctionDecl;
+    FunctionDecl *CFStringFunctionDecl;
+    FunctionDecl *SuperConstructorFunctionDecl;
+    FunctionDecl *CurFunctionDef;
+
+    /* Misc. containers needed for meta-data rewrite. */
+    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
+    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
+    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCWrittenInterfaces;
+    llvm::SmallPtrSet<TagDecl*, 32> GlobalDefinedTags;
+    SmallVector<ObjCInterfaceDecl*, 32> ObjCInterfacesSeen;
+    /// DefinedNonLazyClasses - List of defined "non-lazy" classes.
+    SmallVector<ObjCInterfaceDecl*, 8> DefinedNonLazyClasses;
+    
+    /// DefinedNonLazyCategories - List of defined "non-lazy" categories.
+    SmallVector<ObjCCategoryDecl *, 8> DefinedNonLazyCategories;
+    
+    SmallVector<Stmt *, 32> Stmts;
+    SmallVector<int, 8> ObjCBcLabelNo;
+    // Remember all the @protocol(<expr>) expressions.
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
+    
+    llvm::DenseSet<uint64_t> CopyDestroyCache;
+
+    // Block expressions.
+    SmallVector<BlockExpr *, 32> Blocks;
+    SmallVector<int, 32> InnerDeclRefsCount;
+    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
+    
+    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
+
+    
+    // Block related declarations.
+    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+    SmallVector<ValueDecl *, 8> BlockByRefDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
+    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
+    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
+    
+    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+    llvm::DenseMap<ObjCInterfaceDecl *, 
+                    llvm::SmallPtrSet<ObjCIvarDecl *, 8> > ReferencedIvars;
+    
+    // ivar bitfield grouping containers
+    llvm::DenseSet<const ObjCInterfaceDecl *> ObjCInterefaceHasBitfieldGroups;
+    llvm::DenseMap<const ObjCIvarDecl* , unsigned> IvarGroupNumber;
+    // This container maps an <class, group number for ivar> tuple to the type
+    // of the struct where the bitfield belongs.
+    llvm::DenseMap<std::pair<const ObjCInterfaceDecl*, unsigned>, QualType> GroupRecordType;
+    SmallVector<FunctionDecl*, 32> FunctionDefinitionsSeen;
+    
+    // This maps an original source AST to it's rewritten form. This allows
+    // us to avoid rewriting the same node twice (which is very uncommon).
+    // This is needed to support some of the exotic property rewriting.
+    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
+
+    // Needed for header files being rewritten
+    bool IsHeader;
+    bool SilenceRewriteMacroWarning;
+    bool GenerateLineInfo;
+    bool objc_impl_method;
+    
+    bool DisableReplaceStmt;
+    class DisableReplaceStmtScope {
+      RewriteModernObjC &R;
+      bool SavedValue;
+    
+    public:
+      DisableReplaceStmtScope(RewriteModernObjC &R)
+        : R(R), SavedValue(R.DisableReplaceStmt) {
+        R.DisableReplaceStmt = true;
+      }
+      ~DisableReplaceStmtScope() {
+        R.DisableReplaceStmt = SavedValue;
+      }
+    };
+    void InitializeCommon(ASTContext &context);
+
+  public:
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    // Top Level Driver code.
+    bool HandleTopLevelDecl(DeclGroupRef D) override {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
+          if (!Class->isThisDeclarationADefinition()) {
+            RewriteForwardClassDecl(D);
+            break;
+          } else {
+            // Keep track of all interface declarations seen.
+            ObjCInterfacesSeen.push_back(Class);
+            break;
+          }
+        }
+
+        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
+          if (!Proto->isThisDeclarationADefinition()) {
+            RewriteForwardProtocolDecl(D);
+            break;
+          }
+        }
+
+        if (FunctionDecl *FDecl = dyn_cast<FunctionDecl>(*I)) {
+          // Under modern abi, we cannot translate body of the function
+          // yet until all class extensions and its implementation is seen.
+          // This is because they may introduce new bitfields which must go
+          // into their grouping struct.
+          if (FDecl->isThisDeclarationADefinition() &&
+              // Not c functions defined inside an objc container.
+              !FDecl->isTopLevelDeclInObjCContainer()) {
+            FunctionDefinitionsSeen.push_back(FDecl);
+            break;
+          }
+        }
+        HandleTopLevelSingleDecl(*I);
+      }
+      return true;
+    }
+
+    void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+        if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(*I)) {
+          if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+            RewriteBlockPointerDecl(TD);
+          else if (TD->getUnderlyingType()->isFunctionPointerType())
+            CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+          else
+            RewriteObjCQualifiedInterfaceTypes(TD);
+        }
+      }
+      return;
+    }
+    
+    void HandleTopLevelSingleDecl(Decl *D);
+    void HandleDeclInMainFile(Decl *D);
+    RewriteModernObjC(std::string inFile, raw_ostream *OS,
+                DiagnosticsEngine &D, const LangOptions &LOpts,
+                bool silenceMacroWarn, bool LineInfo);
+    
+    ~RewriteModernObjC() {}
+
+    void HandleTranslationUnit(ASTContext &C) override;
+
+    void ReplaceStmt(Stmt *Old, Stmt *New) {
+      ReplaceStmtWithRange(Old, New, Old->getSourceRange());
+    }
+
+    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's");
+
+      Stmt *ReplacingStmt = ReplacedNodes[Old];
+      if (ReplacingStmt)
+        return; // We can't rewrite the same node twice.
+
+      if (DisableReplaceStmt)
+        return;
+
+      // Measure the old text.
+      int Size = Rewrite.getRangeSize(SrcRange);
+      if (Size == -1) {
+        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                     << Old->getSourceRange();
+        return;
+      }
+      // Get the new text.
+      std::string SStr;
+      llvm::raw_string_ostream S(SStr);
+      New->printPretty(S, nullptr, PrintingPolicy(LangOpts));
+      const std::string &Str = S.str();
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void InsertText(SourceLocation Loc, StringRef Str,
+                    bool InsertAfter = true) {
+      // If insertion succeeded or warning disabled return with no warning.
+      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     StringRef Str) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+
+    // Syntactic Rewriting.
+    void RewriteRecordBody(RecordDecl *RD);
+    void RewriteInclude();
+    void RewriteLineDirective(const Decl *D);
+    void ConvertSourceLocationToLineDirective(SourceLocation Loc,
+                                              std::string &LineString);
+    void RewriteForwardClassDecl(DeclGroupRef D);
+    void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
+                                     const std::string &typedefString);
+    void RewriteImplementations();
+    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                 ObjCImplementationDecl *IMD,
+                                 ObjCCategoryImplDecl *CID);
+    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
+    void RewriteImplementationDecl(Decl *Dcl);
+    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                               ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                               const FunctionType *&FPRetType);
+    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
+                            ValueDecl *VD, bool def=false);
+    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
+    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
+    void RewriteForwardProtocolDecl(DeclGroupRef D);
+    void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
+    void RewriteProperty(ObjCPropertyDecl *prop);
+    void RewriteFunctionDecl(FunctionDecl *FD);
+    void RewriteBlockPointerType(std::string& Str, QualType Type);
+    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
+    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteTypeOfDecl(VarDecl *VD);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+    
+    std::string getIvarAccessString(ObjCIvarDecl *D);
+  
+    // Expression Rewriting.
+    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
+    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
+    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+    Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
+    Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
+    Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
+    Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
+    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+    Stmt *RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S);
+    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
+    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                       SourceLocation OrigEnd);
+    Stmt *RewriteBreakStmt(BreakStmt *S);
+    Stmt *RewriteContinueStmt(ContinueStmt *S);
+    void RewriteCastExpr(CStyleCastExpr *CE);
+    void RewriteImplicitCastObjCExpr(CastExpr *IE);
+    void RewriteLinkageSpec(LinkageSpecDecl *LSD);
+    
+    // Computes ivar bitfield group no.
+    unsigned ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV);
+    // Names field decl. for ivar bitfield group.
+    void ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV, std::string &Result);
+    // Names struct type for ivar bitfield group.
+    void ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV, std::string &Result);
+    // Names symbol for ivar bitfield group field offset.
+    void ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV, std::string &Result);
+    // Given an ivar bitfield, it builds (or finds) its group record type.
+    QualType GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV);
+    QualType SynthesizeBitfieldGroupStructType(
+                                    ObjCIvarDecl *IV,
+                                    SmallVectorImpl<ObjCIvarDecl *> &IVars);
+    
+    // Block rewriting.
+    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
+    
+    // Block specific rewrite rules.
+    void RewriteBlockPointerDecl(NamedDecl *VD);
+    void RewriteByRefVar(VarDecl *VD, bool firstDecl, bool lastDecl);
+    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
+    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
+    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+    
+    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                      std::string &Result);
+    
+    void RewriteObjCFieldDecl(FieldDecl *fieldDecl, std::string &Result);
+    bool IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, TagDecl *Tag,
+                                 bool &IsNamedDefinition);
+    void RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
+                                              std::string &Result);
+    
+    bool RewriteObjCFieldDeclType(QualType &Type, std::string &Result);
+    
+    void RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
+                                  std::string &Result);
+
+    void Initialize(ASTContext &context) override;
+
+    // Misc. AST transformation routines. Sometimes they end up calling
+    // rewriting routines on the new ASTs.
+    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+                                           Expr **args, unsigned nargs,
+                                           SourceLocation StartLoc=SourceLocation(),
+                                           SourceLocation EndLoc=SourceLocation());
+    
+    Expr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                        QualType returnType, 
+                                        SmallVectorImpl<QualType> &ArgTypes,
+                                        SmallVectorImpl<Expr*> &MsgExprs,
+                                        ObjCMethodDecl *Method);
+
+    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
+                           SourceLocation StartLoc=SourceLocation(),
+                           SourceLocation EndLoc=SourceLocation());
+    
+    void SynthCountByEnumWithState(std::string &buf);
+    void SynthMsgSendFunctionDecl();
+    void SynthMsgSendSuperFunctionDecl();
+    void SynthMsgSendStretFunctionDecl();
+    void SynthMsgSendFpretFunctionDecl();
+    void SynthMsgSendSuperStretFunctionDecl();
+    void SynthGetClassFunctionDecl();
+    void SynthGetMetaClassFunctionDecl();
+    void SynthGetSuperClassFunctionDecl();
+    void SynthSelGetUidFunctionDecl();
+    void SynthSuperConstructorFunctionDecl();
+    
+    // Rewriting metadata
+    template<typename MethodIterator>
+    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                    MethodIterator MethodEnd,
+                                    bool IsInstanceMethod,
+                                    StringRef prefix,
+                                    StringRef ClassName,
+                                    std::string &Result);
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     std::string &Result);
+    void RewriteObjCProtocolListMetaData(
+                   const ObjCList<ObjCProtocolDecl> &Prots,
+                   StringRef prefix, StringRef ClassName, std::string &Result);
+    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                          std::string &Result);
+    void RewriteClassSetupInitHook(std::string &Result);
+    
+    void RewriteMetaDataIntoBuffer(std::string &Result);
+    void WriteImageInfo(std::string &Result);
+    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                             std::string &Result);
+    void RewriteCategorySetupInitHook(std::string &Result);
+    
+    // Rewriting ivar
+    void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                              std::string &Result);
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV);
+
+    
+    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
+    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockImpl(BlockExpr *CE, 
+                                    std::string Tag, std::string Desc);
+    std::string SynthesizeBlockDescriptor(std::string DescTag, 
+                                          std::string ImplTag,
+                                          int i, StringRef funcName,
+                                          unsigned hasCopy);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 StringRef FunName);
+    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
+    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
+                      const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
+
+    // Misc. helper routines.
+    QualType getProtocolType();
+    void WarnAboutReturnGotoStmts(Stmt *S);
+    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+
+    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
+    void CollectBlockDeclRefInfo(BlockExpr *Exp);
+    void GetBlockDeclRefExprs(Stmt *S);
+    void GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
+
+    // We avoid calling Type::isBlockPointerType(), since it operates on the
+    // canonical type. We only care if the top-level type is a closure pointer.
+    bool isTopLevelBlockPointerType(QualType T) {
+      return isa<BlockPointerType>(T);
+    }
+
+    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
+    /// to a function pointer type and upon success, returns true; false
+    /// otherwise.
+    bool convertBlockPointerToFunctionPointer(QualType &T) {
+      if (isTopLevelBlockPointerType(T)) {
+        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
+        T = Context->getPointerType(BPT->getPointeeType());
+        return true;
+      }
+      return false;
+    }
+    
+    bool convertObjCTypeToCStyleType(QualType &T);
+    
+    bool needToScanForQualifiers(QualType T);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
+    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
+    
+    void convertToUnqualifiedObjCType(QualType &T) {
+      if (T->isObjCQualifiedIdType()) {
+        bool isConst = T.isConstQualified();
+        T = isConst ? Context->getObjCIdType().withConst() 
+                    : Context->getObjCIdType();
+      }
+      else if (T->isObjCQualifiedClassType())
+        T = Context->getObjCClassType();
+      else if (T->isObjCObjectPointerType() &&
+               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
+        if (const ObjCObjectPointerType * OBJPT =
+              T->getAsObjCInterfacePointerType()) {
+          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
+          T = QualType(IFaceT, 0);
+          T = Context->getPointerType(T);
+        }
+     }
+    }
+    
+    // FIXME: This predicate seems like it would be useful to add to ASTContext.
+    bool isObjCType(QualType T) {
+      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+        return false;
+
+      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+
+      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+          OCT == Context->getCanonicalType(Context->getObjCClassType()))
+        return true;
+
+      if (const PointerType *PT = OCT->getAs<PointerType>()) {
+        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
+            PT->getPointeeType()->isObjCQualifiedIdType())
+          return true;
+      }
+      return false;
+    }
+    bool PointerTypeTakesAnyBlockArguments(QualType QT);
+    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
+    void GetExtentOfArgList(const char *Name, const char *&LParen,
+                            const char *&RParen);
+    
+    void QuoteDoublequotes(std::string &From, std::string &To) {
+      for (unsigned i = 0; i < From.length(); i++) {
+        if (From[i] == '"')
+          To += "\\\"";
+        else
+          To += From[i];
+      }
+    }
+
+    QualType getSimpleFunctionType(QualType result,
+                                   ArrayRef<QualType> args,
+                                   bool variadic = false) {
+      if (result == Context->getObjCInstanceType())
+        result =  Context->getObjCIdType();
+      FunctionProtoType::ExtProtoInfo fpi;
+      fpi.Variadic = variadic;
+      return Context->getFunctionType(result, args, fpi);
+    }
+
+    // Helper function: create a CStyleCastExpr with trivial type source info.
+    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
+                                             CastKind Kind, Expr *E) {
+      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
+      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr,
+                                    TInfo, SourceLocation(), SourceLocation());
+    }
+    
+    bool ImplementationIsNonLazy(const ObjCImplDecl *OD) const {
+      IdentifierInfo* II = &Context->Idents.get("load");
+      Selector LoadSel = Context->Selectors.getSelector(0, &II);
+      return OD->getClassMethod(LoadSel) != nullptr;
+    }
+
+    StringLiteral *getStringLiteral(StringRef Str) {
+      QualType StrType = Context->getConstantArrayType(
+          Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal,
+          0);
+      return StringLiteral::Create(*Context, Str, StringLiteral::Ascii,
+                                   /*Pascal=*/false, StrType, SourceLocation());
+    }
+  };
+  
+}
+
+void RewriteModernObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
+                                                   NamedDecl *D) {
+  if (const FunctionProtoType *fproto
+      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
+    for (const auto &I : fproto->param_types())
+      if (isTopLevelBlockPointerType(I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteModernObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAs<PointerType>();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false;
+  }
+
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}
+
+RewriteModernObjC::RewriteModernObjC(std::string inFile, raw_ostream* OS,
+                         DiagnosticsEngine &D, const LangOptions &LOpts,
+                         bool silenceMacroWarn,
+                         bool LineInfo)
+      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
+        SilenceRewriteMacroWarning(silenceMacroWarn), GenerateLineInfo(LineInfo) {
+  IsHeader = IsHeaderFile(inFile);
+  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+               "rewriting sub-expression within a macro (may not be correct)");
+  // FIXME. This should be an error. But if block is not called, it is OK. And it
+  // may break including some headers.
+  GlobalBlockRewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+    "rewriting block literal declared in global scope is not implemented");
+          
+  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
+               DiagnosticsEngine::Warning,
+               "rewriter doesn't support user-specified control flow semantics "
+               "for @try/@finally (code may not execute properly)");
+}
+
+std::unique_ptr<ASTConsumer> clang::CreateModernObjCRewriter(
+    const std::string &InFile, raw_ostream *OS, DiagnosticsEngine &Diags,
+    const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo) {
+  return llvm::make_unique<RewriteModernObjC>(
+      InFile, OS, Diags, LOpts, SilenceRewriteMacroWarning, LineInfo);
+}
+
+void RewriteModernObjC::InitializeCommon(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  TUDecl = Context->getTranslationUnitDecl();
+  MsgSendFunctionDecl = nullptr;
+  MsgSendSuperFunctionDecl = nullptr;
+  MsgSendStretFunctionDecl = nullptr;
+  MsgSendSuperStretFunctionDecl = nullptr;
+  MsgSendFpretFunctionDecl = nullptr;
+  GetClassFunctionDecl = nullptr;
+  GetMetaClassFunctionDecl = nullptr;
+  GetSuperClassFunctionDecl = nullptr;
+  SelGetUidFunctionDecl = nullptr;
+  CFStringFunctionDecl = nullptr;
+  ConstantStringClassReference = nullptr;
+  NSStringRecord = nullptr;
+  CurMethodDef = nullptr;
+  CurFunctionDef = nullptr;
+  GlobalVarDecl = nullptr;
+  GlobalConstructionExp = nullptr;
+  SuperStructDecl = nullptr;
+  ProtocolTypeDecl = nullptr;
+  ConstantStringDecl = nullptr;
+  BcLabelCount = 0;
+  SuperConstructorFunctionDecl = nullptr;
+  NumObjCStringLiterals = 0;
+  PropParentMap = nullptr;
+  CurrentBody = nullptr;
+  DisableReplaceStmt = false;
+  objc_impl_method = false;
+
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+
+  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteModernObjC::HandleTopLevelSingleDecl(Decl *D) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getExpansionLoc(Loc);
+
+  // If this is for a builtin, ignore it.
+  if (Loc.isInvalid()) return;
+
+  // Look for built-in declarations that we need to refer during the rewrite.
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    RewriteFunctionDecl(FD);
+  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (FVD->getName() == "_NSConstantStringClassReference") {
+      ConstantStringClassReference = FVD;
+      return;
+    }
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+    RewriteCategoryDecl(CD);
+  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+    if (PD->isThisDeclarationADefinition())
+      RewriteProtocolDecl(PD);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    // FIXME. This will not work in all situations and leaving it out
+    // is harmless.
+    // RewriteLinkageSpec(LSD);
+    
+    // Recurse into linkage specifications
+    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+                                 DIEnd = LSD->decls_end();
+         DI != DIEnd; ) {
+      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
+        if (!IFace->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = IFace->getLocStart();
+          do {
+            if (isa<ObjCInterfaceDecl>(*DI) &&
+                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardClassDecl(DG);
+          continue;
+        }
+        else {
+          // Keep track of all interface declarations seen.
+          ObjCInterfacesSeen.push_back(IFace);
+          ++DI;
+          continue;
+        }
+      }
+
+      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
+        if (!Proto->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = Proto->getLocStart();
+          do {
+            if (isa<ObjCProtocolDecl>(*DI) &&
+                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardProtocolDecl(DG);
+          continue;
+        }
+      }
+      
+      HandleTopLevelSingleDecl(*DI);
+      ++DI;
+    }
+  }
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isWrittenInMainFile(Loc))
+    return HandleDeclInMainFile(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Syntactic (non-AST) Rewriting Code
+//===----------------------------------------------------------------------===//
+
+void RewriteModernObjC::RewriteInclude() {
+  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
+  StringRef MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.begin();
+  const char *MainBufEnd = MainBuf.end();
+  size_t ImportLen = strlen("import");
+
+  // Loop over the whole file, looking for includes.
+  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
+    if (*BufPtr == '#') {
+      if (++BufPtr == MainBufEnd)
+        return;
+      while (*BufPtr == ' ' || *BufPtr == '\t')
+        if (++BufPtr == MainBufEnd)
+          return;
+      if (!strncmp(BufPtr, "import", ImportLen)) {
+        // replace import with include
+        SourceLocation ImportLoc =
+          LocStart.getLocWithOffset(BufPtr-MainBufStart);
+        ReplaceText(ImportLoc, ImportLen, "include");
+        BufPtr += ImportLen;
+      }
+    }
+  }
+}
+
+static void WriteInternalIvarName(const ObjCInterfaceDecl *IDecl,
+                                  ObjCIvarDecl *IvarDecl, std::string &Result) {
+  Result += "OBJC_IVAR_$_";
+  Result += IDecl->getName();
+  Result += "$";
+  Result += IvarDecl->getName();
+}
+
+std::string 
+RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) {
+  const ObjCInterfaceDecl *ClassDecl = D->getContainingInterface();
+  
+  // Build name of symbol holding ivar offset.
+  std::string IvarOffsetName;
+  if (D->isBitField())
+    ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
+  else
+    WriteInternalIvarName(ClassDecl, D, IvarOffsetName);
+  
+  
+  std::string S = "(*(";
+  QualType IvarT = D->getType();
+  if (D->isBitField())
+    IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
+  
+  if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
+    RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
+    RD = RD->getDefinition();
+    if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
+      // decltype(((Foo_IMPL*)0)->bar) *
+      ObjCContainerDecl *CDecl = 
+      dyn_cast<ObjCContainerDecl>(D->getDeclContext());
+      // ivar in class extensions requires special treatment.
+      if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
+        CDecl = CatDecl->getClassInterface();
+      std::string RecName = CDecl->getName();
+      RecName += "_IMPL";
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          &Context->Idents.get(RecName.c_str()));
+      QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
+      unsigned UnsignedIntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+      Expr *Zero = IntegerLiteral::Create(*Context,
+                                          llvm::APInt(UnsignedIntSize, 0),
+                                          Context->UnsignedIntTy, SourceLocation());
+      Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
+      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                              Zero);
+      FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                        SourceLocation(),
+                                        &Context->Idents.get(D->getNameAsString()),
+                                        IvarT, nullptr,
+                                        /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                        ICIS_NoInit);
+      MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                                FD->getType(), VK_LValue,
+                                                OK_Ordinary);
+      IvarT = Context->getDecltypeType(ME, ME->getType());
+    }
+  }
+  convertObjCTypeToCStyleType(IvarT);
+  QualType castT = Context->getPointerType(IvarT);
+  std::string TypeString(castT.getAsString(Context->getPrintingPolicy()));
+  S += TypeString;
+  S += ")";
+  
+  // ((char *)self + IVAR_OFFSET_SYMBOL_NAME)
+  S += "((char *)self + ";
+  S += IvarOffsetName;
+  S += "))";
+  if (D->isBitField()) {
+    S += ".";
+    S += D->getNameAsString();
+  }
+  ReferencedIvars[const_cast<ObjCInterfaceDecl *>(ClassDecl)].insert(D);
+  return S;
+}
+
+/// mustSynthesizeSetterGetterMethod - returns true if setter or getter has not
+/// been found in the class implementation. In this case, it must be synthesized.
+static bool mustSynthesizeSetterGetterMethod(ObjCImplementationDecl *IMP,
+                                             ObjCPropertyDecl *PD,
+                                             bool getter) {
+  return getter ? !IMP->getInstanceMethod(PD->getGetterName())
+                : !IMP->getInstanceMethod(PD->getSetterName());
+  
+}
+
+void RewriteModernObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                          ObjCImplementationDecl *IMD,
+                                          ObjCCategoryImplDecl *CID) {
+  static bool objcGetPropertyDefined = false;
+  static bool objcSetPropertyDefined = false;
+  SourceLocation startGetterSetterLoc;
+  
+  if (PID->getLocStart().isValid()) {
+    SourceLocation startLoc = PID->getLocStart();
+    InsertText(startLoc, "// ");
+    const char *startBuf = SM->getCharacterData(startLoc);
+    assert((*startBuf == '@') && "bogus @synthesize location");
+    const char *semiBuf = strchr(startBuf, ';');
+    assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+    startGetterSetterLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
+  }
+  else
+    startGetterSetterLoc = IMD ? IMD->getLocEnd() : CID->getLocEnd();
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+
+  // Generate the 'getter' function.
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+  assert(IMD && OID && "Synthesized ivars must be attached to @implementation");
+
+  unsigned Attributes = PD->getPropertyAttributes();
+  if (mustSynthesizeSetterGetterMethod(IMD, PD, true /*getter*/)) {
+    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                         ObjCPropertyDecl::OBJC_PR_copy));
+    std::string Getr;
+    if (GenGetProperty && !objcGetPropertyDefined) {
+      objcGetPropertyDefined = true;
+      // FIXME. Is this attribute correct in all cases?
+      Getr = "\nextern \"C\" __declspec(dllimport) "
+            "id objc_getProperty(id, SEL, long, bool);\n";
+    }
+    RewriteObjCMethodDecl(OID->getContainingInterface(),  
+                          PD->getGetterMethodDecl(), Getr);
+    Getr += "{ ";
+    // Synthesize an explicit cast to gain access to the ivar.
+    // See objc-act.c:objc_synthesize_new_getter() for details.
+    if (GenGetProperty) {
+      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
+      Getr += "typedef ";
+      const FunctionType *FPRetType = nullptr;
+      RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr,
+                            FPRetType);
+      Getr += " _TYPE";
+      if (FPRetType) {
+        Getr += ")"; // close the precedence "scope" for "*".
+      
+        // Now, emit the argument types (if any).
+        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
+          Getr += "(";
+          for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+            if (i) Getr += ", ";
+            std::string ParamStr =
+                FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+            Getr += ParamStr;
+          }
+          if (FT->isVariadic()) {
+            if (FT->getNumParams())
+              Getr += ", ";
+            Getr += "...";
+          }
+          Getr += ")";
+        } else
+          Getr += "()";
+      }
+      Getr += ";\n";
+      Getr += "return (_TYPE)";
+      Getr += "objc_getProperty(self, _cmd, ";
+      RewriteIvarOffsetComputation(OID, Getr);
+      Getr += ", 1)";
+    }
+    else
+      Getr += "return " + getIvarAccessString(OID);
+    Getr += "; }";
+    InsertText(startGetterSetterLoc, Getr);
+  }
+  
+  if (PD->isReadOnly() || 
+      !mustSynthesizeSetterGetterMethod(IMD, PD, false /*setter*/))
+    return;
+
+  // Generate the 'setter' function.
+  std::string Setr;
+  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                      ObjCPropertyDecl::OBJC_PR_copy);
+  if (GenSetProperty && !objcSetPropertyDefined) {
+    objcSetPropertyDefined = true;
+    // FIXME. Is this attribute correct in all cases?
+    Setr = "\nextern \"C\" __declspec(dllimport) "
+    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
+  }
+  
+  RewriteObjCMethodDecl(OID->getContainingInterface(), 
+                        PD->getSetterMethodDecl(), Setr);
+  Setr += "{ ";
+  // Synthesize an explicit cast to initialize the ivar.
+  // See objc-act.c:objc_synthesize_new_setter() for details.
+  if (GenSetProperty) {
+    Setr += "objc_setProperty (self, _cmd, ";
+    RewriteIvarOffsetComputation(OID, Setr);
+    Setr += ", (id)";
+    Setr += PD->getName();
+    Setr += ", ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
+      Setr += "0, ";
+    else
+      Setr += "1, ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
+      Setr += "1)";
+    else
+      Setr += "0)";
+  }
+  else {
+    Setr += getIvarAccessString(OID) + " = ";
+    Setr += PD->getName();
+  }
+  Setr += "; }\n";
+  InsertText(startGetterSetterLoc, Setr);
+}
+
+static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
+                                       std::string &typedefString) {
+  typedefString += "\n#ifndef _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "#define _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "typedef struct objc_object ";
+  typedefString += ForwardDecl->getNameAsString();
+  // typedef struct { } _objc_exc_Classname;
+  typedefString += ";\ntypedef struct {} _objc_exc_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += ";\n#endif\n";
+}
+
+void RewriteModernObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
+                                              const std::string &typedefString) {
+    SourceLocation startLoc = ClassDecl->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *semiPtr = strchr(startBuf, ';'); 
+    // Replace the @class with typedefs corresponding to the classes.
+    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
+}
+
+void RewriteModernObjC::RewriteForwardClassDecl(DeclGroupRef D) {
+  std::string typedefString;
+  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+    if (ObjCInterfaceDecl *ForwardDecl = dyn_cast<ObjCInterfaceDecl>(*I)) {
+      if (I == D.begin()) {
+        // Translate to typedef's that forward reference structs with the same name
+        // as the class. As a convenience, we include the original declaration
+        // as a comment.
+        typedefString += "// @class ";
+        typedefString += ForwardDecl->getNameAsString();
+        typedefString += ";";
+      }
+      RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+    }
+    else
+      HandleTopLevelSingleDecl(*I);
+  }
+  DeclGroupRef::iterator I = D.begin();
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
+}
+
+void RewriteModernObjC::RewriteForwardClassDecl(
+                                const SmallVectorImpl<Decl *> &D) {
+  std::string typedefString;
+  for (unsigned i = 0; i < D.size(); i++) {
+    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
+    if (i == 0) {
+      typedefString += "// @class ";
+      typedefString += ForwardDecl->getNameAsString();
+      typedefString += ";";
+    }
+    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+  }
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
+}
+
+void RewriteModernObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
+  // When method is a synthesized one, such as a getter/setter there is
+  // nothing to rewrite.
+  if (Method->isImplicit())
+    return;
+  SourceLocation LocStart = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+
+  if (SM->getExpansionLineNumber(LocEnd) >
+      SM->getExpansionLineNumber(LocStart)) {
+    InsertText(LocStart, "#if 0\n");
+    ReplaceText(LocEnd, 1, ";\n#endif\n");
+  } else {
+    InsertText(LocStart, "// ");
+  }
+}
+
+void RewriteModernObjC::RewriteProperty(ObjCPropertyDecl *prop) {
+  SourceLocation Loc = prop->getAtLoc();
+
+  ReplaceText(Loc, 0, "// ");
+  // FIXME: handle properties that are declared across multiple lines.
+}
+
+void RewriteModernObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  SourceLocation LocStart = CatDecl->getLocStart();
+
+  // FIXME: handle category headers that are declared across multiple lines.
+  if (CatDecl->getIvarRBraceLoc().isValid()) {
+    ReplaceText(LocStart, 1, "/** ");
+    ReplaceText(CatDecl->getIvarRBraceLoc(), 1, "**/ ");
+  }
+  else {
+    ReplaceText(LocStart, 0, "// ");
+  }
+  
+  for (auto *I : CatDecl->properties())
+    RewriteProperty(I);
+  
+  for (auto *I : CatDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : CatDecl->class_methods())
+    RewriteMethodDeclaration(I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
+              strlen("@end"), "/* @end */\n");
+}
+
+void RewriteModernObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocStart();
+  assert(PDecl->isThisDeclarationADefinition());
+  
+  // FIXME: handle protocol headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (auto *I : PDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->class_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->properties())
+    RewriteProperty(I);
+  
+  // Lastly, comment out the @end.
+  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
+  ReplaceText(LocEnd, strlen("@end"), "/* @end */\n");
+
+  // Must comment out @optional/@required
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  for (const char *p = startBuf; p < endBuf; p++) {
+    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
+
+    }
+    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
+
+    }
+  }
+}
+
+void RewriteModernObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
+  SourceLocation LocStart = (*D.begin())->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void 
+RewriteModernObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {
+  SourceLocation LocStart = DG[0]->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void 
+RewriteModernObjC::RewriteLinkageSpec(LinkageSpecDecl *LSD) {
+  SourceLocation LocStart = LSD->getExternLoc();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid extern SourceLocation");
+  
+  ReplaceText(LocStart, 0, "// ");
+  if (!LSD->hasBraces())
+    return;
+  // FIXME. We don't rewrite well if '{' is not on same line as 'extern'.
+  SourceLocation LocRBrace = LSD->getRBraceLoc();
+  if (LocRBrace.isInvalid())
+    llvm_unreachable("Invalid rbrace SourceLocation");
+  ReplaceText(LocRBrace, 0, "// ");
+}
+
+void RewriteModernObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                                        const FunctionType *&FPRetType) {
+  if (T->isObjCQualifiedIdType())
+    ResultStr += "id";
+  else if (T->isFunctionPointerType() ||
+           T->isBlockPointerType()) {
+    // needs special handling, since pointer-to-functions have special
+    // syntax (where a decaration models use).
+    QualType retType = T;
+    QualType PointeeTy;
+    if (const PointerType* PT = retType->getAs<PointerType>())
+      PointeeTy = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
+      PointeeTy = BPT->getPointeeType();
+    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
+      ResultStr +=
+          FPRetType->getReturnType().getAsString(Context->getPrintingPolicy());
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += T.getAsString(Context->getPrintingPolicy());
+}
+
+void RewriteModernObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                                        ObjCMethodDecl *OMD,
+                                        std::string &ResultStr) {
+  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+  const FunctionType *FPRetType = nullptr;
+  ResultStr += "\nstatic ";
+  RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType);
+  ResultStr += " ";
+
+  // Unique method name
+  std::string NameStr;
+
+  if (OMD->isInstanceMethod())
+    NameStr += "_I_";
+  else
+    NameStr += "_C_";
+
+  NameStr += IDecl->getNameAsString();
+  NameStr += "_";
+
+  if (ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+    NameStr += CID->getNameAsString();
+    NameStr += "_";
+  }
+  // Append selector names, replacing ':' with '_'
+  {
+    std::string selString = OMD->getSelector().getAsString();
+    int len = selString.size();
+    for (int i = 0; i < len; i++)
+      if (selString[i] == ':')
+        selString[i] = '_';
+    NameStr += selString;
+  }
+  // Remember this name for metadata emission
+  MethodInternalNames[OMD] = NameStr;
+  ResultStr += NameStr;
+
+  // Rewrite arguments
+  ResultStr += "(";
+
+  // invisible arguments
+  if (OMD->isInstanceMethod()) {
+    QualType selfTy = Context->getObjCInterfaceType(IDecl);
+    selfTy = Context->getPointerType(selfTy);
+    if (!LangOpts.MicrosoftExt) {
+      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
+        ResultStr += "struct ";
+    }
+    // When rewriting for Microsoft, explicitly omit the structure name.
+    ResultStr += IDecl->getNameAsString();
+    ResultStr += " *";
+  }
+  else
+    ResultStr += Context->getObjCClassType().getAsString(
+      Context->getPrintingPolicy());
+
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
+  ResultStr += " _cmd";
+
+  // Method arguments.
+  for (const auto *PDecl : OMD->params()) {
+    ResultStr += ", ";
+    if (PDecl->getType()->isObjCQualifiedIdType()) {
+      ResultStr += "id ";
+      ResultStr += PDecl->getNameAsString();
+    } else {
+      std::string Name = PDecl->getNameAsString();
+      QualType QT = PDecl->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      ResultStr += Name;
+    }
+  }
+  if (OMD->isVariadic())
+    ResultStr += ", ...";
+  ResultStr += ") ";
+
+  if (FPRetType) {
+    ResultStr += ")"; // close the precedence "scope" for "*".
+
+    // Now, emit the argument types (if any).
+    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+      ResultStr += "(";
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+        if (i) ResultStr += ", ";
+        std::string ParamStr =
+            FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+        ResultStr += ParamStr;
+      }
+      if (FT->isVariadic()) {
+        if (FT->getNumParams())
+          ResultStr += ", ";
+        ResultStr += "...";
+      }
+      ResultStr += ")";
+    } else {
+      ResultStr += "()";
+    }
+  }
+}
+void RewriteModernObjC::RewriteImplementationDecl(Decl *OID) {
+  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
+  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
+
+  if (IMD) {
+    if (IMD->getIvarRBraceLoc().isValid()) {
+      ReplaceText(IMD->getLocStart(), 1, "/** ");
+      ReplaceText(IMD->getIvarRBraceLoc(), 1, "**/ ");
+    }
+    else {
+      InsertText(IMD->getLocStart(), "// ");
+    }
+  }
+  else
+    InsertText(CID->getLocStart(), "// ");
+
+  for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+
+  for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+  for (auto *I : IMD ? IMD->property_impls() : CID->property_impls())
+    RewritePropertyImplDecl(I, IMD, CID);
+
+  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
+}
+
+void RewriteModernObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(ClassDecl))
+    return;
+  // Make sure super class's are written before current class is written.
+  ObjCInterfaceDecl *SuperClass = ClassDecl->getSuperClass();
+  while (SuperClass) {
+    RewriteInterfaceDecl(SuperClass);
+    SuperClass = SuperClass->getSuperClass();
+  }
+  std::string ResultStr;
+  if (!ObjCWrittenInterfaces.count(ClassDecl->getCanonicalDecl())) {
+    // we haven't seen a forward decl - generate a typedef.
+    RewriteOneForwardClassDecl(ClassDecl, ResultStr);
+    RewriteIvarOffsetSymbols(ClassDecl, ResultStr);
+    
+    RewriteObjCInternalStruct(ClassDecl, ResultStr);
+    // Mark this typedef as having been written into its c++ equivalent.
+    ObjCWrittenInterfaces.insert(ClassDecl->getCanonicalDecl());
+  
+    for (auto *I : ClassDecl->properties())
+      RewriteProperty(I);
+    for (auto *I : ClassDecl->instance_methods())
+      RewriteMethodDeclaration(I);
+    for (auto *I : ClassDecl->class_methods())
+      RewriteMethodDeclaration(I);
+
+    // Lastly, comment out the @end.
+    ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
+                "/* @end */\n");
+  }
+}
+
+Stmt *RewriteModernObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
+                            PseudoOp->getNumSemanticExprs() - 1));
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base;
+  SmallVector<Expr*, 2> Args;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    Base = nullptr;
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+  
+    unsigned numArgs = OldMsg->getNumArgs();
+    for (unsigned i = 0; i < numArgs; i++) {
+      Expr *Arg = OldMsg->getArg(i);
+      if (isa<OpaqueValueExpr>(Arg))
+        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
+      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
+      Args.push_back(Arg);
+    }
+  }
+
+  // TODO: avoid this copy.
+  SmallVector<SourceLocation, 1> SelLocs;
+  OldMsg->getSelectorLocs(SelLocs);
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+Stmt *RewriteModernObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base = nullptr;
+  SmallVector<Expr*, 1> Args;
+  {
+    DisableReplaceStmtScope S(*this);
+    // Rebuild the base expression if we have one.
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+    unsigned numArgs = OldMsg->getNumArgs();
+    for (unsigned i = 0; i < numArgs; i++) {
+      Expr *Arg = OldMsg->getArg(i);
+      if (isa<OpaqueValueExpr>(Arg))
+        Arg = cast<OpaqueValueExpr>(Arg)->getSourceExpr();
+      Arg = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Arg));
+      Args.push_back(Arg);
+    }
+  }
+
+  // Intentionally empty.
+  SmallVector<SourceLocation, 1> SelLocs;
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+/// SynthCountByEnumWithState - To print:
+/// ((NSUInteger (*)
+///  (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger))
+///  (void *)objc_msgSend)((id)l_collection,
+///                        sel_registerName(
+///                          "countByEnumeratingWithState:objects:count:"),
+///                        &enumState,
+///                        (id *)__rw_items, (NSUInteger)16)
+///
+void RewriteModernObjC::SynthCountByEnumWithState(std::string &buf) {
+  buf += "((_WIN_NSUInteger (*) (id, SEL, struct __objcFastEnumerationState *, "
+  "id *, _WIN_NSUInteger))(void *)objc_msgSend)";
+  buf += "\n\t\t";
+  buf += "((id)l_collection,\n\t\t";
+  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
+  buf += "\n\t\t";
+  buf += "&enumState, "
+         "(id *)__rw_items, (_WIN_NSUInteger)16)";
+}
+
+/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
+/// statement to exit to its outer synthesized loop.
+///
+Stmt *RewriteModernObjC::RewriteBreakStmt(BreakStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace break with goto __break_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("break"), buf);
+
+  return nullptr;
+}
+
+void RewriteModernObjC::ConvertSourceLocationToLineDirective(
+                                          SourceLocation Loc,
+                                          std::string &LineString) {
+  if (Loc.isFileID() && GenerateLineInfo) {
+    LineString += "\n#line ";
+    PresumedLoc PLoc = SM->getPresumedLoc(Loc);
+    LineString += utostr(PLoc.getLine());
+    LineString += " \"";
+    LineString += Lexer::Stringify(PLoc.getFilename());
+    LineString += "\"\n";
+  }
+}
+
+/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
+/// statement to continue with its inner synthesized loop.
+///
+Stmt *RewriteModernObjC::RewriteContinueStmt(ContinueStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace continue with goto __continue_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("continue"), buf);
+
+  return nullptr;
+}
+
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
+///  It rewrites:
+/// for ( type elem in collection) { stmts; }
+
+/// Into:
+/// {
+///   type elem;
+///   struct __objcFastEnumerationState enumState = { 0 };
+///   id __rw_items[16];
+///   id l_collection = (id)collection;
+///   NSUInteger limit = [l_collection countByEnumeratingWithState:&enumState
+///                                       objects:__rw_items count:16];
+/// if (limit) {
+///   unsigned long startMutations = *enumState.mutationsPtr;
+///   do {
+///        unsigned long counter = 0;
+///        do {
+///             if (startMutations != *enumState.mutationsPtr)
+///               objc_enumerationMutation(l_collection);
+///             elem = (type)enumState.itemsPtr[counter++];
+///             stmts;
+///             __continue_label: ;
+///        } while (counter < limit);
+///   } while ((limit = [l_collection countByEnumeratingWithState:&enumState
+///                                  objects:__rw_items count:16]));
+///   elem = nil;
+///   __break_label: ;
+///  }
+///  else
+///       elem = nil;
+///  }
+///
+Stmt *RewriteModernObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                                SourceLocation OrigEnd) {
+  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
+  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
+         "ObjCForCollectionStmt Statement stack mismatch");
+  assert(!ObjCBcLabelNo.empty() &&
+         "ObjCForCollectionStmt - Label No stack empty");
+
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  StringRef elementName;
+  std::string elementTypeAsString;
+  std::string buf;
+  // line directive first.
+  SourceLocation ForEachLoc = S->getForLoc();
+  ConvertSourceLocationToLineDirective(ForEachLoc, buf);
+  buf += "{\n\t";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
+    // type elem;
+    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
+    QualType ElementType = cast<ValueDecl>(D)->getType();
+    if (ElementType->isObjCQualifiedIdType() ||
+        ElementType->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getName();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getName();
+    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+    if (VD->getType()->isObjCQualifiedIdType() ||
+        VD->getType()->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
+  }
+
+  // struct __objcFastEnumerationState enumState = { 0 };
+  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
+  // id __rw_items[16];
+  buf += "id __rw_items[16];\n\t";
+  // id l_collection = (id)
+  buf += "id l_collection = (id)";
+  // Find start location of 'collection' the hard way!
+  const char *startCollectionBuf = startBuf;
+  startCollectionBuf += 3;  // skip 'for'
+  startCollectionBuf = strchr(startCollectionBuf, '(');
+  startCollectionBuf++; // skip '('
+  // find 'in' and skip it.
+  while (*startCollectionBuf != ' ' ||
+         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
+         (*(startCollectionBuf+3) != ' ' &&
+          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
+    startCollectionBuf++;
+  startCollectionBuf += 3;
+
+  // Replace: "for (type element in" with string constructed thus far.
+  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
+  // Replace ')' in for '(' type elem in collection ')' with ';'
+  SourceLocation rightParenLoc = S->getRParenLoc();
+  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
+  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
+  buf = ";\n\t";
+
+  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+  //                                   objects:__rw_items count:16];
+  // which is synthesized into:
+  // NSUInteger limit =
+  // ((NSUInteger (*)
+  //  (id, SEL, struct __objcFastEnumerationState *, id *, NSUInteger))
+  //  (void *)objc_msgSend)((id)l_collection,
+  //                        sel_registerName(
+  //                          "countByEnumeratingWithState:objects:count:"),
+  //                        (struct __objcFastEnumerationState *)&state,
+  //                        (id *)__rw_items, (NSUInteger)16);
+  buf += "_WIN_NSUInteger limit =\n\t\t";
+  SynthCountByEnumWithState(buf);
+  buf += ";\n\t";
+  /// if (limit) {
+  ///   unsigned long startMutations = *enumState.mutationsPtr;
+  ///   do {
+  ///        unsigned long counter = 0;
+  ///        do {
+  ///             if (startMutations != *enumState.mutationsPtr)
+  ///               objc_enumerationMutation(l_collection);
+  ///             elem = (type)enumState.itemsPtr[counter++];
+  buf += "if (limit) {\n\t";
+  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
+  buf += "do {\n\t\t";
+  buf += "unsigned long counter = 0;\n\t\t";
+  buf += "do {\n\t\t\t";
+  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
+  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
+  buf += elementName;
+  buf += " = (";
+  buf += elementTypeAsString;
+  buf += ")enumState.itemsPtr[counter++];";
+  // Replace ')' in for '(' type elem in collection ')' with all of these.
+  ReplaceText(lparenLoc, 1, buf);
+
+  ///            __continue_label: ;
+  ///        } while (counter < limit);
+  ///   } while ((limit = [l_collection countByEnumeratingWithState:&enumState
+  ///                                  objects:__rw_items count:16]));
+  ///   elem = nil;
+  ///   __break_label: ;
+  ///  }
+  ///  else
+  ///       elem = nil;
+  ///  }
+  ///
+  buf = ";\n\t";
+  buf += "__continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;";
+  buf += "\n\t\t";
+  buf += "} while (counter < limit);\n\t";
+  buf += "} while ((limit = ";
+  SynthCountByEnumWithState(buf);
+  buf += "));\n\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "__break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;\n\t";
+  buf += "}\n\t";
+  buf += "else\n\t\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "}\n";
+
+  // Insert all these *after* the statement body.
+  // FIXME: If this should support Obj-C++, support CXXTryStmt
+  if (isa<CompoundStmt>(S->getBody())) {
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
+    InsertText(endBodyLoc, buf);
+  } else {
+    /* Need to treat single statements specially. For example:
+     *
+     *     for (A *a in b) if (stuff()) break;
+     *     for (A *a in b) xxxyy;
+     *
+     * The following code simply scans ahead to the semi to find the actual end.
+     */
+    const char *stmtBuf = SM->getCharacterData(OrigEnd);
+    const char *semiBuf = strchr(stmtBuf, ';');
+    assert(semiBuf && "Can't find ';'");
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
+    InsertText(endBodyLoc, buf);
+  }
+  Stmts.pop_back();
+  ObjCBcLabelNo.pop_back();
+  return nullptr;
+}
+
+static void Write_RethrowObject(std::string &buf) {
+  buf += "{ struct _FIN { _FIN(id reth) : rethrow(reth) {}\n";
+  buf += "\t~_FIN() { if (rethrow) objc_exception_throw(rethrow); }\n";
+  buf += "\tid rethrow;\n";
+  buf += "\t} _fin_force_rethow(_rethrow);";
+}
+
+/// RewriteObjCSynchronizedStmt -
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteModernObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @synchronized location");
+
+  std::string buf;
+  SourceLocation SynchLoc = S->getAtSynchronizedLoc();
+  ConvertSourceLocationToLineDirective(SynchLoc, buf);
+  buf += "{ id _rethrow = 0; id _sync_obj = (id)";
+  
+  const char *lparenBuf = startBuf;
+  while (*lparenBuf != '(') lparenBuf++;
+  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
+  
+  buf = "; objc_sync_enter(_sync_obj);\n";
+  buf += "try {\n\tstruct _SYNC_EXIT { _SYNC_EXIT(id arg) : sync_exit(arg) {}";
+  buf += "\n\t~_SYNC_EXIT() {objc_sync_exit(sync_exit);}";
+  buf += "\n\tid sync_exit;";
+  buf += "\n\t} _sync_exit(_sync_obj);\n";
+
+  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
+  // the sync expression is typically a message expression that's already
+  // been rewritten! (which implies the SourceLocation's are invalid).
+  SourceLocation RParenExprLoc = S->getSynchBody()->getLocStart();
+  const char *RParenExprLocBuf = SM->getCharacterData(RParenExprLoc);
+  while (*RParenExprLocBuf != ')') RParenExprLocBuf--;
+  RParenExprLoc = startLoc.getLocWithOffset(RParenExprLocBuf-startBuf);
+  
+  SourceLocation LBranceLoc = S->getSynchBody()->getLocStart();
+  const char *LBraceLocBuf = SM->getCharacterData(LBranceLoc);
+  assert (*LBraceLocBuf == '{');
+  ReplaceText(RParenExprLoc, (LBraceLocBuf - SM->getCharacterData(RParenExprLoc) + 1), buf);
+  
+  SourceLocation startRBraceLoc = S->getSynchBody()->getLocEnd();
+  assert((*SM->getCharacterData(startRBraceLoc) == '}') &&
+         "bogus @synchronized block");
+  
+  buf = "} catch (id e) {_rethrow = e;}\n";
+  Write_RethrowObject(buf);
+  buf += "}\n";
+  buf += "}\n";
+
+  ReplaceText(startRBraceLoc, 1, buf);
+
+  return nullptr;
+}
+
+void RewriteModernObjC::WarnAboutReturnGotoStmts(Stmt *S)
+{
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI)
+      WarnAboutReturnGotoStmts(*CI);
+
+  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
+    Diags.Report(Context->getFullLoc(S->getLocStart()),
+                 TryFinallyContainsReturnDiag);
+  }
+  return;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCAutoreleasePoolStmt(ObjCAutoreleasePoolStmt  *S) {
+  SourceLocation startLoc = S->getAtLoc();
+  ReplaceText(startLoc, strlen("@autoreleasepool"), "/* @autoreleasepool */");
+  ReplaceText(S->getSubStmt()->getLocStart(), 1, 
+              "{ __AtAutoreleasePool __autoreleasepool; ");
+
+  return nullptr;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+  ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt();
+  bool noCatch = S->getNumCatchStmts() == 0;
+  std::string buf;
+  SourceLocation TryLocation = S->getAtTryLoc();
+  ConvertSourceLocationToLineDirective(TryLocation, buf);
+  
+  if (finalStmt) {
+    if (noCatch)
+      buf += "{ id volatile _rethrow = 0;\n";
+    else {
+      buf += "{ id volatile _rethrow = 0;\ntry {\n";
+    }
+  }
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @try location");
+  if (finalStmt)
+    ReplaceText(startLoc, 1, buf);
+  else
+    // @try -> try
+    ReplaceText(startLoc, 1, "");
+  
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+    VarDecl *catchDecl = Catch->getCatchParamDecl();
+    
+    startLoc = Catch->getLocStart();
+    bool AtRemoved = false;
+    if (catchDecl) {
+      QualType t = catchDecl->getType();
+      if (const ObjCObjectPointerType *Ptr = t->getAs<ObjCObjectPointerType>()) {
+        // Should be a pointer to a class.
+        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
+        if (IDecl) {
+          std::string Result;
+          ConvertSourceLocationToLineDirective(Catch->getLocStart(), Result);
+          
+          startBuf = SM->getCharacterData(startLoc);
+          assert((*startBuf == '@') && "bogus @catch location");
+          SourceLocation rParenLoc = Catch->getRParenLoc();
+          const char *rParenBuf = SM->getCharacterData(rParenLoc);
+          
+          // _objc_exc_Foo *_e as argument to catch.
+          Result += "catch (_objc_exc_"; Result += IDecl->getNameAsString();
+          Result += " *_"; Result += catchDecl->getNameAsString();
+          Result += ")";
+          ReplaceText(startLoc, rParenBuf-startBuf+1, Result);
+          // Foo *e = (Foo *)_e;
+          Result.clear();
+          Result = "{ ";
+          Result += IDecl->getNameAsString();
+          Result += " *"; Result += catchDecl->getNameAsString();
+          Result += " = ("; Result += IDecl->getNameAsString(); Result += "*)";
+          Result += "_"; Result += catchDecl->getNameAsString();
+          
+          Result += "; ";
+          SourceLocation lBraceLoc = Catch->getCatchBody()->getLocStart();
+          ReplaceText(lBraceLoc, 1, Result);
+          AtRemoved = true;
+        }
+      }
+    }
+    if (!AtRemoved)
+      // @catch -> catch
+      ReplaceText(startLoc, 1, "");
+      
+  }
+  if (finalStmt) {
+    buf.clear();
+    SourceLocation FinallyLoc = finalStmt->getLocStart();
+    
+    if (noCatch) {
+      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
+      buf += "catch (id e) {_rethrow = e;}\n";
+    }
+    else {
+      buf += "}\n";
+      ConvertSourceLocationToLineDirective(FinallyLoc, buf);
+      buf += "catch (id e) {_rethrow = e;}\n";
+    }
+    
+    SourceLocation startFinalLoc = finalStmt->getLocStart();
+    ReplaceText(startFinalLoc, 8, buf);
+    Stmt *body = finalStmt->getFinallyBody();
+    SourceLocation startFinalBodyLoc = body->getLocStart();
+    buf.clear();
+    Write_RethrowObject(buf);
+    ReplaceText(startFinalBodyLoc, 1, buf);
+    
+    SourceLocation endFinalBodyLoc = body->getLocEnd();
+    ReplaceText(endFinalBodyLoc, 1, "}\n}");
+    // Now check for any return/continue/go statements within the @try.
+    WarnAboutReturnGotoStmts(S->getTryBody());
+  }
+
+  return nullptr;
+}
+
+// This can't be done with ReplaceStmt(S, ThrowExpr), since
+// the throw expression is typically a message expression that's already
+// been rewritten! (which implies the SourceLocation's are invalid).
+Stmt *RewriteModernObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @throw location");
+
+  std::string buf;
+  /* void objc_exception_throw(id) __attribute__((noreturn)); */
+  if (S->getThrowExpr())
+    buf = "objc_exception_throw(";
+  else
+    buf = "throw";
+
+  // handle "@  throw" correctly.
+  const char *wBuf = strchr(startBuf, 'w');
+  assert((*wBuf == 'w') && "@throw: can't find 'w'");
+  ReplaceText(startLoc, wBuf-startBuf+1, buf);
+
+  SourceLocation endLoc = S->getLocEnd();
+  const char *endBuf = SM->getCharacterData(endLoc);
+  const char *semiBuf = strchr(endBuf, ';');
+  assert((*semiBuf == ';') && "@throw: can't find ';'");
+  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
+  if (S->getThrowExpr())
+    ReplaceText(semiLoc, 1, ");");
+  return nullptr;
+}
+
+Stmt *RewriteModernObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
+  // Create a new string expression.
+  std::string StrEncoding;
+  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = getStringLiteral(StrEncoding);
+  ReplaceStmt(Exp, Replacement);
+
+  // Replace this subexpr in the parent.
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return Replacement;
+}
+
+Stmt *RewriteModernObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
+  // Create a call to sel_registerName("selName").
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  ReplaceStmt(Exp, SelExp);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return SelExp;
+}
+
+CallExpr *RewriteModernObjC::SynthesizeCallToFunctionDecl(
+  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
+                                                    SourceLocation EndLoc) {
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = FD->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE =
+    new (Context) DeclRefExpr(FD, false, msgSendType, VK_LValue, SourceLocation());
+
+  // Now, we cast the reference to a pointer to the objc_msgSend type.
+  QualType pToFunc = Context->getPointerType(msgSendType);
+  ImplicitCastExpr *ICE = 
+    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
+                             DRE, nullptr, VK_RValue);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+
+  CallExpr *Exp =  
+    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
+                           FT->getCallResultType(*Context),
+                           VK_RValue, EndLoc);
+  return Exp;
+}
+
+static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
+                                const char *&startRef, const char *&endRef) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '<')
+      startRef = startBuf; // mark the start.
+    if (*startBuf == '>') {
+      if (startRef && *startRef == '<') {
+        endRef = startBuf; // mark the end.
+        return true;
+      }
+      return false;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+static void scanToNextArgument(const char *&argRef) {
+  int angle = 0;
+  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
+    if (*argRef == '<')
+      angle++;
+    else if (*argRef == '>')
+      angle--;
+    argRef++;
+  }
+  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
+}
+
+bool RewriteModernObjC::needToScanForQualifiers(QualType T) {
+  if (T->isObjCQualifiedIdType())
+    return true;
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    if (PT->getPointeeType()->isObjCQualifiedIdType())
+      return true;
+  }
+  if (T->isObjCObjectPointerType()) {
+    T = T->getPointeeType();
+    return T->isObjCQualifiedInterfaceType();
+  }
+  if (T->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(T);
+    return needToScanForQualifiers(ElemTy);
+  }
+  return false;
+}
+
+void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
+  QualType Type = E->getType();
+  if (needToScanForQualifiers(Type)) {
+    SourceLocation Loc, EndLoc;
+
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
+      Loc = ECE->getLParenLoc();
+      EndLoc = ECE->getRParenLoc();
+    } else {
+      Loc = E->getLocStart();
+      EndLoc = E->getLocEnd();
+    }
+    // This will defend against trying to rewrite synthesized expressions.
+    if (Loc.isInvalid() || EndLoc.isInvalid())
+      return;
+
+    const char *startBuf = SM->getCharacterData(Loc);
+    const char *endBuf = SM->getCharacterData(EndLoc);
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+}
+
+void RewriteModernObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
+  SourceLocation Loc;
+  QualType Type;
+  const FunctionProtoType *proto = nullptr;
+  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
+    Loc = VD->getLocation();
+    Type = VD->getType();
+  }
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    // Check for ObjC 'id' and class types that have been adorned with protocol
+    // information (id<p>, C<p>*). The protocol references need to be rewritten!
+    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+    assert(funcType && "missing function type");
+    proto = dyn_cast<FunctionProtoType>(funcType);
+    if (!proto)
+      return;
+    Type = proto->getReturnType();
+  }
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    Type = FD->getType();
+  }
+  else if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(Dcl)) {
+    Loc = TD->getLocation();
+    Type = TD->getUnderlyingType();
+  }
+  else
+    return;
+
+  if (needToScanForQualifiers(Type)) {
+    // Since types are unique, we need to scan the buffer.
+
+    const char *endBuf = SM->getCharacterData(Loc);
+    const char *startBuf = endBuf;
+    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
+      startBuf--; // scan backward (from the decl location) for return type.
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+  if (!proto)
+      return; // most likely, was a variable
+  // Now check arguments.
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *startFuncBuf = startBuf;
+  for (unsigned i = 0; i < proto->getNumParams(); i++) {
+    if (needToScanForQualifiers(proto->getParamType(i))) {
+      // Since types are unique, we need to scan the buffer.
+
+      const char *endBuf = startBuf;
+      // scan forward (from the decl location) for argument types.
+      scanToNextArgument(endBuf);
+      const char *startRef = nullptr, *endRef = nullptr;
+      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+        // Get the locations of the startRef, endRef.
+        SourceLocation LessLoc =
+          Loc.getLocWithOffset(startRef-startFuncBuf);
+        SourceLocation GreaterLoc =
+          Loc.getLocWithOffset(endRef-startFuncBuf+1);
+        // Comment out the protocol references.
+        InsertText(LessLoc, "/*");
+        InsertText(GreaterLoc, "*/");
+      }
+      startBuf = ++endBuf;
+    }
+    else {
+      // If the function name is derived from a macro expansion, then the
+      // argument buffer will not follow the name. Need to speak with Chris.
+      while (*startBuf && *startBuf != ')' && *startBuf != ',')
+        startBuf++; // scan forward (from the decl location) for argument types.
+      startBuf++;
+    }
+  }
+}
+
+void RewriteModernObjC::RewriteTypeOfDecl(VarDecl *ND) {
+  QualType QT = ND->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (!isa<TypeOfExprType>(TypePtr))
+    return;
+  while (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    TypePtr = QT->getAs<Type>();
+  }
+  // FIXME. This will not work for multiple declarators; as in:
+  // __typeof__(a) b,c,d;
+  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  if (ND->getInit()) {
+    std::string Name(ND->getNameAsString());
+    TypeAsString += " " + Name + " = ";
+    Expr *E = ND->getInit();
+    SourceLocation startLoc;
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    const char *endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+  else {
+    SourceLocation X = ND->getLocEnd();
+    X = SM->getExpansionLoc(X);
+    const char *endBuf = SM->getCharacterData(X);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+}
+
+// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
+void RewriteModernObjC::SynthSelGetUidFunctionDecl() {
+  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getFuncType =
+    getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                               SourceLocation(),
+                                               SourceLocation(),
+                                               SelGetUidIdent, getFuncType,
+                                               nullptr, SC_Extern);
+}
+
+void RewriteModernObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      FD->getName() == "sel_registerName") {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+void RewriteModernObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  if (!strchr(argPtr, '^')) {
+    Str += TypeString;
+    return;
+  }
+  while (*argPtr) {
+    Str += (*argPtr == '^' ? '*' : *argPtr);
+    argPtr++;
+  }
+}
+
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+void RewriteModernObjC::RewriteBlockPointerTypeVariable(std::string& Str,
+                                                  ValueDecl *VD) {
+  QualType Type = VD->getType();
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  int paren = 0;
+  while (*argPtr) {
+    switch (*argPtr) {
+      case '(':
+        Str += *argPtr;
+        paren++;
+        break;
+      case ')':
+        Str += *argPtr;
+        paren--;
+        break;
+      case '^':
+        Str += '*';
+        if (paren == 1)
+          Str += VD->getNameAsString();
+        break;
+      default:
+        Str += *argPtr;
+        break;
+    }
+    argPtr++;
+  }
+}
+
+void RewriteModernObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
+  if (!proto)
+    return;
+  QualType Type = proto->getReturnType();
+  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
+  FdStr += " ";
+  FdStr += FD->getName();
+  FdStr +=  "(";
+  unsigned numArgs = proto->getNumParams();
+  for (unsigned i = 0; i < numArgs; i++) {
+    QualType ArgType = proto->getParamType(i);
+  RewriteBlockPointerType(FdStr, ArgType);
+  if (i+1 < numArgs)
+    FdStr += ", ";
+  }
+  if (FD->isVariadic()) {
+    FdStr +=  (numArgs > 0) ? ", ...);\n" : "...);\n";
+  }
+  else
+    FdStr +=  ");\n";
+  InsertText(FunLocStart, FdStr);
+}
+
+// SynthSuperConstructorFunctionDecl - id __rw_objc_super(id obj, id super);
+void RewriteModernObjC::SynthSuperConstructorFunctionDecl() {
+  if (SuperConstructorFunctionDecl)
+    return;
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys);
+  SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                     SourceLocation(),
+                                                     SourceLocation(),
+                                                     msgSendIdent, msgSendType,
+                                                     nullptr, SC_Extern);
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteModernObjC::SynthMsgSendFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                             SourceLocation(),
+                                             SourceLocation(),
+                                             msgSendIdent, msgSendType, nullptr,
+                                             SC_Extern);
+}
+
+// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(void);
+void RewriteModernObjC::SynthMsgSendSuperFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
+  SmallVector<QualType, 2> ArgTys;
+  ArgTys.push_back(Context->VoidTy);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
+void RewriteModernObjC::SynthMsgSendStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendSuperStretFunctionDecl -
+// id objc_msgSendSuper_stret(void);
+void RewriteModernObjC::SynthMsgSendSuperStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent =
+    &Context->Idents.get("objc_msgSendSuper_stret");
+  SmallVector<QualType, 2> ArgTys;
+  ArgTys.push_back(Context->VoidTy);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                       SourceLocation(),
+                                                       SourceLocation(),
+                                                       msgSendIdent,
+                                                       msgSendType, nullptr,
+                                                       SC_Extern);
+}
+
+// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
+void RewriteModernObjC::SynthMsgSendFpretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthGetClassFunctionDecl - Class objc_getClass(const char *name);
+void RewriteModernObjC::SynthGetClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              SourceLocation(),
+                                              getClassIdent, getClassType,
+                                              nullptr, SC_Extern);
+}
+
+// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
+void RewriteModernObjC::SynthGetSuperClassFunctionDecl() {
+  IdentifierInfo *getSuperClassIdent = 
+    &Context->Idents.get("class_getSuperclass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getObjCClassType());
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   getSuperClassIdent,
+                                                   getClassType, nullptr,
+                                                   SC_Extern);
+}
+
+// SynthGetMetaClassFunctionDecl - Class objc_getMetaClass(const char *name);
+void RewriteModernObjC::SynthGetMetaClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  getClassIdent, getClassType,
+                                                  nullptr, SC_Extern);
+}
+
+Stmt *RewriteModernObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  assert (Exp != nullptr && "Expected non-null ObjCStringLiteral");
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+
+  std::string tmpName = InFileName;
+  unsigned i;
+  for (i=0; i < tmpName.length(); i++) {
+    char c = tmpName.at(i);
+    // replace any non-alphanumeric characters with '_'.
+    if (!isAlphanumeric(c))
+      tmpName[i] = '_';
+  }
+  S += tmpName;
+  S += "_";
+  S += utostr(NumObjCStringLiterals++);
+
+  Preamble += "static __NSConstantStringImpl " + S;
+  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
+  Preamble += "0x000007c8,"; // utf8_str
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::string prettyBufS;
+  llvm::raw_string_ostream prettyBuf(prettyBufS);
+  Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts));
+  Preamble += prettyBuf.str();
+  Preamble += ",";
+  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                   SourceLocation(), &Context->Idents.get(S),
+                                   strType, nullptr, SC_Static);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
+                                               SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                                 Context->getPointerType(DRE->getType()),
+                                           VK_RValue, OK_Ordinary,
+                                           SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
+                                            CK_CPointerToObjCPointerCast, Unop);
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return cast;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
+  unsigned IntSize =
+    static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  
+  Expr *FlagExp = IntegerLiteral::Create(*Context, 
+                                         llvm::APInt(IntSize, Exp->getValue()), 
+                                         Context->IntTy, Exp->getLocation());
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
+                                            CK_BitCast, FlagExp);
+  ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(), 
+                                          cast);
+  ReplaceStmt(Exp, PE);
+  return PE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 4> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  
+  // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument.
+  ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod();
+  ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface();
+  
+  IdentifierInfo *clsName = BoxingClass->getIdentifier();
+  ClsExprs.push_back(getStringLiteral(clsName->getName()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("<BoxingMethod>:"), etc.
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  SelExprs.push_back(
+      getStringLiteral(BoxingMethod->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // User provided sub-expression is the 3rd, and last, argument.
+  Expr *subExpr  = Exp->getSubExpr();
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) {
+    QualType type = ICE->getType();
+    const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+    CastKind CK = CK_BitCast;
+    if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
+      CK = CK_IntegralToBoolean;
+    subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
+  }
+  MsgExprs.push_back(subExpr);
+  
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (const auto PI : BoxingMethod->parameters())
+    ArgTypes.push_back(PI->getType());
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+    getSimpleFunctionType(returnType, ArgTypes, BoxingMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Build the expression: __NSContainer_literal(int, ...).arr
+  QualType IntQT = Context->IntTy;
+  QualType NSArrayFType =
+    getSimpleFunctionType(Context->VoidTy, IntQT, true);
+  std::string NSArrayFName("__NSContainer_literal");
+  FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
+  DeclRefExpr *NSArrayDRE = 
+    new (Context) DeclRefExpr(NSArrayFD, false, NSArrayFType, VK_RValue,
+                              SourceLocation());
+
+  SmallVector<Expr*, 16> InitExprs;
+  unsigned NumElements = Exp->getNumElements();
+  unsigned UnsignedIntSize = 
+    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+  Expr *count = IntegerLiteral::Create(*Context,
+                                       llvm::APInt(UnsignedIntSize, NumElements),
+                                       Context->UnsignedIntTy, SourceLocation());
+  InitExprs.push_back(count);
+  for (unsigned i = 0; i < NumElements; i++)
+    InitExprs.push_back(Exp->getElement(i));
+  Expr *NSArrayCallExpr = 
+    new (Context) CallExpr(*Context, NSArrayDRE, InitExprs,
+                           NSArrayFType, VK_LValue, SourceLocation());
+
+  FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("arr"),
+                                    Context->getPointerType(Context->VoidPtrTy),
+                                    nullptr, /*BitWidth=*/nullptr,
+                                    /*Mutable=*/true, ICIS_NoInit);
+  MemberExpr *ArrayLiteralME = 
+    new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD, 
+                             SourceLocation(),
+                             ARRFD->getType(), VK_LValue,
+                             OK_Ordinary);
+  QualType ConstIdT = Context->getObjCIdType().withConst();
+  CStyleCastExpr * ArrayLiteralObjects = 
+    NoTypeInfoCStyleCastExpr(Context, 
+                             Context->getPointerType(ConstIdT),
+                             CK_BitCast,
+                             ArrayLiteralME);
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 32> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  QualType expType = Exp->getType();
+  
+  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
+  ObjCInterfaceDecl *Class = 
+    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
+  
+  IdentifierInfo *clsName = Class->getIdentifier();
+  ClsExprs.push_back(getStringLiteral(clsName->getName()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("arrayWithObjects:count:").
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
+  SelExprs.push_back(
+      getStringLiteral(ArrayMethod->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // (const id [])objects
+  MsgExprs.push_back(ArrayLiteralObjects);
+  
+  // (NSUInteger)cnt
+  Expr *cnt = IntegerLiteral::Create(*Context,
+                                     llvm::APInt(UnsignedIntSize, NumElements),
+                                     Context->UnsignedIntTy, SourceLocation());
+  MsgExprs.push_back(cnt);
+  
+  
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (const auto *PI : ArrayMethod->params())
+    ArgTypes.push_back(PI->getType());
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+  getSimpleFunctionType(returnType, ArgTypes, ArrayMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Build the expression: __NSContainer_literal(int, ...).arr
+  QualType IntQT = Context->IntTy;
+  QualType NSDictFType =
+    getSimpleFunctionType(Context->VoidTy, IntQT, true);
+  std::string NSDictFName("__NSContainer_literal");
+  FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
+  DeclRefExpr *NSDictDRE = 
+    new (Context) DeclRefExpr(NSDictFD, false, NSDictFType, VK_RValue,
+                              SourceLocation());
+  
+  SmallVector<Expr*, 16> KeyExprs;
+  SmallVector<Expr*, 16> ValueExprs;
+  
+  unsigned NumElements = Exp->getNumElements();
+  unsigned UnsignedIntSize = 
+    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+  Expr *count = IntegerLiteral::Create(*Context,
+                                       llvm::APInt(UnsignedIntSize, NumElements),
+                                       Context->UnsignedIntTy, SourceLocation());
+  KeyExprs.push_back(count);
+  ValueExprs.push_back(count);
+  for (unsigned i = 0; i < NumElements; i++) {
+    ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
+    KeyExprs.push_back(Element.Key);
+    ValueExprs.push_back(Element.Value);
+  }
+  
+  // (const id [])objects
+  Expr *NSValueCallExpr = 
+    new (Context) CallExpr(*Context, NSDictDRE, ValueExprs,
+                           NSDictFType, VK_LValue, SourceLocation());
+
+  FieldDecl *ARRFD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                       SourceLocation(),
+                                       &Context->Idents.get("arr"),
+                                       Context->getPointerType(Context->VoidPtrTy),
+                                       nullptr, /*BitWidth=*/nullptr,
+                                       /*Mutable=*/true, ICIS_NoInit);
+  MemberExpr *DictLiteralValueME = 
+    new (Context) MemberExpr(NSValueCallExpr, false, ARRFD, 
+                             SourceLocation(),
+                             ARRFD->getType(), VK_LValue,
+                             OK_Ordinary);
+  QualType ConstIdT = Context->getObjCIdType().withConst();
+  CStyleCastExpr * DictValueObjects = 
+    NoTypeInfoCStyleCastExpr(Context, 
+                             Context->getPointerType(ConstIdT),
+                             CK_BitCast,
+                             DictLiteralValueME);
+  // (const id <NSCopying> [])keys
+  Expr *NSKeyCallExpr = 
+    new (Context) CallExpr(*Context, NSDictDRE, KeyExprs,
+                           NSDictFType, VK_LValue, SourceLocation());
+  
+  MemberExpr *DictLiteralKeyME = 
+    new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD, 
+                             SourceLocation(),
+                             ARRFD->getType(), VK_LValue,
+                             OK_Ordinary);
+  
+  CStyleCastExpr * DictKeyObjects = 
+    NoTypeInfoCStyleCastExpr(Context, 
+                             Context->getPointerType(ConstIdT),
+                             CK_BitCast,
+                             DictLiteralKeyME);
+  
+  
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 32> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  QualType expType = Exp->getType();
+  
+  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
+  ObjCInterfaceDecl *Class = 
+  expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
+  
+  IdentifierInfo *clsName = Class->getIdentifier();
+  ClsExprs.push_back(getStringLiteral(clsName->getName()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("arrayWithObjects:count:").
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
+  SelExprs.push_back(getStringLiteral(DictMethod->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // (const id [])objects
+  MsgExprs.push_back(DictValueObjects);
+  
+  // (const id <NSCopying> [])keys
+  MsgExprs.push_back(DictKeyObjects);
+  
+  // (NSUInteger)cnt
+  Expr *cnt = IntegerLiteral::Create(*Context,
+                                     llvm::APInt(UnsignedIntSize, NumElements),
+                                     Context->UnsignedIntTy, SourceLocation());
+  MsgExprs.push_back(cnt);
+  
+  
+  SmallVector<QualType, 8> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (const auto *PI : DictMethod->params()) {
+    QualType T = PI->getType();
+    if (const PointerType* PT = T->getAs<PointerType>()) {
+      QualType PointeeTy = PT->getPointeeType();
+      convertToUnqualifiedObjCType(PointeeTy);
+      T = Context->getPointerType(PointeeTy);
+    }
+    ArgTypes.push_back(T);
+  }
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+  getSimpleFunctionType(returnType, ArgTypes, DictMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+// struct __rw_objc_super { 
+//   struct objc_object *object; struct objc_object *superClass; 
+// };
+QualType RewriteModernObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                         SourceLocation(), SourceLocation(),
+                                         &Context->Idents.get("__rw_objc_super"));
+    QualType FieldTypes[2];
+
+    // struct objc_object *object;
+    FieldTypes[0] = Context->getObjCIdType();
+    // struct objc_object *superClass;
+    FieldTypes[1] = Context->getObjCIdType();
+
+    // Create fields
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
+                                                 SourceLocation(),
+                                                 SourceLocation(), nullptr,
+                                                 FieldTypes[i], nullptr,
+                                                 /*BitWidth=*/nullptr,
+                                                 /*Mutable=*/false,
+                                                 ICIS_NoInit));
+    }
+
+    SuperStructDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(SuperStructDecl);
+}
+
+QualType RewriteModernObjC::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                            SourceLocation(), SourceLocation(),
+                         &Context->Idents.get("__NSConstantStringImpl"));
+    QualType FieldTypes[4];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // int flags;
+    FieldTypes[1] = Context->IntTy;
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);
+    // long length;
+    FieldTypes[3] = Context->LongTy;
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
+                                                    ConstantStringDecl,
+                                                    SourceLocation(),
+                                                    SourceLocation(), nullptr,
+                                                    FieldTypes[i], nullptr,
+                                                    /*BitWidth=*/nullptr,
+                                                    /*Mutable=*/true,
+                                                    ICIS_NoInit));
+    }
+
+    ConstantStringDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
+/// getFunctionSourceLocation - returns start location of a function
+/// definition. Complication arises when function has declared as
+/// extern "C" or extern "C" {...}
+static SourceLocation getFunctionSourceLocation (RewriteModernObjC &R,
+                                                 FunctionDecl *FD) {
+  if (FD->isExternC()  && !FD->isMain()) {
+    const DeclContext *DC = FD->getDeclContext();
+    if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
+      // if it is extern "C" {...}, return function decl's own location.
+      if (!LSD->getRBraceLoc().isValid())
+        return LSD->getExternLoc();
+  }
+  if (FD->getStorageClass() != SC_None)
+    R.RewriteBlockLiteralFunctionDecl(FD);
+  return FD->getTypeSpecStartLoc();
+}
+
+void RewriteModernObjC::RewriteLineDirective(const Decl *D) {
+  
+  SourceLocation Location = D->getLocation();
+  
+  if (Location.isFileID() && GenerateLineInfo) {
+    std::string LineString("\n#line ");
+    PresumedLoc PLoc = SM->getPresumedLoc(Location);
+    LineString += utostr(PLoc.getLine());
+    LineString += " \"";
+    LineString += Lexer::Stringify(PLoc.getFilename());
+    if (isa<ObjCMethodDecl>(D))
+      LineString += "\"";
+    else LineString += "\"\n";
+    
+    Location = D->getLocStart();
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+      if (FD->isExternC()  && !FD->isMain()) {
+        const DeclContext *DC = FD->getDeclContext();
+        if (const LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(DC))
+          // if it is extern "C" {...}, return function decl's own location.
+          if (!LSD->getRBraceLoc().isValid())
+            Location = LSD->getExternLoc();
+      }
+    }
+    InsertText(Location, LineString);
+  }
+}
+
+/// SynthMsgSendStretCallExpr - This routine translates message expression
+/// into a call to objc_msgSend_stret() entry point. Tricky part is that
+/// nil check on receiver must be performed before calling objc_msgSend_stret.
+/// MsgSendStretFlavor - function declaration objc_msgSend_stret(...)
+/// msgSendType - function type of objc_msgSend_stret(...)
+/// returnType - Result type of the method being synthesized.
+/// ArgTypes - type of the arguments passed to objc_msgSend_stret, starting with receiver type.
+/// MsgExprs - list of argument expressions being passed to objc_msgSend_stret, 
+/// starting with receiver.
+/// Method - Method being rewritten.
+Expr *RewriteModernObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                                 QualType returnType, 
+                                                 SmallVectorImpl<QualType> &ArgTypes,
+                                                 SmallVectorImpl<Expr*> &MsgExprs,
+                                                 ObjCMethodDecl *Method) {
+  // Now do the "normal" pointer to function cast.
+  QualType castType = getSimpleFunctionType(returnType, ArgTypes,
+                                            Method ? Method->isVariadic()
+                                                   : false);
+  castType = Context->getPointerType(castType);
+  
+  // build type for containing the objc_msgSend_stret object.
+  static unsigned stretCount=0;
+  std::string name = "__Stret"; name += utostr(stretCount);
+  std::string str = 
+    "extern \"C\" void * __cdecl memset(void *_Dst, int _Val, size_t _Size);\n";
+  str += "namespace {\n";
+  str += "struct "; str += name;
+  str += " {\n\t";
+  str += name;
+  str += "(id receiver, SEL sel";
+  for (unsigned i = 2; i < ArgTypes.size(); i++) {
+    std::string ArgName = "arg"; ArgName += utostr(i);
+    ArgTypes[i].getAsStringInternal(ArgName, Context->getPrintingPolicy());
+    str += ", "; str += ArgName;
+  }
+  // could be vararg.
+  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
+    std::string ArgName = "arg"; ArgName += utostr(i);
+    MsgExprs[i]->getType().getAsStringInternal(ArgName,
+                                               Context->getPrintingPolicy());
+    str += ", "; str += ArgName;
+  }
+  
+  str += ") {\n";
+  str += "\t  unsigned size = sizeof(";
+  str += returnType.getAsString(Context->getPrintingPolicy()); str += ");\n";
+  
+  str += "\t  if (size == 1 || size == 2 || size == 4 || size == 8)\n";
+  
+  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
+  str += ")(void *)objc_msgSend)(receiver, sel";
+  for (unsigned i = 2; i < ArgTypes.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  // could be vararg.
+  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  str+= ");\n";
+  
+  str += "\t  else if (receiver == 0)\n";
+  str += "\t    memset((void*)&s, 0, sizeof(s));\n";
+  str += "\t  else\n";
+  
+  
+  str += "\t    s = (("; str += castType.getAsString(Context->getPrintingPolicy());
+  str += ")(void *)objc_msgSend_stret)(receiver, sel";
+  for (unsigned i = 2; i < ArgTypes.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  // could be vararg.
+  for (unsigned i = ArgTypes.size(); i < MsgExprs.size(); i++) {
+    str += ", arg"; str += utostr(i);
+  }
+  str += ");\n";
+  
+  
+  str += "\t}\n";
+  str += "\t"; str += returnType.getAsString(Context->getPrintingPolicy());
+  str += " s;\n";
+  str += "};\n};\n\n";
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+    FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
+  else {
+    assert(CurMethodDef && "SynthMsgSendStretCallExpr - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+
+  InsertText(FunLocStart, str);
+  ++stretCount;
+  
+  // AST for __Stretn(receiver, args).s;
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  FunctionDecl *FD = FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
+                                          SourceLocation(), ID, castType,
+                                          nullptr, SC_Extern, false, false);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, castType, VK_RValue,
+                                               SourceLocation());
+  CallExpr *STCE = new (Context) CallExpr(*Context, DRE, MsgExprs,
+                                          castType, VK_LValue, SourceLocation());
+
+  FieldDecl *FieldD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("s"),
+                                    returnType, nullptr,
+                                    /*BitWidth=*/nullptr,
+                                    /*Mutable=*/true, ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(STCE, false, FieldD, SourceLocation(),
+                                            FieldD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  return ME;
+}
+
+Stmt *RewriteModernObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!MsgSendSuperFunctionDecl)
+    SynthMsgSendSuperFunctionDecl();
+  if (!MsgSendStretFunctionDecl)
+    SynthMsgSendStretFunctionDecl();
+  if (!MsgSendSuperStretFunctionDecl)
+    SynthMsgSendSuperStretFunctionDecl();
+  if (!MsgSendFpretFunctionDecl)
+    SynthMsgSendFpretFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  if (!GetSuperClassFunctionDecl)
+    SynthGetSuperClassFunctionDecl();
+  if (!GetMetaClassFunctionDecl)
+    SynthGetMetaClassFunctionDecl();
+
+  // default to objc_msgSend().
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  // May need to use objc_msgSend_stret() as well.
+  FunctionDecl *MsgSendStretFlavor = nullptr;
+  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
+    QualType resultType = mDecl->getReturnType();
+    if (resultType->isRecordType())
+      MsgSendStretFlavor = MsgSendStretFunctionDecl;
+    else if (resultType->isRealFloatingType())
+      MsgSendFlavor = MsgSendFpretFunctionDecl;
+  }
+
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 8> MsgExprs;
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+    SmallVector<Expr*, 4> InitExprs;
+
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue,
+                                             SourceLocation()))
+                        ); // set the 'receiver'.
+
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    // (Class)objc_getClass("CurrentClass")
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    ClsExprs.clear();
+    ClsExprs.push_back(Cls);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CK_BitCast, Cls));
+    // struct __rw_objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue,
+                                        SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CK_BitCast, SuperRep);
+    } else {
+      // (struct __rw_objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_LValue,
+                                                   ILE, false);
+      // struct __rw_objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Class: {
+    SmallVector<Expr*, 8> ClsExprs;
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(getStringLiteral(clsName->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CK_BitCast, Cls);
+    MsgExprs.push_back(ArgExpr);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue, SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    // (Class)objc_getClass("CurrentClass")
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    ClsExprs.clear();
+    ClsExprs.push_back(Cls);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast, Cls));
+    // struct __rw_objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct __rw_objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               VK_RValue, OK_Ordinary,
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CK_BitCast, SuperRep);
+    } else {
+      // (struct __rw_objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_RValue, ILE,
+                                                   false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
+                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
+                                     ? CK_BlockPointerToObjCPointerCast
+                                     : CK_CPointerToObjCPointerCast;
+
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CK, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
+  }
+
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size(),
+                                                  StartLoc,
+                                                  EndLoc);
+  MsgExprs.push_back(SelExp);
+
+  // Now push any user supplied arguments.
+  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
+    Expr *userExpr = Exp->getArg(i);
+    // Make all implicit casts explicit...ICE comes in handy:-)
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+      // Reuse the ICE type, it is exactly what the doctor ordered.
+      QualType type = ICE->getType();
+      if (needToScanForQualifiers(type))
+        type = Context->getObjCIdType();
+      // Make sure we convert "type (^)(...)" to "type (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(type);
+      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+      CastKind CK;
+      if (SubExpr->getType()->isIntegralType(*Context) && 
+          type->isBooleanType()) {
+        CK = CK_IntegralToBoolean;
+      } else if (type->isObjCObjectPointerType()) {
+        if (SubExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (SubExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+      } else {
+        CK = CK_BitCast;
+      }
+
+      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
+    }
+    // Make id<P...> cast into an 'id' cast.
+    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
+      if (CE->getType()->isObjCQualifiedIdType()) {
+        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
+          userExpr = CE->getSubExpr();
+        CastKind CK;
+        if (userExpr->getType()->isIntegralType(*Context)) {
+          CK = CK_IntegralToPointer;
+        } else if (userExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (userExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                            CK, userExpr);
+      }
+    }
+    MsgExprs.push_back(userExpr);
+    // We've transferred the ownership to MsgExprs. For now, we *don't* null
+    // out the argument in the original expression (since we aren't deleting
+    // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
+    //Exp->setArg(i, 0);
+  }
+  // Generate the funky cast.
+  CastExpr *cast;
+  SmallVector<QualType, 8> ArgTypes;
+  QualType returnType;
+
+  // Push 'id' and 'SEL', the 2 implicit arguments.
+  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
+    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
+  else
+    ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
+    // Push any user argument types.
+    for (const auto *PI : OMD->params()) {
+      QualType t = PI->getType()->isObjCQualifiedIdType()
+                     ? Context->getObjCIdType()
+                     : PI->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(t);
+      ArgTypes.push_back(t);
+    }
+    returnType = Exp->getType();
+    convertToUnqualifiedObjCType(returnType);
+    (void)convertBlockPointerToFunctionPointer(returnType);
+  } else {
+    returnType = Context->getObjCIdType();
+  }
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+
+  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
+  // If we don't do this cast, we get the following bizarre warning/note:
+  // xx.m:13: warning: function called through a non-compatible type
+  // xx.m:13: note: if this code is reached, the program will abort
+  cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, DRE);
+
+  // Now do the "normal" pointer to function cast.
+  // If we don't have a method decl, force a variadic cast.
+  const ObjCMethodDecl *MD = Exp->getMethodDecl();
+  QualType castType =
+    getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true);
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  Stmt *ReplacingStmt = CE;
+  if (MsgSendStretFlavor) {
+    // We have the method which returns a struct/union. Must also generate
+    // call to objc_msgSend_stret and hang both varieties on a conditional
+    // expression which dictate which one to envoke depending on size of
+    // method's return type.
+
+    Expr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor,
+                                           returnType,
+                                           ArgTypes, MsgExprs,
+                                           Exp->getMethodDecl());
+    ReplacingStmt = STCE;
+  }
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+Stmt *RewriteModernObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
+  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
+                                         Exp->getLocEnd());
+
+  // Now do the actual rewrite.
+  ReplaceStmt(Exp, ReplacingStmt);
+
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+// typedef struct objc_object Protocol;
+QualType RewriteModernObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    TypeSourceInfo *TInfo
+      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), SourceLocation(),
+                                           &Context->Idents.get("Protocol"),
+                                           TInfo);
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
+/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteModernObjC::HandleTranslationUnit().
+Stmt *RewriteModernObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
+  std::string Name = "_OBJC_PROTOCOL_REFERENCE_$_" + 
+                      Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                SourceLocation(), ID, getProtocolType(),
+                                nullptr, SC_Extern);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+                                               VK_LValue, SourceLocation());
+  CastExpr *castExpr =
+    NoTypeInfoCStyleCastExpr(
+      Context, Context->getPointerType(DRE->getType()), CK_BitCast, DRE);
+  ReplaceStmt(Exp, castExpr);
+  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return castExpr;
+
+}
+
+bool RewriteModernObjC::BufferContainsPPDirectives(const char *startBuf,
+                                             const char *endBuf) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '#') {
+      // Skip whitespace.
+      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
+        ;
+      if (!strncmp(startBuf, "if", strlen("if")) ||
+          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
+          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
+          !strncmp(startBuf, "define", strlen("define")) ||
+          !strncmp(startBuf, "undef", strlen("undef")) ||
+          !strncmp(startBuf, "else", strlen("else")) ||
+          !strncmp(startBuf, "elif", strlen("elif")) ||
+          !strncmp(startBuf, "endif", strlen("endif")) ||
+          !strncmp(startBuf, "pragma", strlen("pragma")) ||
+          !strncmp(startBuf, "include", strlen("include")) ||
+          !strncmp(startBuf, "import", strlen("import")) ||
+          !strncmp(startBuf, "include_next", strlen("include_next")))
+        return true;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+/// IsTagDefinedInsideClass - This routine checks that a named tagged type 
+/// is defined inside an objective-c class. If so, it returns true. 
+bool RewriteModernObjC::IsTagDefinedInsideClass(ObjCContainerDecl *IDecl, 
+                                                TagDecl *Tag,
+                                                bool &IsNamedDefinition) {
+  if (!IDecl)
+    return false;
+  SourceLocation TagLocation;
+  if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) {
+    RD = RD->getDefinition();
+    if (!RD || !RD->getDeclName().getAsIdentifierInfo())
+      return false;
+    IsNamedDefinition = true;
+    TagLocation = RD->getLocation();
+    return Context->getSourceManager().isBeforeInTranslationUnit(
+                                          IDecl->getLocation(), TagLocation);
+  }
+  if (EnumDecl *ED = dyn_cast<EnumDecl>(Tag)) {
+    if (!ED || !ED->getDeclName().getAsIdentifierInfo())
+      return false;
+    IsNamedDefinition = true;
+    TagLocation = ED->getLocation();
+    return Context->getSourceManager().isBeforeInTranslationUnit(
+                                          IDecl->getLocation(), TagLocation);
+
+  }
+  return false;
+}
+
+/// RewriteObjCFieldDeclType - This routine rewrites a type into the buffer.
+/// It handles elaborated types, as well as enum types in the process.
+bool RewriteModernObjC::RewriteObjCFieldDeclType(QualType &Type, 
+                                                 std::string &Result) {
+  if (isa<TypedefType>(Type)) {
+    Result += "\t";
+    return false;
+  }
+    
+  if (Type->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(Type);
+    return RewriteObjCFieldDeclType(ElemTy, Result);
+  }
+  else if (Type->isRecordType()) {
+    RecordDecl *RD = Type->getAs<RecordType>()->getDecl();
+    if (RD->isCompleteDefinition()) {
+      if (RD->isStruct())
+        Result += "\n\tstruct ";
+      else if (RD->isUnion())
+        Result += "\n\tunion ";
+      else
+        assert(false && "class not allowed as an ivar type");
+      
+      Result += RD->getName();
+      if (GlobalDefinedTags.count(RD)) {
+        // struct/union is defined globally, use it.
+        Result += " ";
+        return true;
+      }
+      Result += " {\n";
+      for (auto *FD : RD->fields())
+        RewriteObjCFieldDecl(FD, Result);
+      Result += "\t} "; 
+      return true;
+    }
+  }
+  else if (Type->isEnumeralType()) {
+    EnumDecl *ED = Type->getAs<EnumType>()->getDecl();
+    if (ED->isCompleteDefinition()) {
+      Result += "\n\tenum ";
+      Result += ED->getName();
+      if (GlobalDefinedTags.count(ED)) {
+        // Enum is globall defined, use it.
+        Result += " ";
+        return true;
+      }
+      
+      Result += " {\n";
+      for (const auto *EC : ED->enumerators()) {
+        Result += "\t"; Result += EC->getName(); Result += " = ";
+        llvm::APSInt Val = EC->getInitVal();
+        Result += Val.toString(10);
+        Result += ",\n";
+      }
+      Result += "\t} "; 
+      return true;
+    }
+  }
+  
+  Result += "\t";
+  convertObjCTypeToCStyleType(Type);
+  return false;
+}
+
+
+/// RewriteObjCFieldDecl - This routine rewrites a field into the buffer.
+/// It handles elaborated types, as well as enum types in the process.
+void RewriteModernObjC::RewriteObjCFieldDecl(FieldDecl *fieldDecl, 
+                                             std::string &Result) {
+  QualType Type = fieldDecl->getType();
+  std::string Name = fieldDecl->getNameAsString();
+  
+  bool EleboratedType = RewriteObjCFieldDeclType(Type, Result); 
+  if (!EleboratedType)
+    Type.getAsStringInternal(Name, Context->getPrintingPolicy());
+  Result += Name;
+  if (fieldDecl->isBitField()) {
+    Result += " : "; Result += utostr(fieldDecl->getBitWidthValue(*Context));
+  }
+  else if (EleboratedType && Type->isArrayType()) {
+    const ArrayType *AT = Context->getAsArrayType(Type);
+    do {
+      if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) {
+        Result += "[";
+        llvm::APInt Dim = CAT->getSize();
+        Result += utostr(Dim.getZExtValue());
+        Result += "]";
+      }
+      AT = Context->getAsArrayType(AT->getElementType());
+    } while (AT);
+  }
+  
+  Result += ";\n";
+}
+
+/// RewriteLocallyDefinedNamedAggregates - This routine rewrites locally defined
+/// named aggregate types into the input buffer.
+void RewriteModernObjC::RewriteLocallyDefinedNamedAggregates(FieldDecl *fieldDecl, 
+                                             std::string &Result) {
+  QualType Type = fieldDecl->getType();
+  if (isa<TypedefType>(Type))
+    return;
+  if (Type->isArrayType())
+    Type = Context->getBaseElementType(Type);
+  ObjCContainerDecl *IDecl = 
+    dyn_cast<ObjCContainerDecl>(fieldDecl->getDeclContext());
+
+  TagDecl *TD = nullptr;
+  if (Type->isRecordType()) {
+    TD = Type->getAs<RecordType>()->getDecl();
+  }
+  else if (Type->isEnumeralType()) {
+    TD = Type->getAs<EnumType>()->getDecl();
+  }
+  
+  if (TD) {
+    if (GlobalDefinedTags.count(TD))
+      return;
+    
+    bool IsNamedDefinition = false;
+    if (IsTagDefinedInsideClass(IDecl, TD, IsNamedDefinition)) {
+      RewriteObjCFieldDeclType(Type, Result);
+      Result += ";";
+    }
+    if (IsNamedDefinition)
+      GlobalDefinedTags.insert(TD);
+  }
+    
+}
+
+unsigned RewriteModernObjC::ObjCIvarBitfieldGroupNo(ObjCIvarDecl *IV) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  if (ObjCInterefaceHasBitfieldGroups.count(CDecl)) {
+    return IvarGroupNumber[IV];
+  }
+  unsigned GroupNo = 0;
+  SmallVector<const ObjCIvarDecl *, 8> IVars;
+  for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+       IVD; IVD = IVD->getNextIvar())
+    IVars.push_back(IVD);
+  
+  for (unsigned i = 0, e = IVars.size(); i < e; i++)
+    if (IVars[i]->isBitField()) {
+      IvarGroupNumber[IVars[i++]] = ++GroupNo;
+      while (i < e && IVars[i]->isBitField())
+        IvarGroupNumber[IVars[i++]] = GroupNo;
+      if (i < e)
+        --i;
+    }
+
+  ObjCInterefaceHasBitfieldGroups.insert(CDecl);
+  return IvarGroupNumber[IV];
+}
+
+QualType RewriteModernObjC::SynthesizeBitfieldGroupStructType(
+                              ObjCIvarDecl *IV,
+                              SmallVectorImpl<ObjCIvarDecl *> &IVars) {
+  std::string StructTagName;
+  ObjCIvarBitfieldGroupType(IV, StructTagName);
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct,
+                                      Context->getTranslationUnitDecl(),
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get(StructTagName));
+  for (unsigned i=0, e = IVars.size(); i < e; i++) {
+    ObjCIvarDecl *Ivar = IVars[i];
+    RD->addDecl(FieldDecl::Create(*Context, RD, SourceLocation(), SourceLocation(),
+                                  &Context->Idents.get(Ivar->getName()),
+                                  Ivar->getType(),
+                                  nullptr, /*Expr *BW */Ivar->getBitWidth(),
+                                  false, ICIS_NoInit));
+  }
+  RD->completeDefinition();
+  return Context->getTagDeclType(RD);
+}
+
+QualType RewriteModernObjC::GetGroupRecordTypeForObjCIvarBitfield(ObjCIvarDecl *IV) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
+  std::pair<const ObjCInterfaceDecl*, unsigned> tuple = std::make_pair(CDecl, GroupNo);
+  if (GroupRecordType.count(tuple))
+    return GroupRecordType[tuple];
+  
+  SmallVector<ObjCIvarDecl *, 8> IVars;
+  for (const ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+       IVD; IVD = IVD->getNextIvar()) {
+    if (IVD->isBitField())
+      IVars.push_back(const_cast<ObjCIvarDecl *>(IVD));
+    else {
+      if (!IVars.empty()) {
+        unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
+        // Generate the struct type for this group of bitfield ivars.
+        GroupRecordType[std::make_pair(CDecl, GroupNo)] =
+          SynthesizeBitfieldGroupStructType(IVars[0], IVars);
+        IVars.clear();
+      }
+    }
+  }
+  if (!IVars.empty()) {
+    // Do the last one.
+    unsigned GroupNo = ObjCIvarBitfieldGroupNo(IVars[0]);
+    GroupRecordType[std::make_pair(CDecl, GroupNo)] =
+      SynthesizeBitfieldGroupStructType(IVars[0], IVars);
+  }
+  QualType RetQT = GroupRecordType[tuple];
+  assert(!RetQT.isNull() && "GetGroupRecordTypeForObjCIvarBitfield struct type is NULL");
+  
+  return RetQT;
+}
+
+/// ObjCIvarBitfieldGroupDecl - Names field decl. for ivar bitfield group.
+/// Name would be: classname__GRBF_n where n is the group number for this ivar.
+void RewriteModernObjC::ObjCIvarBitfieldGroupDecl(ObjCIvarDecl *IV,
+                                                  std::string &Result) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  Result += CDecl->getName();
+  Result += "__GRBF_";
+  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
+  Result += utostr(GroupNo);
+  return;
+}
+
+/// ObjCIvarBitfieldGroupType - Names struct type for ivar bitfield group.
+/// Name of the struct would be: classname__T_n where n is the group number for
+/// this ivar.
+void RewriteModernObjC::ObjCIvarBitfieldGroupType(ObjCIvarDecl *IV,
+                                                  std::string &Result) {
+  const ObjCInterfaceDecl *CDecl = IV->getContainingInterface();
+  Result += CDecl->getName();
+  Result += "__T_";
+  unsigned GroupNo = ObjCIvarBitfieldGroupNo(IV);
+  Result += utostr(GroupNo);
+  return;
+}
+
+/// ObjCIvarBitfieldGroupOffset - Names symbol for ivar bitfield group field offset.
+/// Name would be: OBJC_IVAR_$_classname__GRBF_n where n is the group number for
+/// this ivar.
+void RewriteModernObjC::ObjCIvarBitfieldGroupOffset(ObjCIvarDecl *IV,
+                                                    std::string &Result) {
+  Result += "OBJC_IVAR_$_";
+  ObjCIvarBitfieldGroupDecl(IV, Result);
+}
+
+#define SKIP_BITFIELDS(IX, ENDIX, VEC) { \
+      while ((IX < ENDIX) && VEC[IX]->isBitField()) \
+        ++IX; \
+      if (IX < ENDIX) \
+        --IX; \
+}
+
+/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteModernObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                               std::string &Result) {
+  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
+  assert(CDecl->getName() != "" &&
+         "Name missing in SynthesizeObjCInternalStruct");
+  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
+  SmallVector<ObjCIvarDecl *, 8> IVars;
+  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+       IVD; IVD = IVD->getNextIvar())
+    IVars.push_back(IVD);
+  
+  SourceLocation LocStart = CDecl->getLocStart();
+  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
+  
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  
+  // If no ivars and no root or if its root, directly or indirectly,
+  // have no ivars (thus not synthesized) then no need to synthesize this class.
+  if ((!CDecl->isThisDeclarationADefinition() || IVars.size() == 0) &&
+      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+    return;
+  }
+  
+  // Insert named struct/union definitions inside class to
+  // outer scope. This follows semantics of locally defined
+  // struct/unions in objective-c classes.
+  for (unsigned i = 0, e = IVars.size(); i < e; i++)
+    RewriteLocallyDefinedNamedAggregates(IVars[i], Result);
+  
+  // Insert named structs which are syntheized to group ivar bitfields
+  // to outer scope as well.
+  for (unsigned i = 0, e = IVars.size(); i < e; i++)
+    if (IVars[i]->isBitField()) {
+      ObjCIvarDecl *IV = IVars[i];
+      QualType QT = GetGroupRecordTypeForObjCIvarBitfield(IV);
+      RewriteObjCFieldDeclType(QT, Result);
+      Result += ";";
+      // skip over ivar bitfields in this group.
+      SKIP_BITFIELDS(i , e, IVars);
+    }
+    
+  Result += "\nstruct ";
+  Result += CDecl->getNameAsString();
+  Result += "_IMPL {\n";
+  
+  if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
+    Result += "\tstruct "; Result += RCDecl->getNameAsString();
+    Result += "_IMPL "; Result += RCDecl->getNameAsString();
+    Result += "_IVARS;\n";
+  }
+  
+  for (unsigned i = 0, e = IVars.size(); i < e; i++) {
+    if (IVars[i]->isBitField()) {
+      ObjCIvarDecl *IV = IVars[i];
+      Result += "\tstruct ";
+      ObjCIvarBitfieldGroupType(IV, Result); Result += " ";
+      ObjCIvarBitfieldGroupDecl(IV, Result); Result += ";\n";
+      // skip over ivar bitfields in this group.
+      SKIP_BITFIELDS(i , e, IVars);
+    }
+    else
+      RewriteObjCFieldDecl(IVars[i], Result);
+  }
+
+  Result += "};\n";
+  endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+  ReplaceText(LocStart, endBuf-startBuf, Result);
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl).second)
+    llvm_unreachable("struct already synthesize- RewriteObjCInternalStruct");
+}
+
+/// RewriteIvarOffsetSymbols - Rewrite ivar offset symbols of those ivars which
+/// have been referenced in an ivar access expression.
+void RewriteModernObjC::RewriteIvarOffsetSymbols(ObjCInterfaceDecl *CDecl,
+                                                  std::string &Result) {
+  // write out ivar offset symbols which have been referenced in an ivar
+  // access expression.
+  llvm::SmallPtrSet<ObjCIvarDecl *, 8> Ivars = ReferencedIvars[CDecl];
+  if (Ivars.empty())
+    return;
+  
+  llvm::DenseSet<std::pair<const ObjCInterfaceDecl*, unsigned> > GroupSymbolOutput;
+  for (ObjCIvarDecl *IvarDecl : Ivars) {
+    const ObjCInterfaceDecl *IDecl = IvarDecl->getContainingInterface();
+    unsigned GroupNo = 0;
+    if (IvarDecl->isBitField()) {
+      GroupNo = ObjCIvarBitfieldGroupNo(IvarDecl);
+      if (GroupSymbolOutput.count(std::make_pair(IDecl, GroupNo)))
+        continue;
+    }
+    Result += "\n";
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+    Result += "extern \"C\" ";
+    if (LangOpts.MicrosoftExt && 
+        IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
+        IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
+        Result += "__declspec(dllimport) ";
+
+    Result += "unsigned long ";
+    if (IvarDecl->isBitField()) {
+      ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
+      GroupSymbolOutput.insert(std::make_pair(IDecl, GroupNo));
+    }
+    else
+      WriteInternalIvarName(CDecl, IvarDecl, Result);
+    Result += ";";
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// Meta Data Emission
+//===----------------------------------------------------------------------===//
+
+
+/// RewriteImplementations - This routine rewrites all method implementations
+/// and emits meta-data.
+
+void RewriteModernObjC::RewriteImplementations() {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+
+  // Rewrite implemented methods
+  for (int i = 0; i < ClsDefCount; i++) {
+    ObjCImplementationDecl *OIMP = ClassImplementation[i];
+    ObjCInterfaceDecl *CDecl = OIMP->getClassInterface();
+    if (CDecl->isImplicitInterfaceDecl())
+      assert(false &&
+             "Legacy implicit interface rewriting not supported in moder abi");
+    RewriteImplementationDecl(OIMP);
+  }
+
+  for (int i = 0; i < CatDefCount; i++) {
+    ObjCCategoryImplDecl *CIMP = CategoryImplementation[i];
+    ObjCInterfaceDecl *CDecl = CIMP->getClassInterface();
+    if (CDecl->isImplicitInterfaceDecl())
+      assert(false &&
+             "Legacy implicit interface rewriting not supported in moder abi");
+    RewriteImplementationDecl(CIMP);
+  }
+}
+
+void RewriteModernObjC::RewriteByRefString(std::string &ResultStr, 
+                                     const std::string &Name,
+                                     ValueDecl *VD, bool def) {
+  assert(BlockByRefDeclNo.count(VD) && 
+         "RewriteByRefString: ByRef decl missing");
+  if (def)
+    ResultStr += "struct ";
+  ResultStr += "__Block_byref_" + Name + 
+    "_" + utostr(BlockByRefDeclNo[VD]) ;
+}
+
+static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
+  return false;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getReturnType();
+  std::string StructRef = "struct " + Tag;
+  SourceLocation BlockLoc = CE->getExprLoc();
+  std::string S;
+  ConvertSourceLocationToLineDirective(BlockLoc, S);
+  
+  S += "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
+         funcName.str() + "_block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+
+  if (isa<FunctionNoProtoType>(AFT)) {
+    // No user-supplied arguments. Still need to pass in a pointer to the
+    // block (to reference imported block decl refs).
+    S += "(" + StructRef + " *__cself)";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      QualType QT = (*AI)->getType();
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    std::string TypeString;
+    RewriteByRefString(TypeString, Name, (*I));
+    TypeString += " *";
+    Name = TypeString + Name;
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }
+  // Next, emit a declaration for all "by copy" declarations.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    //
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isTopLevelBlockPointerType((*I)->getType())) {
+      RewriteBlockPointerTypeVariable(S, (*I));
+      S += " = (";
+      RewriteBlockPointerType(S, (*I)->getType());
+      S += ")";
+      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+    else {
+      std::string Name = (*I)->getNameAsString();
+      QualType QT = (*I)->getType();
+      if (HasLocalVariableExternalStorage(*I))
+        QT = Context->getPointerType(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      S += Name + " = __cself->" + 
+                              (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (ValueDecl *VD : ImportedBlockDecls) {
+    S += "_Block_object_assign((void*)&dst->";
+    S += VD->getNameAsString();
+    S += ", (void*)src->";
+    S += VD->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count(VD))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (ValueDecl *VD : ImportedBlockDecls) {
+    S += "_Block_object_dispose((void*)src->";
+    S += VD->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count(VD))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  return S;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                             std::string Desc) {
+  std::string S = "\nstruct " + Tag;
+  std::string Constructor = "  " + Tag;
+
+  S += " {\n  struct __block_impl impl;\n";
+  S += "  struct " + Desc;
+  S += "* Desc;\n";
+
+  Constructor += "(void *fp, "; // Invoke function pointer.
+  Constructor += "struct " + Desc; // Descriptor pointer.
+  Constructor += " *desc";
+
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      //
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        QualType QT = (*I)->getType();
+        if (HasLocalVariableExternalStorage(*I))
+          QT = Context->getPointerType(QT);
+        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
+        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      {
+        std::string TypeString;
+        RewriteByRefString(TypeString, FieldName, (*I));
+        TypeString += " *";
+        FieldName = TypeString + FieldName;
+        ArgName = TypeString + ArgName;
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    Constructor += ", int flags=0)";
+    // Initialize all "by copy" arguments.
+    bool firsTime = true;
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+        if (firsTime) {
+          Constructor += " : ";
+          firsTime = false;
+        }
+        else
+          Constructor += ", ";
+        if (isTopLevelBlockPointerType((*I)->getType()))
+          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
+        else
+          Constructor += Name + "(_" + Name + ")";
+    }
+    // Initialize all "by ref" arguments.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      if (firsTime) {
+        Constructor += " : ";
+        firsTime = false;
+      }
+      else
+        Constructor += ", ";
+      Constructor += Name + "(_" + Name + "->__forwarding)";
+    }
+    
+    Constructor += " {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+
+    Constructor += "    Desc = desc;\n";
+  } else {
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    Constructor += "    Desc = desc;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+std::string RewriteModernObjC::SynthesizeBlockDescriptor(std::string DescTag, 
+                                                   std::string ImplTag, int i,
+                                                   StringRef FunName,
+                                                   unsigned hasCopy) {
+  std::string S = "\nstatic struct " + DescTag;
+  
+  S += " {\n  size_t reserved;\n";
+  S += "  size_t Block_size;\n";
+  if (hasCopy) {
+    S += "  void (*copy)(struct ";
+    S += ImplTag; S += "*, struct ";
+    S += ImplTag; S += "*);\n";
+    
+    S += "  void (*dispose)(struct ";
+    S += ImplTag; S += "*);\n";
+  }
+  S += "} ";
+
+  S += DescTag + "_DATA = { 0, sizeof(struct ";
+  S += ImplTag + ")";
+  if (hasCopy) {
+    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
+    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
+  }
+  S += "};\n";
+  return S;
+}
+
+void RewriteModernObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                          StringRef FunName) {
+  bool RewriteSC = (GlobalVarDecl &&
+                    !Blocks.empty() &&
+                    GlobalVarDecl->getStorageClass() == SC_Static &&
+                    GlobalVarDecl->getType().getCVRQualifiers());
+  if (RewriteSC) {
+    std::string SC(" void __");
+    SC += GlobalVarDecl->getNameAsString();
+    SC += "() {}";
+    InsertText(FunLocStart, SC);
+  }
+  
+  // Insert closures that were part of the function.
+  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
+    CollectBlockDeclRefInfo(Blocks[i]);
+    // Need to copy-in the inner copied-in variables not actually used in this
+    // block.
+    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+      DeclRefExpr *Exp = InnerDeclRefs[count++];
+      ValueDecl *VD = Exp->getDecl();
+      BlockDeclRefs.push_back(Exp);
+      if (!VD->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(VD)) {
+          BlockByCopyDeclsPtrSet.insert(VD);
+          BlockByCopyDecls.push_back(VD);
+        }
+        continue;
+      }
+
+      if (!BlockByRefDeclsPtrSet.count(VD)) {
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+
+      // imported objects in the inner blocks not used in the outer
+      // blocks must be copied/disposed in the outer block as well.
+      if (VD->getType()->isObjCObjectPointerType() || 
+          VD->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(VD);
+    }
+
+    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
+    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
+
+    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
+
+    InsertText(FunLocStart, CI);
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
+
+    InsertText(FunLocStart, CF);
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
+      InsertText(FunLocStart, HF);
+    }
+    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
+                                               ImportedBlockDecls.size() > 0);
+    InsertText(FunLocStart, BD);
+
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByRefDeclsPtrSet.clear();
+    BlockByCopyDecls.clear();
+    BlockByCopyDeclsPtrSet.clear();
+    ImportedBlockDecls.clear();
+  }
+  if (RewriteSC) {
+    // Must insert any 'const/volatile/static here. Since it has been
+    // removed as result of rewriting of block literals.
+    std::string SC;
+    if (GlobalVarDecl->getStorageClass() == SC_Static)
+      SC = "static ";
+    if (GlobalVarDecl->getType().isConstQualified())
+      SC += "const ";
+    if (GlobalVarDecl->getType().isVolatileQualified())
+      SC += "volatile ";
+    if (GlobalVarDecl->getType().isRestrictQualified())
+      SC += "restrict ";
+    InsertText(FunLocStart, SC);
+  }
+  if (GlobalConstructionExp) {
+    // extra fancy dance for global literal expression.
+    
+    // Always the latest block expression on the block stack.
+    std::string Tag = "__";
+    Tag += FunName;
+    Tag += "_block_impl_";
+    Tag += utostr(Blocks.size()-1);
+    std::string globalBuf = "static ";
+    globalBuf += Tag; globalBuf += " ";
+    std::string SStr;
+  
+    llvm::raw_string_ostream constructorExprBuf(SStr);
+    GlobalConstructionExp->printPretty(constructorExprBuf, nullptr,
+                                       PrintingPolicy(LangOpts));
+    globalBuf += constructorExprBuf.str();
+    globalBuf += ";\n";
+    InsertText(FunLocStart, globalBuf);
+    GlobalConstructionExp = nullptr;
+  }
+
+  Blocks.clear();
+  InnerDeclRefsCount.clear();
+  InnerDeclRefs.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteModernObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = 
+    (!Blocks.empty()) ? getFunctionSourceLocation(*this, FD)
+                      : FD->getTypeSpecStartLoc();
+  StringRef FuncName = FD->getName();
+
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+static void BuildUniqueMethodName(std::string &Name,
+                                  ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *IFace = MD->getClassInterface();
+  Name = IFace->getName();
+  Name += "__" + MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = Name.find(":", loc)) != std::string::npos)
+    Name.replace(loc, 1, "_");
+}
+
+void RewriteModernObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+  //SourceLocation FunLocStart = MD->getLocStart();
+  SourceLocation FunLocStart = MD->getLocStart();
+  std::string FuncName;
+  BuildUniqueMethodName(FuncName, MD);
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+void RewriteModernObjC::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      // FIXME: Handle enums.
+      if (!isa<FunctionDecl>(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+      if (HasLocalVariableExternalStorage(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+    }
+  }
+  
+  return;
+}
+
+void RewriteModernObjC::GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
+        GetInnerBlockDeclRefExprs(CBE->getBody(),
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+      }
+      else
+        GetInnerBlockDeclRefExprs(*CI,
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      if (!isa<FunctionDecl>(DRE->getDecl()) &&
+          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+        InnerBlockDeclRefs.push_back(DRE);
+      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+        if (Var->isFunctionOrMethodVarDecl())
+          ImportedLocalExternalDecls.insert(Var);
+    }
+  }
+  
+  return;
+}
+
+/// convertObjCTypeToCStyleType - This routine converts such objc types
+/// as qualified objects, and blocks to their closest c/c++ types that
+/// it can. It returns true if input type was modified.
+bool RewriteModernObjC::convertObjCTypeToCStyleType(QualType &T) {
+  QualType oldT = T;
+  convertBlockPointerToFunctionPointer(T);
+  if (T->isFunctionPointerType()) {
+    QualType PointeeTy;
+    if (const PointerType* PT = T->getAs<PointerType>()) {
+      PointeeTy = PT->getPointeeType();
+      if (const FunctionType *FT = PointeeTy->getAs<FunctionType>()) {
+        T = convertFunctionTypeOfBlocks(FT);
+        T = Context->getPointerType(T);
+      }
+    }
+  }
+  
+  convertToUnqualifiedObjCType(T);
+  return T != oldT;
+}
+
+/// convertFunctionTypeOfBlocks - This routine converts a function type
+/// whose result type may be a block pointer or whose argument type(s)
+/// might be block pointers to an equivalent function type replacing
+/// all block pointers to function pointers.
+QualType RewriteModernObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+  QualType Res = FT->getReturnType();
+  bool modified = convertObjCTypeToCStyleType(Res);
+  
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (convertObjCTypeToCStyleType(t))
+        modified = true;
+      ArgTypes.push_back(t);
+    }
+  }
+  QualType FuncType;
+  if (modified)
+    FuncType = getSimpleFunctionType(Res, ArgTypes);
+  else FuncType = QualType(FT, 0);
+  return FuncType;
+}
+
+Stmt *RewriteModernObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
+  // Navigate to relevant type information.
+  const BlockPointerType *CPT = nullptr;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
+    CPT = DRE->getType()->getAs<BlockPointerType>();
+  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
+    CPT = MExpr->getType()->getAs<BlockPointerType>();
+  } 
+  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
+    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
+  }
+  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
+    CPT = IEXPR->getType()->getAs<BlockPointerType>();
+  else if (const ConditionalOperator *CEXPR = 
+            dyn_cast<ConditionalOperator>(BlockExp)) {
+    Expr *LHSExp = CEXPR->getLHS();
+    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
+    Expr *RHSExp = CEXPR->getRHS();
+    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
+    Expr *CONDExp = CEXPR->getCond();
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(CONDExp,
+                                      SourceLocation(), cast<Expr>(LHSStmt),
+                                      SourceLocation(), cast<Expr>(RHSStmt),
+                                      Exp->getType(), VK_RValue, OK_Ordinary);
+    return CondExpr;
+  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
+    CPT = IRE->getType()->getAs<BlockPointerType>();
+  } else if (const PseudoObjectExpr *POE
+               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
+    CPT = POE->getType()->castAs<BlockPointerType>();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("__block_impl"));
+  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
+
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+
+  // Push the block argument type.
+  ArgTypes.push_back(PtrBlock);
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (!convertBlockPointerToFunctionPointer(t))
+        convertToUnqualifiedObjCType(t);
+      ArgTypes.push_back(t);
+    }
+  }
+  // Now do the pointer to function cast.
+  QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes);
+
+  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
+
+  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
+                                               CK_BitCast,
+                                               const_cast<Expr*>(BlockExp));
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                          BlkCast);
+  //PE->dump();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("FuncPtr"),
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  
+  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
+                                                CK_BitCast, ME);
+  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
+
+  SmallVector<Expr*, 8> BlkExprs;
+  // Add the implicit argument.
+  BlkExprs.push_back(BlkCast);
+  // Add the user arguments.
+  for (CallExpr::arg_iterator I = Exp->arg_begin(),
+       E = Exp->arg_end(); I != E; ++I) {
+    BlkExprs.push_back(*I);
+  }
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
+                                        Exp->getType(), VK_RValue,
+                                        SourceLocation());
+  return CE;
+}
+
+// We need to return the rewritten expression to handle cases where the
+// DeclRefExpr is embedded in another expression being rewritten.
+// For example:
+//
+// int main() {
+//    __block Foo *f;
+//    __block int i;
+//
+//    void (^myblock)() = ^() {
+//        [f test]; // f is a DeclRefExpr embedded in a message (which is being rewritten).
+//        i = 77;
+//    };
+//}
+Stmt *RewriteModernObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
+  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
+  // for each DeclRefExp where BYREFVAR is name of the variable.
+  ValueDecl *VD = DeclRefExp->getDecl();
+  bool isArrow = DeclRefExp->refersToEnclosingLocal();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("__forwarding"), 
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
+                                            FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  StringRef Name = VD->getName();
+  FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(),
+                         &Context->Idents.get(Name), 
+                         Context->VoidPtrTy, nullptr,
+                         /*BitWidth=*/nullptr, /*Mutable=*/true,
+                         ICIS_NoInit);
+  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
+                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
+  
+  
+  
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
+                                          DeclRefExp->getExprLoc(), 
+                                          ME);
+  ReplaceStmt(DeclRefExp, PE);
+  return PE;
+}
+
+// Rewrites the imported local variable V with external storage 
+// (static, extern, etc.) as *V
+//
+Stmt *RewriteModernObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
+  ValueDecl *VD = DRE->getDecl();
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    if (!ImportedLocalExternalDecls.count(Var))
+      return DRE;
+  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
+                                          VK_LValue, OK_Ordinary,
+                                          DRE->getLocation());
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                          Exp);
+  ReplaceStmt(DRE, PE);
+  return PE;
+}
+
+void RewriteModernObjC::RewriteCastExpr(CStyleCastExpr *CE) {
+  SourceLocation LocStart = CE->getLParenLoc();
+  SourceLocation LocEnd = CE->getRParenLoc();
+
+  // Need to avoid trying to rewrite synthesized casts.
+  if (LocStart.isInvalid())
+    return;
+  // Need to avoid trying to rewrite casts contained in macros.
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  QualType QT = CE->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    std::string TypeAsString = "(";
+    RewriteBlockPointerType(TypeAsString, QT);
+    TypeAsString += ")";
+    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
+    return;
+  }
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
+      ReplaceText(LocStart, 1, "*");
+      break;
+    }
+  }
+  return;
+}
+
+void RewriteModernObjC::RewriteImplicitCastObjCExpr(CastExpr *IC) {
+  CastKind CastKind = IC->getCastKind();
+  if (CastKind != CK_BlockPointerToObjCPointerCast &&
+      CastKind != CK_AnyPointerToBlockPointerCast)
+    return;
+  
+  QualType QT = IC->getType();
+  (void)convertBlockPointerToFunctionPointer(QT);
+  std::string TypeString(QT.getAsString(Context->getPrintingPolicy()));
+  std::string Str = "(";
+  Str += TypeString;
+  Str += ")";
+  InsertText(IC->getSubExpr()->getLocStart(), &Str[0], Str.size());
+
+  return;
+}
+
+void RewriteModernObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+
+  const char *argPtr = startArgList;
+
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
+      ReplaceText(DeclLoc, 1, "*");
+      break;
+    case '(':
+      parenCount++;
+      break;
+    case ')':
+      parenCount--;
+      break;
+    }
+  }
+  return;
+}
+
+bool RewriteModernObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types())
+      if (isTopLevelBlockPointerType(I))
+        return true;
+  }
+  return false;
+}
+
+bool RewriteModernObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types()) {
+      if (I->isObjCQualifiedIdType())
+        return true;
+      if (I->isObjCObjectPointerType() &&
+          I->getPointeeType()->isObjCQualifiedInterfaceType())
+        return true;
+    }
+        
+  }
+  return false;
+}
+
+void RewriteModernObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
+                                     const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+    case '(': parenCount++; break;
+    case ')': parenCount--; break;
+    default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteModernObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  }
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else
+    llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
+
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
+  std::string buf;
+  unsigned OrigLength=0;
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    buf = '*';
+    startBuf++;
+    OrigLength++;
+  }
+  while (*startBuf != ')') {
+    buf += *startBuf;
+    startBuf++;
+    OrigLength++;
+  }
+  buf += ')';
+  OrigLength++;
+  
+  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
+      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    // Replace id<P> with id/*<>*/
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^')
+        buf += '*';
+      else if (*argListBegin ==  '<') {
+        buf += "/*"; 
+        buf += *argListBegin++;
+        OrigLength++;
+        while (*argListBegin != '>') {
+          buf += *argListBegin++;
+          OrigLength++;
+        }
+        buf += *argListBegin;
+        buf += "*/";
+      }
+      else
+        buf += *argListBegin;
+      argListBegin++;
+      OrigLength++;
+    }
+    buf += ')';
+    OrigLength++;
+  }
+  ReplaceText(Start, OrigLength, buf);
+  
+  return;
+}
+
+
+/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
+/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
+///                    struct Block_byref_id_object *src) {
+///  _Block_object_assign (&_dest->object, _src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_assign(&_dest->object, _src->object, 
+///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                       [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+/// And:
+/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
+///  _Block_object_dispose(_src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_dispose(_src->object, 
+///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                         [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+
+std::string RewriteModernObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
+                                                          int flag) {
+  std::string S;
+  if (CopyDestroyCache.count(flag))
+    return S;
+  CopyDestroyCache.insert(flag);
+  S = "static void __Block_byref_id_object_copy_";
+  S += utostr(flag);
+  S += "(void *dst, void *src) {\n";
+  
+  // offset into the object pointer is computed as:
+  // void * + void* + int + int + void* + void *
+  unsigned IntSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  unsigned VoidPtrSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
+  
+  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
+  S += " _Block_object_assign((char*)dst + ";
+  S += utostr(offset);
+  S += ", *(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  
+  S += "static void __Block_byref_id_object_dispose_";
+  S += utostr(flag);
+  S += "(void *src) {\n";
+  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  return S;
+}
+
+/// RewriteByRefVar - For each __block typex ND variable this routine transforms
+/// the declaration into:
+/// struct __Block_byref_ND {
+/// void *__isa;                  // NULL for everything except __weak pointers
+/// struct __Block_byref_ND *__forwarding;
+/// int32_t __flags;
+/// int32_t __size;
+/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
+/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
+/// typex ND;
+/// };
+///
+/// It then replaces declaration of ND variable with:
+/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
+///                               __size=sizeof(struct __Block_byref_ND), 
+///                               ND=initializer-if-any};
+///
+///
+void RewriteModernObjC::RewriteByRefVar(VarDecl *ND, bool firstDecl,
+                                        bool lastDecl) {
+  int flag = 0;
+  int isa = 0;
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  if (DeclLoc.isInvalid())
+    // If type location is missing, it is because of missing type (a warning).
+    // Use variable's location which is good for this case.
+    DeclLoc = ND->getLocation();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  SourceLocation X = ND->getLocEnd();
+  X = SM->getExpansionLoc(X);
+  const char *endBuf = SM->getCharacterData(X);
+  std::string Name(ND->getNameAsString());
+  std::string ByrefType;
+  RewriteByRefString(ByrefType, Name, ND, true);
+  ByrefType += " {\n";
+  ByrefType += "  void *__isa;\n";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " *__forwarding;\n";
+  ByrefType += " int __flags;\n";
+  ByrefType += " int __size;\n";
+  // Add void *__Block_byref_id_object_copy; 
+  // void *__Block_byref_id_object_dispose; if needed.
+  QualType Ty = ND->getType();
+  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
+  if (HasCopyAndDispose) {
+    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
+    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
+  }
+
+  QualType T = Ty;
+  (void)convertBlockPointerToFunctionPointer(T);
+  T.getAsStringInternal(Name, Context->getPrintingPolicy());
+    
+  ByrefType += " " + Name + ";\n";
+  ByrefType += "};\n";
+  // Insert this type in global scope. It is needed by helper function.
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+     FunLocStart = getFunctionSourceLocation(*this, CurFunctionDef);
+  else {
+    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+  InsertText(FunLocStart, ByrefType);
+  
+  if (Ty.isObjCGCWeak()) {
+    flag |= BLOCK_FIELD_IS_WEAK;
+    isa = 1;
+  }
+  if (HasCopyAndDispose) {
+    flag = BLOCK_BYREF_CALLER;
+    QualType Ty = ND->getType();
+    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
+    if (Ty->isBlockPointerType())
+      flag |= BLOCK_FIELD_IS_BLOCK;
+    else
+      flag |= BLOCK_FIELD_IS_OBJECT;
+    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
+    if (!HF.empty())
+      Preamble += HF;
+  }
+  
+  // struct __Block_byref_ND ND = 
+  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
+  //  initializer-if-any};
+  bool hasInit = (ND->getInit() != nullptr);
+  // FIXME. rewriter does not support __block c++ objects which
+  // require construction.
+  if (hasInit)
+    if (CXXConstructExpr *CExp = dyn_cast<CXXConstructExpr>(ND->getInit())) {
+      CXXConstructorDecl *CXXDecl = CExp->getConstructor();
+      if (CXXDecl && CXXDecl->isDefaultConstructor())
+        hasInit = false;
+    }
+  
+  unsigned flags = 0;
+  if (HasCopyAndDispose)
+    flags |= BLOCK_HAS_COPY_DISPOSE;
+  Name = ND->getNameAsString();
+  ByrefType.clear();
+  RewriteByRefString(ByrefType, Name, ND);
+  std::string ForwardingCastType("(");
+  ForwardingCastType += ByrefType + " *)";
+  ByrefType += " " + Name + " = {(void*)";
+  ByrefType += utostr(isa);
+  ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+  ByrefType += utostr(flags);
+  ByrefType += ", ";
+  ByrefType += "sizeof(";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += ")";
+  if (HasCopyAndDispose) {
+    ByrefType += ", __Block_byref_id_object_copy_";
+    ByrefType += utostr(flag);
+    ByrefType += ", __Block_byref_id_object_dispose_";
+    ByrefType += utostr(flag);
+  }
+  
+  if (!firstDecl) {
+    // In multiple __block declarations, and for all but 1st declaration,
+    // find location of the separating comma. This would be start location
+    // where new text is to be inserted.
+    DeclLoc = ND->getLocation();
+    const char *startDeclBuf = SM->getCharacterData(DeclLoc);
+    const char *commaBuf = startDeclBuf;
+    while (*commaBuf != ',')
+      commaBuf--;
+    assert((*commaBuf == ',') && "RewriteByRefVar: can't find ','");
+    DeclLoc = DeclLoc.getLocWithOffset(commaBuf - startDeclBuf);
+    startBuf = commaBuf;
+  }
+  
+  if (!hasInit) {
+    ByrefType += "};\n";
+    unsigned nameSize = Name.size();
+    // for block or function pointer declaration. Name is aleady
+    // part of the declaration.
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
+      nameSize = 1;
+    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
+  }
+  else {
+    ByrefType += ", ";
+    SourceLocation startLoc;
+    Expr *E = ND->getInit();
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
+
+    const char separator = lastDecl ? ';' : ',';
+    const char *startInitializerBuf = SM->getCharacterData(startLoc);
+    const char *separatorBuf = strchr(startInitializerBuf, separator);
+    assert((*separatorBuf == separator) && 
+           "RewriteByRefVar: can't find ';' or ','");
+    SourceLocation separatorLoc =
+      startLoc.getLocWithOffset(separatorBuf-startInitializerBuf);
+    
+    InsertText(separatorLoc, lastDecl ? "}" : "};\n");
+  }
+  return;
+}
+
+void RewriteModernObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          BlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+  }
+}
+
+FunctionDecl *RewriteModernObjC::SynthBlockInitFunctionDecl(StringRef name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
+                              SourceLocation(), ID, FType, nullptr, SC_Extern,
+                              false, false);
+}
+
+Stmt *RewriteModernObjC::SynthBlockInitExpr(BlockExpr *Exp,
+                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
+  
+  const BlockDecl *block = Exp->getBlockDecl();
+  
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  
+  // Add inner imported variables now used in current block.
+ int countOfInnerDecls = 0;
+  if (!InnerBlockDeclRefs.empty()) {
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
+      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
+      ValueDecl *VD = Exp->getDecl();
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
+      // We need to save the copied-in variables in nested
+      // blocks because it is needed at the end for some of the API generations.
+      // See SynthesizeBlockLiterals routine.
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
+      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
+  }
+  InnerDeclRefsCount.push_back(countOfInnerDecls);
+  
+  std::string FuncName;
+
+  if (CurFunctionDef)
+    FuncName = CurFunctionDef->getNameAsString();
+  else if (CurMethodDef)
+    BuildUniqueMethodName(FuncName, CurMethodDef);
+  else if (GlobalVarDecl)
+    FuncName = std::string(GlobalVarDecl->getNameAsString());
+
+  bool GlobalBlockExpr = 
+    block->getDeclContext()->getRedeclContext()->isFileContext();
+  
+  if (GlobalBlockExpr && !GlobalVarDecl) {
+    Diags.Report(block->getLocation(), GlobalBlockRewriteFailedDiag);
+    GlobalBlockExpr = false;
+  }
+  
+  std::string BlockNumber = utostr(Blocks.size()-1);
+
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+
+  // Get a pointer to the function type so we can cast appropriately.
+  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
+  QualType FType = Context->getPointerType(BFT);
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+
+  // Simulate a constructor call...
+  std::string Tag;
+  
+  if (GlobalBlockExpr)
+    Tag = "__global_";
+  else
+    Tag = "__";
+  Tag += FuncName + "_block_impl_" + BlockNumber;
+  
+  FD = SynthBlockInitFunctionDecl(Tag);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
+                                               SourceLocation());
+
+  SmallVector<Expr*, 4> InitExprs;
+
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func);
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                               VK_LValue, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                                CK_BitCast, Arg);
+  InitExprs.push_back(castExpr);
+
+  // Initialize the block descriptor.
+  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
+                                   SourceLocation(), SourceLocation(),
+                                   &Context->Idents.get(DescData.c_str()),
+                                   Context->VoidPtrTy, nullptr,
+                                   SC_Static);
+  UnaryOperator *DescRefExpr =
+    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
+                                                          Context->VoidPtrTy,
+                                                          VK_LValue,
+                                                          SourceLocation()), 
+                                UO_AddrOf,
+                                Context->getPointerType(Context->VoidPtrTy), 
+                                VK_RValue, OK_Ordinary,
+                                SourceLocation());
+  InitExprs.push_back(DescRefExpr); 
+  
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    Expr *Exp;
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      if (isObjCType((*I)->getType())) {
+        // FIXME: Conform to ABI ([[obj retain] autorelease]).
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                       CK_BitCast, Arg);
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                        VK_LValue, SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+        
+      }
+      InitExprs.push_back(Exp);
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      ValueDecl *ND = (*I);
+      std::string Name(ND->getNameAsString());
+      std::string RecName;
+      RewriteByRefString(RecName, Name, ND, true);
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
+                                                + sizeof("struct"));
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      
+      FD = SynthBlockInitFunctionDecl((*I)->getName());
+      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                      SourceLocation());
+      bool isNestedCapturedVar = false;
+      if (block)
+        for (const auto &CI : block->captures()) {
+          const VarDecl *variable = CI.getVariable();
+          if (variable == ND && CI.isNested()) {
+            assert (CI.isByRef() && 
+                    "SynthBlockInitExpr - captured block variable is not byref");
+            isNestedCapturedVar = true;
+            break;
+          }
+        }
+      // captured nested byref variable has its address passed. Do not take
+      // its address again.
+      if (!isNestedCapturedVar)
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
+                                     Context->getPointerType(Exp->getType()),
+                                     VK_RValue, OK_Ordinary, SourceLocation());
+      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
+      InitExprs.push_back(Exp);
+    }
+  }
+  if (ImportedBlockDecls.size()) {
+    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
+    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
+    unsigned IntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
+                                           Context->IntTy, SourceLocation());
+    InitExprs.push_back(FlagExp);
+  }
+  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                  FType, VK_LValue, SourceLocation());
+  
+  if (GlobalBlockExpr) {
+    assert (!GlobalConstructionExp &&
+            "SynthBlockInitExpr - GlobalConstructionExp must be null");
+    GlobalConstructionExp = NewRep;
+    NewRep = DRE;
+  }
+  
+  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
+                             Context->getPointerType(NewRep->getType()),
+                             VK_RValue, OK_Ordinary, SourceLocation());
+  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
+                                    NewRep);
+  // Put Paren around the call.
+  NewRep = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                   NewRep);
+  
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByRefDeclsPtrSet.clear();
+  BlockByCopyDecls.clear();
+  BlockByCopyDeclsPtrSet.clear();
+  ImportedBlockDecls.clear();
+  return NewRep;
+}
+
+bool RewriteModernObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
+  if (const ObjCForCollectionStmt * CS = 
+      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
+        return CS->getElement() == DS;
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+Stmt *RewriteModernObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S))
+    Stmts.push_back(S);
+  else if (isa<ObjCForCollectionStmt>(S)) {
+    Stmts.push_back(S);
+    ObjCBcLabelNo.push_back(++BcLabelCount);
+  }
+
+  // Pseudo-object operations and ivar references need special
+  // treatment because we're going to recursively rewrite them.
+  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
+    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
+      return RewritePropertyOrImplicitSetter(PseudoOp);
+    } else {
+      return RewritePropertyOrImplicitGetter(PseudoOp);
+    }
+  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+    return RewriteObjCIvarRefExpr(IvarRefExpr);
+  }
+  else if (isa<OpaqueValueExpr>(S))
+    S = cast<OpaqueValueExpr>(S)->getSourceExpr();
+
+  SourceRange OrigStmtRange = S->getSourceRange();
+
+  // Perform a bottom up rewrite of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      Stmt *childStmt = (*CI);
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
+      if (newStmt) {
+        *CI = newStmt;
+      }
+    }
+
+  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
+    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+    InnerContexts.insert(BE->getBlockDecl());
+    ImportedLocalExternalDecls.clear();
+    GetInnerBlockDeclRefExprs(BE->getBody(),
+                              InnerBlockDeclRefs, InnerContexts);
+    // Rewrite the block body in place.
+    Stmt *SaveCurrentBody = CurrentBody;
+    CurrentBody = BE->getBody();
+    PropParentMap = nullptr;
+    // block literal on rhs of a property-dot-sytax assignment
+    // must be replaced by its synthesize ast so getRewrittenText
+    // works as expected. In this case, what actually ends up on RHS
+    // is the blockTranscribed which is the helper function for the
+    // block literal; as in: self.c = ^() {[ace ARR];};
+    bool saveDisableReplaceStmt = DisableReplaceStmt;
+    DisableReplaceStmt = false;
+    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
+    DisableReplaceStmt = saveDisableReplaceStmt;
+    CurrentBody = SaveCurrentBody;
+    PropParentMap = nullptr;
+    ImportedLocalExternalDecls.clear();
+    // Now we snarf the rewritten text and stash it away for later use.
+    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
+    RewrittenBlockExprs[BE] = Str;
+
+    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
+                            
+    //blockTranscribed->dump();
+    ReplaceStmt(S, blockTranscribed);
+    return blockTranscribed;
+  }
+  // Handle specific things.
+  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
+    return RewriteAtEncode(AtEncode);
+
+  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
+    return RewriteAtSelector(AtSelector);
+
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
+  
+  if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
+    return RewriteObjCBoolLiteralExpr(BoolLitExpr);
+  
+  if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S))
+    return RewriteObjCBoxedExpr(BoxedExpr);
+  
+  if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
+    return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
+  
+  if (ObjCDictionaryLiteral *DictionaryLitExpr = 
+        dyn_cast<ObjCDictionaryLiteral>(S))
+    return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
+
+  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+#if 0
+    // Before we rewrite it, put the original message expression in a comment.
+    SourceLocation startLoc = MessExpr->getLocStart();
+    SourceLocation endLoc = MessExpr->getLocEnd();
+
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *endBuf = SM->getCharacterData(endLoc);
+
+    std::string messString;
+    messString += "// ";
+    messString.append(startBuf, endBuf-startBuf+1);
+    messString += "\n";
+
+    // FIXME: Missing definition of
+    // InsertText(clang::SourceLocation, char const*, unsigned int).
+    // InsertText(startLoc, messString.c_str(), messString.size());
+    // Tried this, but it didn't work either...
+    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
+#endif
+    return RewriteMessageExpr(MessExpr);
+  }
+
+  if (ObjCAutoreleasePoolStmt *StmtAutoRelease = 
+        dyn_cast<ObjCAutoreleasePoolStmt>(S)) {
+    return RewriteObjCAutoreleasePoolStmt(StmtAutoRelease);
+  }
+  
+  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
+    return RewriteObjCTryStmt(StmtTry);
+
+  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+    return RewriteObjCSynchronizedStmt(StmtTry);
+
+  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
+    return RewriteObjCThrowStmt(StmtThrow);
+
+  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+    return RewriteObjCProtocolExpr(ProtocolExp);
+
+  if (ObjCForCollectionStmt *StmtForCollection =
+        dyn_cast<ObjCForCollectionStmt>(S))
+    return RewriteObjCForCollectionStmt(StmtForCollection,
+                                        OrigStmtRange.getEnd());
+  if (BreakStmt *StmtBreakStmt =
+      dyn_cast<BreakStmt>(S))
+    return RewriteBreakStmt(StmtBreakStmt);
+  if (ContinueStmt *StmtContinueStmt =
+      dyn_cast<ContinueStmt>(S))
+    return RewriteContinueStmt(StmtContinueStmt);
+
+  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
+  // and cast exprs.
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    // FIXME: What we're doing here is modifying the type-specifier that
+    // precedes the first Decl.  In the future the DeclGroup should have
+    // a separate type-specifier that we can rewrite.
+    // NOTE: We need to avoid rewriting the DeclStmt if it is within
+    // the context of an ObjCForCollectionStmt. For example:
+    //   NSArray *someArray;
+    //   for (id <FooProtocol> index in someArray) ;
+    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
+    // and it depends on the original text locations/positions.
+    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
+      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
+
+    // Blocks rewrite rules.
+    for (DeclStmt::decl_iterator DI = DS->decl_begin(), DE = DS->decl_end();
+         DI != DE; ++DI) {
+      Decl *SD = *DI;
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isTopLevelBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(ND->getType(), ND);
+        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
+          if (VD->hasAttr<BlocksAttr>()) {
+            static unsigned uniqueByrefDeclCount = 0;
+            assert(!BlockByRefDeclNo.count(ND) &&
+              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
+            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
+            RewriteByRefVar(VD, (DI == DS->decl_begin()), ((DI+1) == DE));
+          }
+          else           
+            RewriteTypeOfDecl(VD);
+        }
+      }
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
+    RewriteObjCQualifiedInterfaceTypes(CE);
+
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S)) {
+    assert(!Stmts.empty() && "Statement stack is empty");
+    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
+             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
+            && "Statement stack mismatch");
+    Stmts.pop_back();
+  }
+  // Handle blocks rewriting.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    ValueDecl *VD = DRE->getDecl(); 
+    if (VD->hasAttr<BlocksAttr>())
+      return RewriteBlockDeclRefExpr(DRE);
+    if (HasLocalVariableExternalStorage(VD))
+      return RewriteLocalVariableExternalStorage(DRE);
+  }
+  
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
+      ReplaceStmt(S, BlockCall);
+      return BlockCall;
+    }
+  }
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    RewriteImplicitCastObjCExpr(ICE);
+  }
+#if 0
+
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
+                                                   ICE->getSubExpr(),
+                                                   SourceLocation());
+    // Get the new text.
+    std::string SStr;
+    llvm::raw_string_ostream Buf(SStr);
+    Replacement->printPretty(Buf);
+    const std::string &Str = Buf.str();
+
+    printf("CAST = %s\n", &Str[0]);
+    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+    delete S;
+    return Replacement;
+  }
+#endif
+  // Return this stmt unmodified.
+  return S;
+}
+
+void RewriteModernObjC::RewriteRecordBody(RecordDecl *RD) {
+  for (auto *FD : RD->fields()) {
+    if (isTopLevelBlockPointerType(FD->getType()))
+      RewriteBlockPointerDecl(FD);
+    if (FD->getType()->isObjCQualifiedIdType() ||
+        FD->getType()->isObjCQualifiedInterfaceType())
+      RewriteObjCQualifiedInterfaceTypes(FD);
+  }
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteModernObjC::HandleDeclInMainFile(Decl *D) {
+  switch (D->getKind()) {
+    case Decl::Function: {
+      FunctionDecl *FD = cast<FunctionDecl>(D);
+      if (FD->isOverloadedOperator())
+        return;
+
+      // Since function prototypes don't have ParmDecl's, we check the function
+      // prototype. This enables us to rewrite function declarations and
+      // definitions using the same code.
+      RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+
+      if (!FD->isThisDeclarationADefinition())
+        break;
+
+      // FIXME: If this should support Obj-C++, support CXXTryStmt
+      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
+        CurFunctionDef = FD;
+        CurrentBody = Body;
+        Body =
+        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        FD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        // This synthesizes and inserts the block "impl" struct, invoke function,
+        // and any copy/dispose helper functions.
+        InsertBlockLiteralsWithinFunction(FD);
+        RewriteLineDirective(D);
+        CurFunctionDef = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
+      if (CompoundStmt *Body = MD->getCompoundBody()) {
+        CurMethodDef = MD;
+        CurrentBody = Body;
+        Body =
+          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        MD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        InsertBlockLiteralsWithinMethod(MD);
+        RewriteLineDirective(D);
+        CurMethodDef = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCImplementation: {
+      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
+      ClassImplementation.push_back(CI);
+      break;
+    }
+    case Decl::ObjCCategoryImpl: {
+      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
+      CategoryImplementation.push_back(CI);
+      break;
+    }
+    case Decl::Var: {
+      VarDecl *VD = cast<VarDecl>(D);
+      RewriteObjCQualifiedInterfaceTypes(VD);
+      if (isTopLevelBlockPointerType(VD->getType()))
+        RewriteBlockPointerDecl(VD);
+      else if (VD->getType()->isFunctionPointerType()) {
+        CheckFunctionPointerDecl(VD->getType(), VD);
+        if (VD->getInit()) {
+          if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+          }
+        }
+      } else if (VD->getType()->isRecordType()) {
+        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
+        if (RD->isCompleteDefinition())
+          RewriteRecordBody(RD);
+      }
+      if (VD->getInit()) {
+        GlobalVarDecl = VD;
+        CurrentBody = VD->getInit();
+        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
+        GlobalVarDecl = nullptr;
+
+        // This is needed for blocks.
+        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+        }
+      }
+      break;
+    }
+    case Decl::TypeAlias:
+    case Decl::Typedef: {
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+        else
+          RewriteObjCQualifiedInterfaceTypes(TD);
+      }
+      break;
+    }
+    case Decl::CXXRecord:
+    case Decl::Record: {
+      RecordDecl *RD = cast<RecordDecl>(D);
+      if (RD->isCompleteDefinition()) 
+        RewriteRecordBody(RD);
+      break;
+    }
+    default:
+      break;
+  }
+  // Nothing yet.
+}
+
+/// Write_ProtocolExprReferencedMetadata - This routine writer out the
+/// protocol reference symbols in the for of:
+/// struct _protocol_t *PROTOCOL_REF = &PROTOCOL_METADATA.
+static void Write_ProtocolExprReferencedMetadata(ASTContext *Context, 
+                                                 ObjCProtocolDecl *PDecl,
+                                                 std::string &Result) {
+  // Also output .objc_protorefs$B section and its meta-data.
+  if (Context->getLangOpts().MicrosoftExt)
+    Result += "static ";
+  Result += "struct _protocol_t *";
+  Result += "_OBJC_PROTOCOL_REFERENCE_$_";
+  Result += PDecl->getNameAsString();
+  Result += " = &";
+  Result += "_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
+  Result += ";\n";
+}
+
+void RewriteModernObjC::HandleTranslationUnit(ASTContext &C) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  RewriteInclude();
+
+  for (unsigned i = 0, e = FunctionDefinitionsSeen.size(); i < e; i++) {
+    // translation of function bodies were postponed until all class and
+    // their extensions and implementations are seen. This is because, we
+    // cannot build grouping structs for bitfields until they are all seen.
+    FunctionDecl *FDecl = FunctionDefinitionsSeen[i];
+    HandleTopLevelSingleDecl(FDecl);
+  }
+
+  // Here's a great place to add any extra declarations that may be needed.
+  // Write out meta data for each @protocol(<expr>).
+  for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) {
+    RewriteObjCProtocolMetaData(ProtDecl, Preamble);
+    Write_ProtocolExprReferencedMetadata(Context, ProtDecl, Preamble);
+  }
+
+  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
+  
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+  
+  for (unsigned i = 0, e = ObjCInterfacesSeen.size(); i < e; i++) {
+    ObjCInterfaceDecl *CDecl = ObjCInterfacesSeen[i];
+    // Write struct declaration for the class matching its ivar declarations.
+    // Note that for modern abi, this is postponed until the end of TU
+    // because class extensions and the implementation might declare their own
+    // private ivars.
+    RewriteInterfaceDecl(CDecl);
+  }
+  
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(MainFileID)) {
+    //printf("Changed:\n");
+    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    llvm::errs() << "No changes\n";
+  }
+
+  if (ClassImplementation.size() || CategoryImplementation.size() ||
+      ProtocolExprDecls.size()) {
+    // Rewrite Objective-c meta data*
+    std::string ResultStr;
+    RewriteMetaDataIntoBuffer(ResultStr);
+    // Emit metadata.
+    *OutFile << ResultStr;
+  }
+  // Emit ImageInfo;
+  {
+    std::string ResultStr;
+    WriteImageInfo(ResultStr);
+    *OutFile << ResultStr;
+  }
+  OutFile->flush();
+}
+
+void RewriteModernObjC::Initialize(ASTContext &context) {
+  InitializeCommon(context);
+  
+  Preamble += "#ifndef __OBJC2__\n";
+  Preamble += "#define __OBJC2__\n";
+  Preamble += "#endif\n";
+
+  // declaring objc_selector outside the parameter list removes a silly
+  // scope related warning...
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "struct objc_selector; struct objc_class;\n";
+  Preamble += "struct __rw_objc_super { \n\tstruct objc_object *object; ";
+  Preamble += "\n\tstruct objc_object *superClass; ";
+  // Add a constructor for creating temporary objects.
+  Preamble += "\n\t__rw_objc_super(struct objc_object *o, struct objc_object *s) ";
+  Preamble += ": object(o), superClass(s) {} ";
+  Preamble += "\n};\n";
+  
+  if (LangOpts.MicrosoftExt) {
+    // Define all sections using syntax that makes sense.
+    // These are currently generated.
+    Preamble += "\n#pragma section(\".objc_classlist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_catlist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_imageinfo$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_nlclslist$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_nlcatlist$B\", long, read, write)\n";
+    // These are generated but not necessary for functionality.
+    Preamble += "#pragma section(\".cat_cls_meth$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".inst_meth$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".cls_meth$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_ivar$B\", long, read, write)\n";
+    
+    // These need be generated for performance. Currently they are not,
+    // using API calls instead.
+    Preamble += "#pragma section(\".objc_selrefs$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_classrefs$B\", long, read, write)\n";
+    Preamble += "#pragma section(\".objc_superrefs$B\", long, read, write)\n";
+    
+  }
+  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
+  Preamble += "typedef struct objc_object Protocol;\n";
+  Preamble += "#define _REWRITER_typedef_Protocol\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
+    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
+  } 
+  else
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+  
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_stret(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSendSuper_stret(void);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_msgSend_fpret(void);\n";
+
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
+  Preamble += "(struct objc_class *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *objc_getMetaClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw( struct objc_object *);\n";
+  // @synchronized hooks.
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter( struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit( struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
+  Preamble += "#ifdef _WIN64\n";
+  Preamble += "typedef unsigned long long  _WIN_NSUInteger;\n";
+  Preamble += "#else\n";
+  Preamble += "typedef unsigned int _WIN_NSUInteger;\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
+  Preamble += "struct __objcFastEnumerationState {\n\t";
+  Preamble += "unsigned long state;\n\t";
+  Preamble += "void **itemsPtr;\n\t";
+  Preamble += "unsigned long *mutationsPtr;\n\t";
+  Preamble += "unsigned long extra[5];\n};\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
+  Preamble += "#define __FASTENUMERATIONSTATE\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "struct __NSConstantStringImpl {\n";
+  Preamble += "  int *isa;\n";
+  Preamble += "  int flags;\n";
+  Preamble += "  char *str;\n";
+  Preamble += "#if _WIN64\n";
+  Preamble += "  long long length;\n";
+  Preamble += "#else\n";
+  Preamble += "  long length;\n";
+  Preamble += "#endif\n";
+  Preamble += "};\n";
+  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
+  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
+  Preamble += "#endif\n";
+  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "#endif\n";
+  // Blocks preamble.
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Reserved;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
+  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
+  Preamble += "extern \"C\" __declspec(dllexport) "
+  "void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#endif\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
+    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
+    Preamble += "#define __attribute__(X)\n";
+    Preamble += "#endif\n";
+    Preamble += "#ifndef __weak\n";
+    Preamble += "#define __weak\n";
+    Preamble += "#endif\n";
+    Preamble += "#ifndef __block\n";
+    Preamble += "#define __block\n";
+    Preamble += "#endif\n";
+  }
+  else {
+    Preamble += "#define __block\n";
+    Preamble += "#define __weak\n";
+  }
+  
+  // Declarations required for modern objective-c array and dictionary literals.
+  Preamble += "\n#include <stdarg.h>\n";
+  Preamble += "struct __NSContainer_literal {\n";
+  Preamble += "  void * *arr;\n";
+  Preamble += "  __NSContainer_literal (unsigned int count, ...) {\n";
+  Preamble += "\tva_list marker;\n";
+  Preamble += "\tva_start(marker, count);\n";
+  Preamble += "\tarr = new void *[count];\n";
+  Preamble += "\tfor (unsigned i = 0; i < count; i++)\n";
+  Preamble += "\t  arr[i] = va_arg(marker, void *);\n";
+  Preamble += "\tva_end( marker );\n";
+  Preamble += "  };\n";
+  Preamble += "  ~__NSContainer_literal() {\n";
+  Preamble += "\tdelete[] arr;\n";
+  Preamble += "  }\n";
+  Preamble += "};\n";
+  
+  // Declaration required for implementation of @autoreleasepool statement.
+  Preamble += "extern \"C\" __declspec(dllimport) void * objc_autoreleasePoolPush(void);\n";
+  Preamble += "extern \"C\" __declspec(dllimport) void objc_autoreleasePoolPop(void *);\n\n";
+  Preamble += "struct __AtAutoreleasePool {\n";
+  Preamble += "  __AtAutoreleasePool() {atautoreleasepoolobj = objc_autoreleasePoolPush();}\n";
+  Preamble += "  ~__AtAutoreleasePool() {objc_autoreleasePoolPop(atautoreleasepoolobj);}\n";
+  Preamble += "  void * atautoreleasepoolobj;\n";
+  Preamble += "};\n";
+  
+  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
+  // as this avoids warning in any 64bit/32bit compilation model.
+  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
+}
+
+/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteModernObjC::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                                         std::string &Result) {
+  Result += "__OFFSETOFIVAR__(struct ";
+  Result += ivar->getContainingInterface()->getNameAsString();
+  if (LangOpts.MicrosoftExt)
+    Result += "_IMPL";
+  Result += ", ";
+  if (ivar->isBitField())
+    ObjCIvarBitfieldGroupDecl(ivar, Result);
+  else
+    Result += ivar->getNameAsString();
+  Result += ")";
+}
+
+/// WriteModernMetadataDeclarations - Writes out metadata declarations for modern ABI.
+/// struct _prop_t {
+///   const char *name;
+///   char *attributes;
+/// }
+
+/// struct _prop_list_t {
+///   uint32_t entsize;      // sizeof(struct _prop_t)
+///   uint32_t count_of_properties;
+///   struct _prop_t prop_list[count_of_properties];
+/// }
+
+/// struct _protocol_t;
+
+/// struct _protocol_list_t {
+///   long protocol_count;   // Note, this is 32/64 bit
+///   struct _protocol_t * protocol_list[protocol_count];
+/// }
+
+/// struct _objc_method {
+///   SEL _cmd;
+///   const char *method_type;
+///   char *_imp;
+/// }
+
+/// struct _method_list_t {
+///   uint32_t entsize;  // sizeof(struct _objc_method)
+///   uint32_t method_count;
+///   struct _objc_method method_list[method_count];
+/// }
+
+/// struct _protocol_t {
+///   id isa;  // NULL
+///   const char *protocol_name;
+///   const struct _protocol_list_t * protocol_list; // super protocols
+///   const struct method_list_t *instance_methods;
+///   const struct method_list_t *class_methods;
+///   const struct method_list_t *optionalInstanceMethods;
+///   const struct method_list_t *optionalClassMethods;
+///   const struct _prop_list_t * properties;
+///   const uint32_t size;  // sizeof(struct _protocol_t)
+///   const uint32_t flags;  // = 0
+///   const char ** extendedMethodTypes;
+/// }
+
+/// struct _ivar_t {
+///   unsigned long int *offset;  // pointer to ivar offset location
+///   const char *name;
+///   const char *type;
+///   uint32_t alignment;
+///   uint32_t size;
+/// }
+
+/// struct _ivar_list_t {
+///   uint32 entsize;  // sizeof(struct _ivar_t)
+///   uint32 count;
+///   struct _ivar_t list[count];
+/// }
+
+/// struct _class_ro_t {
+///   uint32_t flags;
+///   uint32_t instanceStart;
+///   uint32_t instanceSize;
+///   uint32_t reserved;  // only when building for 64bit targets
+///   const uint8_t *ivarLayout;
+///   const char *name;
+///   const struct _method_list_t *baseMethods;
+///   const struct _protocol_list_t *baseProtocols;
+///   const struct _ivar_list_t *ivars;
+///   const uint8_t *weakIvarLayout;
+///   const struct _prop_list_t *properties;
+/// }
+
+/// struct _class_t {
+///   struct _class_t *isa;
+///   struct _class_t *superclass;
+///   void *cache;
+///   IMP *vtable;
+///   struct _class_ro_t *ro;
+/// }
+
+/// struct _category_t {
+///   const char *name;
+///   struct _class_t *cls;
+///   const struct _method_list_t *instance_methods;
+///   const struct _method_list_t *class_methods;
+///   const struct _protocol_list_t *protocols;
+///   const struct _prop_list_t *properties;
+/// }
+
+/// MessageRefTy - LLVM for:
+/// struct _message_ref_t {
+///   IMP messenger;
+///   SEL name;
+/// };
+
+/// SuperMessageRefTy - LLVM for:
+/// struct _super_message_ref_t {
+///   SUPER_IMP messenger;
+///   SEL name;
+/// };
+
+static void WriteModernMetadataDeclarations(ASTContext *Context, std::string &Result) {
+  static bool meta_data_declared = false;
+  if (meta_data_declared)
+    return;
+  
+  Result += "\nstruct _prop_t {\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tconst char *attributes;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _protocol_t;\n";
+  
+  Result += "\nstruct _objc_method {\n";
+  Result += "\tstruct objc_selector * _cmd;\n";
+  Result += "\tconst char *method_type;\n";
+  Result += "\tvoid  *_imp;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _protocol_t {\n";
+  Result += "\tvoid * isa;  // NULL\n";
+  Result += "\tconst char *protocol_name;\n";
+  Result += "\tconst struct _protocol_list_t * protocol_list; // super protocols\n";
+  Result += "\tconst struct method_list_t *instance_methods;\n";
+  Result += "\tconst struct method_list_t *class_methods;\n";
+  Result += "\tconst struct method_list_t *optionalInstanceMethods;\n";
+  Result += "\tconst struct method_list_t *optionalClassMethods;\n";
+  Result += "\tconst struct _prop_list_t * properties;\n";
+  Result += "\tconst unsigned int size;  // sizeof(struct _protocol_t)\n";
+  Result += "\tconst unsigned int flags;  // = 0\n";
+  Result += "\tconst char ** extendedMethodTypes;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _ivar_t {\n";
+  Result += "\tunsigned long int *offset;  // pointer to ivar offset location\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tconst char *type;\n";
+  Result += "\tunsigned int alignment;\n";
+  Result += "\tunsigned int  size;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _class_ro_t {\n";
+  Result += "\tunsigned int flags;\n";
+  Result += "\tunsigned int instanceStart;\n";
+  Result += "\tunsigned int instanceSize;\n";
+  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
+  if (Triple.getArch() == llvm::Triple::x86_64)
+    Result += "\tunsigned int reserved;\n";
+  Result += "\tconst unsigned char *ivarLayout;\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tconst struct _method_list_t *baseMethods;\n";
+  Result += "\tconst struct _objc_protocol_list *baseProtocols;\n";
+  Result += "\tconst struct _ivar_list_t *ivars;\n";
+  Result += "\tconst unsigned char *weakIvarLayout;\n";
+  Result += "\tconst struct _prop_list_t *properties;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _class_t {\n";
+  Result += "\tstruct _class_t *isa;\n";
+  Result += "\tstruct _class_t *superclass;\n";
+  Result += "\tvoid *cache;\n";
+  Result += "\tvoid *vtable;\n";
+  Result += "\tstruct _class_ro_t *ro;\n";
+  Result += "};\n";
+  
+  Result += "\nstruct _category_t {\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tstruct _class_t *cls;\n";
+  Result += "\tconst struct _method_list_t *instance_methods;\n";
+  Result += "\tconst struct _method_list_t *class_methods;\n";
+  Result += "\tconst struct _protocol_list_t *protocols;\n";
+  Result += "\tconst struct _prop_list_t *properties;\n";
+  Result += "};\n";
+  
+  Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
+  Result += "#pragma warning(disable:4273)\n";
+  meta_data_declared = true;
+}
+
+static void Write_protocol_list_t_TypeDecl(std::string &Result,
+                                           long super_protocol_count) {
+  Result += "struct /*_protocol_list_t*/"; Result += " {\n";
+  Result += "\tlong protocol_count;  // Note, this is 32/64 bit\n";
+  Result += "\tstruct _protocol_t *super_protocols[";
+  Result += utostr(super_protocol_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write_method_list_t_TypeDecl(std::string &Result,
+                                         unsigned int method_count) {
+  Result += "struct /*_method_list_t*/"; Result += " {\n";
+  Result += "\tunsigned int entsize;  // sizeof(struct _objc_method)\n";
+  Result += "\tunsigned int method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(method_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write__prop_list_t_TypeDecl(std::string &Result,
+                                        unsigned int property_count) {
+  Result += "struct /*_prop_list_t*/"; Result += " {\n";
+  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
+  Result += "\tunsigned int count_of_properties;\n";
+  Result += "\tstruct _prop_t prop_list[";
+  Result += utostr(property_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write__ivar_list_t_TypeDecl(std::string &Result,
+                                        unsigned int ivar_count) {
+  Result += "struct /*_ivar_list_t*/"; Result += " {\n";
+  Result += "\tunsigned int entsize;  // sizeof(struct _prop_t)\n";
+  Result += "\tunsigned int count;\n";
+  Result += "\tstruct _ivar_t ivar_list[";
+  Result += utostr(ivar_count); Result += "];\n";
+  Result += "}";
+}
+
+static void Write_protocol_list_initializer(ASTContext *Context, std::string &Result,
+                                            ArrayRef<ObjCProtocolDecl *> SuperProtocols,
+                                            StringRef VarName,
+                                            StringRef ProtocolName) {
+  if (SuperProtocols.size() > 0) {
+    Result += "\nstatic ";
+    Write_protocol_list_t_TypeDecl(Result, SuperProtocols.size());
+    Result += " "; Result += VarName;
+    Result += ProtocolName; 
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += utostr(SuperProtocols.size()); Result += ",\n";
+    for (unsigned i = 0, e = SuperProtocols.size(); i < e; i++) {
+      ObjCProtocolDecl *SuperPD = SuperProtocols[i];
+      Result += "\t&"; Result += "_OBJC_PROTOCOL_"; 
+      Result += SuperPD->getNameAsString();
+      if (i == e-1)
+        Result += "\n};\n";
+      else
+        Result += ",\n";
+    }
+  }
+}
+
+static void Write_method_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                            ASTContext *Context, std::string &Result,
+                                            ArrayRef<ObjCMethodDecl *> Methods,
+                                            StringRef VarName,
+                                            StringRef TopLevelDeclName,
+                                            bool MethodImpl) {
+  if (Methods.size() > 0) {
+    Result += "\nstatic ";
+    Write_method_list_t_TypeDecl(Result, Methods.size());
+    Result += " "; Result += VarName;
+    Result += TopLevelDeclName; 
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += "sizeof(_objc_method)"; Result += ",\n";
+    Result += "\t"; Result += utostr(Methods.size()); Result += ",\n";
+    for (unsigned i = 0, e = Methods.size(); i < e; i++) {
+      ObjCMethodDecl *MD = Methods[i];
+      if (i == 0)
+        Result += "\t{{(struct objc_selector *)\"";
+      else
+        Result += "\t{(struct objc_selector *)\"";
+      Result += (MD)->getSelector().getAsString(); Result += "\"";
+      Result += ", ";
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl(MD, MethodTypeString);
+      Result += "\""; Result += MethodTypeString; Result += "\"";
+      Result += ", ";
+      if (!MethodImpl)
+        Result += "0";
+      else {
+        Result += "(void *)";
+        Result += RewriteObj.MethodInternalNames[MD];
+      }
+      if (i  == e-1)
+        Result += "}}\n";
+      else
+        Result += "},\n";
+    }
+    Result += "};\n";
+  }
+}
+
+static void Write_prop_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                           ASTContext *Context, std::string &Result,
+                                           ArrayRef<ObjCPropertyDecl *> Properties,
+                                           const Decl *Container,
+                                           StringRef VarName,
+                                           StringRef ProtocolName) {
+  if (Properties.size() > 0) {
+    Result += "\nstatic ";
+    Write__prop_list_t_TypeDecl(Result, Properties.size());
+    Result += " "; Result += VarName;
+    Result += ProtocolName; 
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += "sizeof(_prop_t)"; Result += ",\n";
+    Result += "\t"; Result += utostr(Properties.size()); Result += ",\n";
+    for (unsigned i = 0, e = Properties.size(); i < e; i++) {
+      ObjCPropertyDecl *PropDecl = Properties[i];
+      if (i == 0)
+        Result += "\t{{\"";
+      else
+        Result += "\t{\"";
+      Result += PropDecl->getName(); Result += "\",";
+      std::string PropertyTypeString, QuotePropertyTypeString;
+      Context->getObjCEncodingForPropertyDecl(PropDecl, Container, PropertyTypeString);
+      RewriteObj.QuoteDoublequotes(PropertyTypeString, QuotePropertyTypeString);
+      Result += "\""; Result += QuotePropertyTypeString; Result += "\"";
+      if (i  == e-1)
+        Result += "}}\n";
+      else
+        Result += "},\n";
+    }
+    Result += "};\n";
+  }
+}
+
+// Metadata flags
+enum MetaDataDlags {
+  CLS = 0x0,
+  CLS_META = 0x1,
+  CLS_ROOT = 0x2,
+  OBJC2_CLS_HIDDEN = 0x10,
+  CLS_EXCEPTION = 0x20,
+  
+  /// (Obsolete) ARC-specific: this class has a .release_ivars method
+  CLS_HAS_IVAR_RELEASER = 0x40,
+  /// class was compiled with -fobjc-arr
+  CLS_COMPILED_BY_ARC = 0x80  // (1<<7)
+};
+
+static void Write__class_ro_t_initializer(ASTContext *Context, std::string &Result, 
+                                          unsigned int flags, 
+                                          const std::string &InstanceStart, 
+                                          const std::string &InstanceSize,
+                                          ArrayRef<ObjCMethodDecl *>baseMethods,
+                                          ArrayRef<ObjCProtocolDecl *>baseProtocols,
+                                          ArrayRef<ObjCIvarDecl *>ivars,
+                                          ArrayRef<ObjCPropertyDecl *>Properties,
+                                          StringRef VarName,
+                                          StringRef ClassName) {
+  Result += "\nstatic struct _class_ro_t ";
+  Result += VarName; Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+  Result += "\t"; 
+  Result += llvm::utostr(flags); Result += ", "; 
+  Result += InstanceStart; Result += ", ";
+  Result += InstanceSize; Result += ", \n";
+  Result += "\t";
+  const llvm::Triple &Triple(Context->getTargetInfo().getTriple());
+  if (Triple.getArch() == llvm::Triple::x86_64)
+    // uint32_t const reserved; // only when building for 64bit targets
+    Result += "(unsigned int)0, \n\t";
+  // const uint8_t * const ivarLayout;
+  Result += "0, \n\t";
+  Result += "\""; Result += ClassName; Result += "\",\n\t";
+  bool metaclass = ((flags & CLS_META) != 0);
+  if (baseMethods.size() > 0) {
+    Result += "(const struct _method_list_t *)&";
+    if (metaclass)
+      Result += "_OBJC_$_CLASS_METHODS_";
+    else
+      Result += "_OBJC_$_INSTANCE_METHODS_";
+    Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  if (!metaclass && baseProtocols.size() > 0) {
+    Result += "(const struct _objc_protocol_list *)&";
+    Result += "_OBJC_CLASS_PROTOCOLS_$_"; Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  if (!metaclass && ivars.size() > 0) {
+    Result += "(const struct _ivar_list_t *)&";
+    Result += "_OBJC_$_INSTANCE_VARIABLES_"; Result += ClassName;
+    Result += ",\n\t";
+  }
+  else
+    Result += "0, \n\t";
+
+  // weakIvarLayout
+  Result += "0, \n\t";
+  if (!metaclass && Properties.size() > 0) {
+    Result += "(const struct _prop_list_t *)&";
+    Result += "_OBJC_$_PROP_LIST_"; Result += ClassName;
+    Result += ",\n";
+  }
+  else
+    Result += "0, \n";
+
+  Result += "};\n";
+}
+
+static void Write_class_t(ASTContext *Context, std::string &Result,
+                          StringRef VarName,
+                          const ObjCInterfaceDecl *CDecl, bool metaclass) {
+  bool rootClass = (!CDecl->getSuperClass());
+  const ObjCInterfaceDecl *RootClass = CDecl;
+  
+  if (!rootClass) {
+    // Find the Root class
+    RootClass = CDecl->getSuperClass();
+    while (RootClass->getSuperClass()) {
+      RootClass = RootClass->getSuperClass();
+    }
+  }
+
+  if (metaclass && rootClass) {
+    // Need to handle a case of use of forward declaration.
+    Result += "\n";
+    Result += "extern \"C\" ";
+    if (CDecl->getImplementation())
+      Result += "__declspec(dllexport) ";
+    else
+      Result += "__declspec(dllimport) ";
+    
+    Result += "struct _class_t OBJC_CLASS_$_";
+    Result += CDecl->getNameAsString();
+    Result += ";\n";
+  }
+  // Also, for possibility of 'super' metadata class not having been defined yet.
+  if (!rootClass) {
+    ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
+    Result += "\n";
+    Result += "extern \"C\" ";
+    if (SuperClass->getImplementation())
+      Result += "__declspec(dllexport) ";
+    else
+      Result += "__declspec(dllimport) ";
+
+    Result += "struct _class_t "; 
+    Result += VarName;
+    Result += SuperClass->getNameAsString();
+    Result += ";\n";
+    
+    if (metaclass && RootClass != SuperClass) {
+      Result += "extern \"C\" ";
+      if (RootClass->getImplementation())
+        Result += "__declspec(dllexport) ";
+      else
+        Result += "__declspec(dllimport) ";
+
+      Result += "struct _class_t "; 
+      Result += VarName;
+      Result += RootClass->getNameAsString();
+      Result += ";\n";
+    }
+  }
+  
+  Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 
+  Result += VarName; Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
+  Result += "\t";
+  if (metaclass) {
+    if (!rootClass) {
+      Result += "0, // &"; Result += VarName;
+      Result += RootClass->getNameAsString();
+      Result += ",\n\t";
+      Result += "0, // &"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+    }
+    else {
+      Result += "0, // &"; Result += VarName; 
+      Result += CDecl->getNameAsString();
+      Result += ",\n\t";
+      Result += "0, // &OBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+      Result += ",\n\t";
+    }
+  }
+  else {
+    Result += "0, // &OBJC_METACLASS_$_"; 
+    Result += CDecl->getNameAsString();
+    Result += ",\n\t";
+    if (!rootClass) {
+      Result += "0, // &"; Result += VarName;
+      Result += CDecl->getSuperClass()->getNameAsString();
+      Result += ",\n\t";
+    }
+    else 
+      Result += "0,\n\t";
+  }
+  Result += "0, // (void *)&_objc_empty_cache,\n\t";
+  Result += "0, // unused, was (void *)&_objc_empty_vtable,\n\t";
+  if (metaclass)
+    Result += "&_OBJC_METACLASS_RO_$_";
+  else
+    Result += "&_OBJC_CLASS_RO_$_";
+  Result += CDecl->getNameAsString();
+  Result += ",\n};\n";
+  
+  // Add static function to initialize some of the meta-data fields.
+  // avoid doing it twice.
+  if (metaclass)
+    return;
+  
+  const ObjCInterfaceDecl *SuperClass = 
+    rootClass ? CDecl : CDecl->getSuperClass();
+  
+  Result += "static void OBJC_CLASS_SETUP_$_";
+  Result += CDecl->getNameAsString();
+  Result += "(void ) {\n";
+  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
+  Result += RootClass->getNameAsString(); Result += ";\n";
+  
+  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".superclass = ";
+  if (rootClass)
+    Result += "&OBJC_CLASS_$_";
+  else
+     Result += "&OBJC_METACLASS_$_";
+
+  Result += SuperClass->getNameAsString(); Result += ";\n";
+  
+  Result += "\tOBJC_METACLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
+  
+  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".isa = "; Result += "&OBJC_METACLASS_$_";
+  Result += CDecl->getNameAsString(); Result += ";\n";
+  
+  if (!rootClass) {
+    Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+    Result += ".superclass = "; Result += "&OBJC_CLASS_$_";
+    Result += SuperClass->getNameAsString(); Result += ";\n";
+  }
+  
+  Result += "\tOBJC_CLASS_$_"; Result += CDecl->getNameAsString();
+  Result += ".cache = "; Result += "&_objc_empty_cache"; Result += ";\n";
+  Result += "}\n";
+}
+
+static void Write_category_t(RewriteModernObjC &RewriteObj, ASTContext *Context, 
+                             std::string &Result,
+                             ObjCCategoryDecl *CatDecl,
+                             ObjCInterfaceDecl *ClassDecl,
+                             ArrayRef<ObjCMethodDecl *> InstanceMethods,
+                             ArrayRef<ObjCMethodDecl *> ClassMethods,
+                             ArrayRef<ObjCProtocolDecl *> RefedProtocols,
+                             ArrayRef<ObjCPropertyDecl *> ClassProperties) {
+  StringRef CatName = CatDecl->getName();
+  StringRef ClassName = ClassDecl->getName();
+  // must declare an extern class object in case this class is not implemented 
+  // in this TU.
+  Result += "\n";
+  Result += "extern \"C\" ";
+  if (ClassDecl->getImplementation())
+    Result += "__declspec(dllexport) ";
+  else
+    Result += "__declspec(dllimport) ";
+  
+  Result += "struct _class_t ";
+  Result += "OBJC_CLASS_$_"; Result += ClassName;
+  Result += ";\n";
+  
+  Result += "\nstatic struct _category_t ";
+  Result += "_OBJC_$_CATEGORY_";
+  Result += ClassName; Result += "_$_"; Result += CatName;
+  Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
+  Result += "{\n";
+  Result += "\t\""; Result += ClassName; Result += "\",\n";
+  Result += "\t0, // &"; Result += "OBJC_CLASS_$_"; Result += ClassName;
+  Result += ",\n";
+  if (InstanceMethods.size() > 0) {
+    Result += "\t(const struct _method_list_t *)&";  
+    Result += "_OBJC_$_CATEGORY_INSTANCE_METHODS_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ClassMethods.size() > 0) {
+    Result += "\t(const struct _method_list_t *)&";  
+    Result += "_OBJC_$_CATEGORY_CLASS_METHODS_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (RefedProtocols.size() > 0) {
+    Result += "\t(const struct _protocol_list_t *)&";  
+    Result += "_OBJC_CATEGORY_PROTOCOLS_$_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ClassProperties.size() > 0) {
+    Result += "\t(const struct _prop_list_t *)&";  Result += "_OBJC_$_PROP_LIST_";
+    Result += ClassName; Result += "_$_"; Result += CatName;
+    Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  Result += "};\n";
+  
+  // Add static function to initialize the class pointer in the category structure.
+  Result += "static void OBJC_CATEGORY_SETUP_$_";
+  Result += ClassDecl->getNameAsString();
+  Result += "_$_";
+  Result += CatName;
+  Result += "(void ) {\n";
+  Result += "\t_OBJC_$_CATEGORY_"; 
+  Result += ClassDecl->getNameAsString();
+  Result += "_$_";
+  Result += CatName;
+  Result += ".cls = "; Result += "&OBJC_CLASS_$_"; Result += ClassName;
+  Result += ";\n}\n";
+}
+
+static void Write__extendedMethodTypes_initializer(RewriteModernObjC &RewriteObj,
+                                           ASTContext *Context, std::string &Result,
+                                           ArrayRef<ObjCMethodDecl *> Methods,
+                                           StringRef VarName,
+                                           StringRef ProtocolName) {
+  if (Methods.size() == 0)
+    return;
+  
+  Result += "\nstatic const char *";
+  Result += VarName; Result += ProtocolName;
+  Result += " [] __attribute__ ((used, section (\"__DATA,__objc_const\"))) = \n";
+  Result += "{\n";
+  for (unsigned i = 0, e = Methods.size(); i < e; i++) {
+    ObjCMethodDecl *MD = Methods[i];
+    std::string MethodTypeString, QuoteMethodTypeString;
+    Context->getObjCEncodingForMethodDecl(MD, MethodTypeString, true);
+    RewriteObj.QuoteDoublequotes(MethodTypeString, QuoteMethodTypeString);
+    Result += "\t\""; Result += QuoteMethodTypeString; Result += "\"";
+    if (i == e-1)
+      Result += "\n};\n";
+    else {
+      Result += ",\n";
+    }
+  }
+}
+
+static void Write_IvarOffsetVar(RewriteModernObjC &RewriteObj,
+                                ASTContext *Context,
+                                std::string &Result, 
+                                ArrayRef<ObjCIvarDecl *> Ivars, 
+                                ObjCInterfaceDecl *CDecl) {
+  // FIXME. visibilty of offset symbols may have to be set; for Darwin
+  // this is what happens:
+  /**
+   if (Ivar->getAccessControl() == ObjCIvarDecl::Private ||
+       Ivar->getAccessControl() == ObjCIvarDecl::Package ||
+       Class->getVisibility() == HiddenVisibility)
+     Visibility shoud be: HiddenVisibility;
+   else
+     Visibility shoud be: DefaultVisibility;
+  */
+  
+  Result += "\n";
+  for (unsigned i =0, e = Ivars.size(); i < e; i++) {
+    ObjCIvarDecl *IvarDecl = Ivars[i];
+    if (Context->getLangOpts().MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+    
+    if (!Context->getLangOpts().MicrosoftExt ||
+        IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
+        IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
+      Result += "extern \"C\" unsigned long int "; 
+    else
+      Result += "extern \"C\" __declspec(dllexport) unsigned long int ";
+    if (Ivars[i]->isBitField())
+      RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
+    else
+      WriteInternalIvarName(CDecl, IvarDecl, Result);
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
+    Result += " = ";
+    RewriteObj.RewriteIvarOffsetComputation(IvarDecl, Result);
+    Result += ";\n";
+    if (Ivars[i]->isBitField()) {
+      // skip over rest of the ivar bitfields.
+      SKIP_BITFIELDS(i , e, Ivars);
+    }
+  }
+}
+
+static void Write__ivar_list_t_initializer(RewriteModernObjC &RewriteObj,
+                                           ASTContext *Context, std::string &Result,
+                                           ArrayRef<ObjCIvarDecl *> OriginalIvars,
+                                           StringRef VarName,
+                                           ObjCInterfaceDecl *CDecl) {
+  if (OriginalIvars.size() > 0) {
+    Write_IvarOffsetVar(RewriteObj, Context, Result, OriginalIvars, CDecl);
+    SmallVector<ObjCIvarDecl *, 8> Ivars;
+    // strip off all but the first ivar bitfield from each group of ivars.
+    // Such ivars in the ivar list table will be replaced by their grouping struct
+    // 'ivar'.
+    for (unsigned i = 0, e = OriginalIvars.size(); i < e; i++) {
+      if (OriginalIvars[i]->isBitField()) {
+        Ivars.push_back(OriginalIvars[i]);
+        // skip over rest of the ivar bitfields.
+        SKIP_BITFIELDS(i , e, OriginalIvars);
+      }
+      else
+        Ivars.push_back(OriginalIvars[i]);
+    }
+    
+    Result += "\nstatic ";
+    Write__ivar_list_t_TypeDecl(Result, Ivars.size());
+    Result += " "; Result += VarName;
+    Result += CDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__DATA,__objc_const\"))) = {\n";
+    Result += "\t"; Result += "sizeof(_ivar_t)"; Result += ",\n";
+    Result += "\t"; Result += utostr(Ivars.size()); Result += ",\n";
+    for (unsigned i =0, e = Ivars.size(); i < e; i++) {
+      ObjCIvarDecl *IvarDecl = Ivars[i];
+      if (i == 0)
+        Result += "\t{{";
+      else
+        Result += "\t {";
+      Result += "(unsigned long int *)&";
+      if (Ivars[i]->isBitField())
+        RewriteObj.ObjCIvarBitfieldGroupOffset(IvarDecl, Result);
+      else
+        WriteInternalIvarName(CDecl, IvarDecl, Result);
+      Result += ", ";
+      
+      Result += "\"";
+      if (Ivars[i]->isBitField())
+        RewriteObj.ObjCIvarBitfieldGroupDecl(Ivars[i], Result);
+      else
+        Result += IvarDecl->getName();
+      Result += "\", ";
+      
+      QualType IVQT = IvarDecl->getType();
+      if (IvarDecl->isBitField())
+        IVQT = RewriteObj.GetGroupRecordTypeForObjCIvarBitfield(IvarDecl);
+      
+      std::string IvarTypeString, QuoteIvarTypeString;
+      Context->getObjCEncodingForType(IVQT, IvarTypeString,
+                                      IvarDecl);
+      RewriteObj.QuoteDoublequotes(IvarTypeString, QuoteIvarTypeString);
+      Result += "\""; Result += QuoteIvarTypeString; Result += "\", ";
+      
+      // FIXME. this alignment represents the host alignment and need be changed to
+      // represent the target alignment.
+      unsigned Align = Context->getTypeAlign(IVQT)/8;
+      Align = llvm::Log2_32(Align);
+      Result += llvm::utostr(Align); Result += ", ";
+      CharUnits Size = Context->getTypeSizeInChars(IVQT);
+      Result += llvm::utostr(Size.getQuantity());
+      if (i  == e-1)
+        Result += "}}\n";
+      else
+        Result += "},\n";
+    }
+    Result += "};\n";
+  }
+}
+
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
+void RewriteModernObjC::RewriteObjCProtocolMetaData(ObjCProtocolDecl *PDecl, 
+                                                    std::string &Result) {
+  
+  // Do not synthesize the protocol more than once.
+  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
+    return;
+  WriteModernMetadataDeclarations(Context, Result);
+  
+  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
+    PDecl = Def;
+  // Must write out all protocol definitions in current qualifier list,
+  // and in their nested qualifiers before writing out current definition.
+  for (auto *I : PDecl->protocols())
+    RewriteObjCProtocolMetaData(I, Result);
+  
+  // Construct method lists.
+  std::vector<ObjCMethodDecl *> InstanceMethods, ClassMethods;
+  std::vector<ObjCMethodDecl *> OptInstanceMethods, OptClassMethods;
+  for (auto *MD : PDecl->instance_methods()) {
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptInstanceMethods.push_back(MD);
+    } else {
+      InstanceMethods.push_back(MD);
+    }
+  }
+  
+  for (auto *MD : PDecl->class_methods()) {
+    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
+      OptClassMethods.push_back(MD);
+    } else {
+      ClassMethods.push_back(MD);
+    }
+  }
+  std::vector<ObjCMethodDecl *> AllMethods;
+  for (unsigned i = 0, e = InstanceMethods.size(); i < e; i++)
+    AllMethods.push_back(InstanceMethods[i]);
+  for (unsigned i = 0, e = ClassMethods.size(); i < e; i++)
+    AllMethods.push_back(ClassMethods[i]);
+  for (unsigned i = 0, e = OptInstanceMethods.size(); i < e; i++)
+    AllMethods.push_back(OptInstanceMethods[i]);
+  for (unsigned i = 0, e = OptClassMethods.size(); i < e; i++)
+    AllMethods.push_back(OptClassMethods[i]);
+
+  Write__extendedMethodTypes_initializer(*this, Context, Result,
+                                         AllMethods,
+                                         "_OBJC_PROTOCOL_METHOD_TYPES_",
+                                         PDecl->getNameAsString());
+  // Protocol's super protocol list
+  SmallVector<ObjCProtocolDecl *, 8> SuperProtocols(PDecl->protocols());  
+  Write_protocol_list_initializer(Context, Result, SuperProtocols,
+                                  "_OBJC_PROTOCOL_REFS_",
+                                  PDecl->getNameAsString());
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods, 
+                                  "_OBJC_PROTOCOL_INSTANCE_METHODS_",
+                                  PDecl->getNameAsString(), false);
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods, 
+                                  "_OBJC_PROTOCOL_CLASS_METHODS_",
+                                  PDecl->getNameAsString(), false);
+
+  Write_method_list_t_initializer(*this, Context, Result, OptInstanceMethods, 
+                                  "_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_",
+                                  PDecl->getNameAsString(), false);
+  
+  Write_method_list_t_initializer(*this, Context, Result, OptClassMethods, 
+                                  "_OBJC_PROTOCOL_OPT_CLASS_METHODS_",
+                                  PDecl->getNameAsString(), false);
+  
+  // Protocol's property metadata.
+  SmallVector<ObjCPropertyDecl *, 8> ProtocolProperties(PDecl->properties());
+  Write_prop_list_t_initializer(*this, Context, Result, ProtocolProperties,
+                                 /* Container */nullptr,
+                                 "_OBJC_PROTOCOL_PROPERTIES_",
+                                 PDecl->getNameAsString());
+
+  // Writer out root metadata for current protocol: struct _protocol_t
+  Result += "\n";
+  if (LangOpts.MicrosoftExt)
+    Result += "static ";
+  Result += "struct _protocol_t _OBJC_PROTOCOL_";
+  Result += PDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__DATA,__datacoal_nt,coalesced\"))) = {\n";
+  Result += "\t0,\n"; // id is; is null
+  Result += "\t\""; Result += PDecl->getNameAsString(); Result += "\",\n";
+  if (SuperProtocols.size() > 0) {
+    Result += "\t(const struct _protocol_list_t *)&"; Result += "_OBJC_PROTOCOL_REFS_";
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  if (InstanceMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_INSTANCE_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+
+  if (ClassMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_CLASS_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (OptInstanceMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_INSTANCE_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (OptClassMethods.size() > 0) {
+    Result += "\t(const struct method_list_t *)&_OBJC_PROTOCOL_OPT_CLASS_METHODS_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  if (ProtocolProperties.size() > 0) {
+    Result += "\t(const struct _prop_list_t *)&_OBJC_PROTOCOL_PROPERTIES_"; 
+    Result += PDecl->getNameAsString(); Result += ",\n";
+  }
+  else
+    Result += "\t0,\n";
+  
+  Result += "\t"; Result += "sizeof(_protocol_t)"; Result += ",\n";
+  Result += "\t0,\n";
+  
+  if (AllMethods.size() > 0) {
+    Result += "\t(const char **)&"; Result += "_OBJC_PROTOCOL_METHOD_TYPES_";
+    Result += PDecl->getNameAsString();
+    Result += "\n};\n";
+  }
+  else
+    Result += "\t0\n};\n";
+  
+  if (LangOpts.MicrosoftExt)
+    Result += "static ";
+  Result += "struct _protocol_t *";
+  Result += "_OBJC_LABEL_PROTOCOL_$_"; Result += PDecl->getNameAsString();
+  Result += " = &_OBJC_PROTOCOL_"; Result += PDecl->getNameAsString();
+  Result += ";\n";
+    
+  // Mark this protocol as having been generated.
+  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second)
+    llvm_unreachable("protocol already synthesized");
+  
+}
+
+void RewriteModernObjC::RewriteObjCProtocolListMetaData(
+                                const ObjCList<ObjCProtocolDecl> &Protocols,
+                                StringRef prefix, StringRef ClassName,
+                                std::string &Result) {
+  if (Protocols.empty()) return;
+  
+  for (unsigned i = 0; i != Protocols.size(); i++)
+    RewriteObjCProtocolMetaData(Protocols[i], Result);
+  
+  // Output the top lovel protocol meta-data for the class.
+  /* struct _objc_protocol_list {
+   struct _objc_protocol_list *next;
+   int    protocol_count;
+   struct _objc_protocol *class_protocols[];
+   }
+   */
+  Result += "\n";
+  if (LangOpts.MicrosoftExt)
+    Result += "__declspec(allocate(\".cat_cls_meth$B\")) ";
+  Result += "static struct {\n";
+  Result += "\tstruct _objc_protocol_list *next;\n";
+  Result += "\tint    protocol_count;\n";
+  Result += "\tstruct _objc_protocol *class_protocols[";
+  Result += utostr(Protocols.size());
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += "_PROTOCOLS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+  "{\n\t0, ";
+  Result += utostr(Protocols.size());
+  Result += "\n";
+  
+  Result += "\t,{&_OBJC_PROTOCOL_";
+  Result += Protocols[0]->getNameAsString();
+  Result += " \n";
+  
+  for (unsigned i = 1; i != Protocols.size(); i++) {
+    Result += "\t ,&_OBJC_PROTOCOL_";
+    Result += Protocols[i]->getNameAsString();
+    Result += "\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+/// hasObjCExceptionAttribute - Return true if this class or any super
+/// class has the __objc_exception__ attribute.
+/// FIXME. Move this to ASTContext.cpp as it is also used for IRGen.
+static bool hasObjCExceptionAttribute(ASTContext &Context,
+                                      const ObjCInterfaceDecl *OID) {
+  if (OID->hasAttr<ObjCExceptionAttr>())
+    return true;
+  if (const ObjCInterfaceDecl *Super = OID->getSuperClass())
+    return hasObjCExceptionAttribute(Context, Super);
+  return false;
+}
+
+void RewriteModernObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                           std::string &Result) {
+  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+  
+  // Explicitly declared @interface's are already synthesized.
+  if (CDecl->isImplicitInterfaceDecl())
+    assert(false && 
+           "Legacy implicit interface rewriting not supported in moder abi");
+  
+  WriteModernMetadataDeclarations(Context, Result);
+  SmallVector<ObjCIvarDecl *, 8> IVars;
+  
+  for (ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+      IVD; IVD = IVD->getNextIvar()) {
+    // Ignore unnamed bit-fields.
+    if (!IVD->getDeclName())
+      continue;
+    IVars.push_back(IVD);
+  }
+  
+  Write__ivar_list_t_initializer(*this, Context, Result, IVars, 
+                                 "_OBJC_$_INSTANCE_VARIABLES_",
+                                 CDecl);
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      if (mustSynthesizeSetterGetterMethod(IDecl, PD, true /*getter*/))
+        InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      if (mustSynthesizeSetterGetterMethod(IDecl, PD, false /*setter*/))
+        InstanceMethods.push_back(Setter);
+  }
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
+                                  "_OBJC_$_INSTANCE_METHODS_",
+                                  IDecl->getNameAsString(), true);
+  
+  SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->class_methods());
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
+                                  "_OBJC_$_CLASS_METHODS_",
+                                  IDecl->getNameAsString(), true);
+  
+  // Protocols referenced in class declaration?
+  // Protocol's super protocol list
+  std::vector<ObjCProtocolDecl *> RefedProtocols;
+  const ObjCList<ObjCProtocolDecl> &Protocols = CDecl->getReferencedProtocols();
+  for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
+       E = Protocols.end();
+       I != E; ++I) {
+    RefedProtocols.push_back(*I);
+    // Must write out all protocol definitions in current qualifier list,
+    // and in their nested qualifiers before writing out current definition.
+    RewriteObjCProtocolMetaData(*I, Result);
+  }
+  
+  Write_protocol_list_initializer(Context, Result, 
+                                  RefedProtocols,
+                                  "_OBJC_CLASS_PROTOCOLS_$_",
+                                  IDecl->getNameAsString());
+  
+  // Protocol's property metadata.
+  SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties());
+  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
+                                 /* Container */IDecl,
+                                 "_OBJC_$_PROP_LIST_",
+                                 CDecl->getNameAsString());
+
+  
+  // Data for initializing _class_ro_t  metaclass meta-data
+  uint32_t flags = CLS_META;
+  std::string InstanceSize;
+  std::string InstanceStart;
+  
+  
+  bool classIsHidden = CDecl->getVisibility() == HiddenVisibility;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  
+  if (!CDecl->getSuperClass())
+    // class is root
+    flags |= CLS_ROOT;
+  InstanceSize = "sizeof(struct _class_t)";
+  InstanceStart = InstanceSize;
+  Write__class_ro_t_initializer(Context, Result, flags, 
+                                InstanceStart, InstanceSize,
+                                ClassMethods,
+                                nullptr,
+                                nullptr,
+                                nullptr,
+                                "_OBJC_METACLASS_RO_$_",
+                                CDecl->getNameAsString());
+
+  // Data for initializing _class_ro_t meta-data
+  flags = CLS;
+  if (classIsHidden)
+    flags |= OBJC2_CLS_HIDDEN;
+  
+  if (hasObjCExceptionAttribute(*Context, CDecl))
+    flags |= CLS_EXCEPTION;
+
+  if (!CDecl->getSuperClass())
+    // class is root
+    flags |= CLS_ROOT;
+  
+  InstanceSize.clear();
+  InstanceStart.clear();
+  if (!ObjCSynthesizedStructs.count(CDecl)) {
+    InstanceSize = "0";
+    InstanceStart = "0";
+  }
+  else {
+    InstanceSize = "sizeof(struct ";
+    InstanceSize += CDecl->getNameAsString();
+    InstanceSize += "_IMPL)";
+    
+    ObjCIvarDecl *IVD = CDecl->all_declared_ivar_begin();
+    if (IVD) {
+      RewriteIvarOffsetComputation(IVD, InstanceStart);
+    }
+    else 
+      InstanceStart = InstanceSize;
+  }
+  Write__class_ro_t_initializer(Context, Result, flags, 
+                                InstanceStart, InstanceSize,
+                                InstanceMethods,
+                                RefedProtocols,
+                                IVars,
+                                ClassProperties,
+                                "_OBJC_CLASS_RO_$_",
+                                CDecl->getNameAsString());
+  
+  Write_class_t(Context, Result,
+                "OBJC_METACLASS_$_",
+                CDecl, /*metaclass*/true);
+  
+  Write_class_t(Context, Result,
+                "OBJC_CLASS_$_",
+                CDecl, /*metaclass*/false);
+  
+  if (ImplementationIsNonLazy(IDecl))
+    DefinedNonLazyClasses.push_back(CDecl);
+                
+}
+
+void RewriteModernObjC::RewriteClassSetupInitHook(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  if (!ClsDefCount)
+    return;
+  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
+  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
+  Result += "static void *OBJC_CLASS_SETUP[] = {\n";
+  for (int i = 0; i < ClsDefCount; i++) {
+    ObjCImplementationDecl *IDecl = ClassImplementation[i];
+    ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+    Result += "\t(void *)&OBJC_CLASS_SETUP_$_";
+    Result  += CDecl->getName(); Result += ",\n";
+  }
+  Result += "};\n";
+}
+
+void RewriteModernObjC::RewriteMetaDataIntoBuffer(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+  
+  // For each implemented class, write out all its meta data.
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteObjCClassMetaData(ClassImplementation[i], Result);
+  
+  RewriteClassSetupInitHook(Result);
+  
+  // For each implemented category, write out all its meta data.
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+  
+  RewriteCategorySetupInitHook(Result);
+  
+  if (ClsDefCount > 0) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_classlist$B\")) ";
+    Result += "static struct _class_t *L_OBJC_LABEL_CLASS_$ [";
+    Result += llvm::utostr(ClsDefCount); Result += "]";
+    Result += 
+      " __attribute__((used, section (\"__DATA, __objc_classlist,"
+      "regular,no_dead_strip\")))= {\n";
+    for (int i = 0; i < ClsDefCount; i++) {
+      Result += "\t&OBJC_CLASS_$_";
+      Result += ClassImplementation[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+    
+    if (!DefinedNonLazyClasses.empty()) {
+      if (LangOpts.MicrosoftExt)
+        Result += "__declspec(allocate(\".objc_nlclslist$B\")) \n";
+      Result += "static struct _class_t *_OBJC_LABEL_NONLAZY_CLASS_$[] = {\n\t";
+      for (unsigned i = 0, e = DefinedNonLazyClasses.size(); i < e; i++) {
+        Result += "\t&OBJC_CLASS_$_"; Result += DefinedNonLazyClasses[i]->getNameAsString();
+        Result += ",\n";
+      }
+      Result += "};\n";
+    }
+  }
+  
+  if (CatDefCount > 0) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_catlist$B\")) ";
+    Result += "static struct _category_t *L_OBJC_LABEL_CATEGORY_$ [";
+    Result += llvm::utostr(CatDefCount); Result += "]";
+    Result += 
+    " __attribute__((used, section (\"__DATA, __objc_catlist,"
+    "regular,no_dead_strip\")))= {\n";
+    for (int i = 0; i < CatDefCount; i++) {
+      Result += "\t&_OBJC_$_CATEGORY_";
+      Result += 
+        CategoryImplementation[i]->getClassInterface()->getNameAsString(); 
+      Result += "_$_";
+      Result += CategoryImplementation[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+  }
+  
+  if (!DefinedNonLazyCategories.empty()) {
+    if (LangOpts.MicrosoftExt)
+      Result += "__declspec(allocate(\".objc_nlcatlist$B\")) \n";
+    Result += "static struct _category_t *_OBJC_LABEL_NONLAZY_CATEGORY_$[] = {\n\t";
+    for (unsigned i = 0, e = DefinedNonLazyCategories.size(); i < e; i++) {
+      Result += "\t&_OBJC_$_CATEGORY_";
+      Result += 
+        DefinedNonLazyCategories[i]->getClassInterface()->getNameAsString(); 
+      Result += "_$_";
+      Result += DefinedNonLazyCategories[i]->getNameAsString();
+      Result += ",\n";
+    }
+    Result += "};\n";
+  }
+}
+
+void RewriteModernObjC::WriteImageInfo(std::string &Result) {
+  if (LangOpts.MicrosoftExt)
+    Result += "__declspec(allocate(\".objc_imageinfo$B\")) \n";
+  
+  Result += "static struct IMAGE_INFO { unsigned version; unsigned flag; } ";
+  // version 0, ObjCABI is 2
+  Result += "_OBJC_IMAGE_INFO = { 0, 2 };\n";
+}
+
+/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
+/// implementation.
+void RewriteModernObjC::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
+                                              std::string &Result) {
+  WriteModernMetadataDeclarations(Context, Result);
+  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+  // Find category declaration for this implementation.
+  ObjCCategoryDecl *CDecl
+    = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier());
+  
+  std::string FullCategoryName = ClassDecl->getNameAsString();
+  FullCategoryName += "_$_";
+  FullCategoryName += CDecl->getNameAsString();
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  
+  Write_method_list_t_initializer(*this, Context, Result, InstanceMethods,
+                                  "_OBJC_$_CATEGORY_INSTANCE_METHODS_",
+                                  FullCategoryName, true);
+  
+  SmallVector<ObjCMethodDecl *, 32> ClassMethods(IDecl->class_methods());
+  
+  Write_method_list_t_initializer(*this, Context, Result, ClassMethods,
+                                  "_OBJC_$_CATEGORY_CLASS_METHODS_",
+                                  FullCategoryName, true);
+  
+  // Protocols referenced in class declaration?
+  // Protocol's super protocol list
+  SmallVector<ObjCProtocolDecl *, 8> RefedProtocols(CDecl->protocols());
+  for (auto *I : CDecl->protocols())
+    // Must write out all protocol definitions in current qualifier list,
+    // and in their nested qualifiers before writing out current definition.
+    RewriteObjCProtocolMetaData(I, Result);
+  
+  Write_protocol_list_initializer(Context, Result, 
+                                  RefedProtocols,
+                                  "_OBJC_CATEGORY_PROTOCOLS_$_",
+                                  FullCategoryName);
+  
+  // Protocol's property metadata.
+  SmallVector<ObjCPropertyDecl *, 8> ClassProperties(CDecl->properties());
+  Write_prop_list_t_initializer(*this, Context, Result, ClassProperties,
+                                /* Container */IDecl,
+                                "_OBJC_$_PROP_LIST_",
+                                FullCategoryName);
+  
+  Write_category_t(*this, Context, Result,
+                   CDecl,
+                   ClassDecl,
+                   InstanceMethods,
+                   ClassMethods,
+                   RefedProtocols,
+                   ClassProperties);
+  
+  // Determine if this category is also "non-lazy".
+  if (ImplementationIsNonLazy(IDecl))
+    DefinedNonLazyCategories.push_back(CDecl);
+    
+}
+
+void RewriteModernObjC::RewriteCategorySetupInitHook(std::string &Result) {
+  int CatDefCount = CategoryImplementation.size();
+  if (!CatDefCount)
+    return;
+  Result += "#pragma section(\".objc_inithooks$B\", long, read, write)\n";
+  Result += "__declspec(allocate(\".objc_inithooks$B\")) ";
+  Result += "static void *OBJC_CATEGORY_SETUP[] = {\n";
+  for (int i = 0; i < CatDefCount; i++) {
+    ObjCCategoryImplDecl *IDecl = CategoryImplementation[i];
+    ObjCCategoryDecl *CatDecl= IDecl->getCategoryDecl();
+    ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+    Result += "\t(void *)&OBJC_CATEGORY_SETUP_$_";
+    Result += ClassDecl->getName();
+    Result += "_$_";
+    Result += CatDecl->getName();
+    Result += ",\n";
+  }
+  Result += "};\n";
+}
+
+// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
+/// class methods.
+template<typename MethodIterator>
+void RewriteModernObjC::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                             MethodIterator MethodEnd,
+                                             bool IsInstanceMethod,
+                                             StringRef prefix,
+                                             StringRef ClassName,
+                                             std::string &Result) {
+  if (MethodBegin == MethodEnd) return;
+  
+  if (!objc_impl_method) {
+    /* struct _objc_method {
+     SEL _cmd;
+     char *method_types;
+     void *_imp;
+     }
+     */
+    Result += "\nstruct _objc_method {\n";
+    Result += "\tSEL _cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "\tvoid *_imp;\n";
+    Result += "};\n";
+    
+    objc_impl_method = true;
+  }
+  
+  // Build _objc_method_list for class's methods if needed
+  
+  /* struct  {
+   struct _objc_method_list *next_method;
+   int method_count;
+   struct _objc_method method_list[];
+   }
+   */
+  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
+  Result += "\n";
+  if (LangOpts.MicrosoftExt) {
+    if (IsInstanceMethod)
+      Result += "__declspec(allocate(\".inst_meth$B\")) ";
+    else
+      Result += "__declspec(allocate(\".cls_meth$B\")) ";
+  }
+  Result += "static struct {\n";
+  Result += "\tstruct _objc_method_list *next_method;\n";
+  Result += "\tint method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(NumMethods);
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
+  Result += "_METHODS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __";
+  Result += IsInstanceMethod ? "inst" : "cls";
+  Result += "_meth\")))= ";
+  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
+  
+  Result += "\t,{{(SEL)\"";
+  Result += (*MethodBegin)->getSelector().getAsString().c_str();
+  std::string MethodTypeString;
+  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+  Result += "\", \"";
+  Result += MethodTypeString;
+  Result += "\", (void *)";
+  Result += MethodInternalNames[*MethodBegin];
+  Result += "}\n";
+  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
+    Result += "\t  ,{(SEL)\"";
+    Result += (*MethodBegin)->getSelector().getAsString().c_str();
+    std::string MethodTypeString;
+    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+    Result += "\", \"";
+    Result += MethodTypeString;
+    Result += "\", (void *)";
+    Result += MethodInternalNames[*MethodBegin];
+    Result += "}\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
+  SourceRange OldRange = IV->getSourceRange();
+  Expr *BaseExpr = IV->getBase();
+  
+  // Rewrite the base, but without actually doing replaces.
+  {
+    DisableReplaceStmtScope S(*this);
+    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
+    IV->setBase(BaseExpr);
+  }
+  
+  ObjCIvarDecl *D = IV->getDecl();
+  
+  Expr *Replacement = IV;
+  
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      const ObjCInterfaceType *iFaceDecl =
+        dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = nullptr;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Build name of symbol holding ivar offset.
+      std::string IvarOffsetName;
+      if (D->isBitField())
+        ObjCIvarBitfieldGroupOffset(D, IvarOffsetName);
+      else
+        WriteInternalIvarName(clsDeclared, D, IvarOffsetName);
+      
+      ReferencedIvars[clsDeclared].insert(D);
+      
+      // cast offset to "char *".
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, 
+                                                    Context->getPointerType(Context->CharTy),
+                                                    CK_BitCast,
+                                                    BaseExpr);
+      VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                       SourceLocation(), &Context->Idents.get(IvarOffsetName),
+                                       Context->UnsignedLongTy, nullptr,
+                                       SC_Extern);
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false,
+                                                   Context->UnsignedLongTy, VK_LValue,
+                                                   SourceLocation());
+      BinaryOperator *addExpr = 
+        new (Context) BinaryOperator(castExpr, DRE, BO_Add, 
+                                     Context->getPointerType(Context->CharTy),
+                                     VK_RValue, OK_Ordinary, SourceLocation(), false);
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
+                                              SourceLocation(),
+                                              addExpr);
+      QualType IvarT = D->getType();
+      if (D->isBitField())
+        IvarT = GetGroupRecordTypeForObjCIvarBitfield(D);
+
+      if (!isa<TypedefType>(IvarT) && IvarT->isRecordType()) {
+        RecordDecl *RD = IvarT->getAs<RecordType>()->getDecl();
+        RD = RD->getDefinition();
+        if (RD && !RD->getDeclName().getAsIdentifierInfo()) {
+          // decltype(((Foo_IMPL*)0)->bar) *
+          ObjCContainerDecl *CDecl = 
+            dyn_cast<ObjCContainerDecl>(D->getDeclContext());
+          // ivar in class extensions requires special treatment.
+          if (ObjCCategoryDecl *CatDecl = dyn_cast<ObjCCategoryDecl>(CDecl))
+            CDecl = CatDecl->getClassInterface();
+          std::string RecName = CDecl->getName();
+          RecName += "_IMPL";
+          RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                              SourceLocation(), SourceLocation(),
+                                              &Context->Idents.get(RecName.c_str()));
+          QualType PtrStructIMPL = Context->getPointerType(Context->getTagDeclType(RD));
+          unsigned UnsignedIntSize = 
+            static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+          Expr *Zero = IntegerLiteral::Create(*Context,
+                                              llvm::APInt(UnsignedIntSize, 0),
+                                              Context->UnsignedIntTy, SourceLocation());
+          Zero = NoTypeInfoCStyleCastExpr(Context, PtrStructIMPL, CK_BitCast, Zero);
+          ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                                  Zero);
+          FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                            SourceLocation(),
+                                            &Context->Idents.get(D->getNameAsString()),
+                                            IvarT, nullptr,
+                                            /*BitWidth=*/nullptr,
+                                            /*Mutable=*/true, ICIS_NoInit);
+          MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                                    FD->getType(), VK_LValue,
+                                                    OK_Ordinary);
+          IvarT = Context->getDecltypeType(ME, ME->getType());
+        }
+      }
+      convertObjCTypeToCStyleType(IvarT);
+      QualType castT = Context->getPointerType(IvarT);
+          
+      castExpr = NoTypeInfoCStyleCastExpr(Context, 
+                                          castT,
+                                          CK_BitCast,
+                                          PE);
+      
+      
+      Expr *Exp = new (Context) UnaryOperator(castExpr, UO_Deref, IvarT,
+                                              VK_LValue, OK_Ordinary,
+                                              SourceLocation());
+      PE = new (Context) ParenExpr(OldRange.getBegin(),
+                                   OldRange.getEnd(),
+                                   Exp);
+      
+      if (D->isBitField()) {
+        FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                          SourceLocation(),
+                                          &Context->Idents.get(D->getNameAsString()),
+                                          D->getType(), nullptr,
+                                          /*BitWidth=*/D->getBitWidth(),
+                                          /*Mutable=*/true, ICIS_NoInit);
+        MemberExpr *ME = new (Context) MemberExpr(PE, /*isArrow*/false, FD, SourceLocation(),
+                                                  FD->getType(), VK_LValue,
+                                                  OK_Ordinary);
+        Replacement = ME;
+
+      }
+      else
+        Replacement = PE;
+    }
+  
+    ReplaceStmtWithRange(IV, Replacement, OldRange);
+    return Replacement;  
+}
+
+#endif
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
new file mode 100644
index 0000000..5fb2374
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -0,0 +1,5935 @@
+//===--- RewriteObjC.cpp - Playground for the code rewriter ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hacks and fun related to the code rewriter.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/ASTConsumers.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/Attr.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <memory>
+
+#ifdef CLANG_ENABLE_OBJC_REWRITER
+
+using namespace clang;
+using llvm::utostr;
+
+namespace {
+  class RewriteObjC : public ASTConsumer {
+  protected:
+    
+    enum {
+      BLOCK_FIELD_IS_OBJECT   =  3,  /* id, NSObject, __attribute__((NSObject)),
+                                        block, ... */
+      BLOCK_FIELD_IS_BLOCK    =  7,  /* a block variable */
+      BLOCK_FIELD_IS_BYREF    =  8,  /* the on stack structure holding the 
+                                        __block variable */
+      BLOCK_FIELD_IS_WEAK     = 16,  /* declared __weak, only used in byref copy
+                                        helpers */
+      BLOCK_BYREF_CALLER      = 128, /* called from __block (byref) copy/dispose
+                                        support routines */
+      BLOCK_BYREF_CURRENT_MAX = 256
+    };
+    
+    enum {
+      BLOCK_NEEDS_FREE =        (1 << 24),
+      BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
+      BLOCK_HAS_CXX_OBJ =       (1 << 26),
+      BLOCK_IS_GC =             (1 << 27),
+      BLOCK_IS_GLOBAL =         (1 << 28),
+      BLOCK_HAS_DESCRIPTOR =    (1 << 29)
+    };
+    static const int OBJC_ABI_VERSION = 7;
+    
+    Rewriter Rewrite;
+    DiagnosticsEngine &Diags;
+    const LangOptions &LangOpts;
+    ASTContext *Context;
+    SourceManager *SM;
+    TranslationUnitDecl *TUDecl;
+    FileID MainFileID;
+    const char *MainFileStart, *MainFileEnd;
+    Stmt *CurrentBody;
+    ParentMap *PropParentMap; // created lazily.
+    std::string InFileName;
+    raw_ostream* OutFile;
+    std::string Preamble;
+    
+    TypeDecl *ProtocolTypeDecl;
+    VarDecl *GlobalVarDecl;
+    unsigned RewriteFailedDiag;
+    // ObjC string constant support.
+    unsigned NumObjCStringLiterals;
+    VarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+
+    // ObjC foreach break/continue generation support.
+    int BcLabelCount;
+    
+    unsigned TryFinallyContainsReturnDiag;
+    // Needed for super.
+    ObjCMethodDecl *CurMethodDef;
+    RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
+    
+    FunctionDecl *MsgSendFunctionDecl;
+    FunctionDecl *MsgSendSuperFunctionDecl;
+    FunctionDecl *MsgSendStretFunctionDecl;
+    FunctionDecl *MsgSendSuperStretFunctionDecl;
+    FunctionDecl *MsgSendFpretFunctionDecl;
+    FunctionDecl *GetClassFunctionDecl;
+    FunctionDecl *GetMetaClassFunctionDecl;
+    FunctionDecl *GetSuperClassFunctionDecl;
+    FunctionDecl *SelGetUidFunctionDecl;
+    FunctionDecl *CFStringFunctionDecl;
+    FunctionDecl *SuperConstructorFunctionDecl;
+    FunctionDecl *CurFunctionDef;
+    FunctionDecl *CurFunctionDeclToDeclareForBlock;
+
+    /* Misc. containers needed for meta-data rewrite. */
+    SmallVector<ObjCImplementationDecl *, 8> ClassImplementation;
+    SmallVector<ObjCCategoryImplDecl *, 8> CategoryImplementation;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCSynthesizedStructs;
+    llvm::SmallPtrSet<ObjCProtocolDecl*, 8> ObjCSynthesizedProtocols;
+    llvm::SmallPtrSet<ObjCInterfaceDecl*, 8> ObjCForwardDecls;
+    llvm::DenseMap<ObjCMethodDecl*, std::string> MethodInternalNames;
+    SmallVector<Stmt *, 32> Stmts;
+    SmallVector<int, 8> ObjCBcLabelNo;
+    // Remember all the @protocol(<expr>) expressions.
+    llvm::SmallPtrSet<ObjCProtocolDecl *, 32> ProtocolExprDecls;
+    
+    llvm::DenseSet<uint64_t> CopyDestroyCache;
+
+    // Block expressions.
+    SmallVector<BlockExpr *, 32> Blocks;
+    SmallVector<int, 32> InnerDeclRefsCount;
+    SmallVector<DeclRefExpr *, 32> InnerDeclRefs;
+    
+    SmallVector<DeclRefExpr *, 32> BlockDeclRefs;
+
+    // Block related declarations.
+    SmallVector<ValueDecl *, 8> BlockByCopyDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByCopyDeclsPtrSet;
+    SmallVector<ValueDecl *, 8> BlockByRefDecls;
+    llvm::SmallPtrSet<ValueDecl *, 8> BlockByRefDeclsPtrSet;
+    llvm::DenseMap<ValueDecl *, unsigned> BlockByRefDeclNo;
+    llvm::SmallPtrSet<ValueDecl *, 8> ImportedBlockDecls;
+    llvm::SmallPtrSet<VarDecl *, 8> ImportedLocalExternalDecls;
+    
+    llvm::DenseMap<BlockExpr *, std::string> RewrittenBlockExprs;
+
+    // This maps an original source AST to it's rewritten form. This allows
+    // us to avoid rewriting the same node twice (which is very uncommon).
+    // This is needed to support some of the exotic property rewriting.
+    llvm::DenseMap<Stmt *, Stmt *> ReplacedNodes;
+
+    // Needed for header files being rewritten
+    bool IsHeader;
+    bool SilenceRewriteMacroWarning;
+    bool objc_impl_method;
+    
+    bool DisableReplaceStmt;
+    class DisableReplaceStmtScope {
+      RewriteObjC &R;
+      bool SavedValue;
+    
+    public:
+      DisableReplaceStmtScope(RewriteObjC &R)
+        : R(R), SavedValue(R.DisableReplaceStmt) {
+        R.DisableReplaceStmt = true;
+      }
+      ~DisableReplaceStmtScope() {
+        R.DisableReplaceStmt = SavedValue;
+      }
+    };
+    void InitializeCommon(ASTContext &context);
+
+  public:
+
+    // Top Level Driver code.
+    bool HandleTopLevelDecl(DeclGroupRef D) override {
+      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+        if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*I)) {
+          if (!Class->isThisDeclarationADefinition()) {
+            RewriteForwardClassDecl(D);
+            break;
+          }
+        }
+
+        if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*I)) {
+          if (!Proto->isThisDeclarationADefinition()) {
+            RewriteForwardProtocolDecl(D);
+            break;
+          }
+        }
+
+        HandleTopLevelSingleDecl(*I);
+      }
+      return true;
+    }
+    void HandleTopLevelSingleDecl(Decl *D);
+    void HandleDeclInMainFile(Decl *D);
+    RewriteObjC(std::string inFile, raw_ostream *OS,
+                DiagnosticsEngine &D, const LangOptions &LOpts,
+                bool silenceMacroWarn);
+
+    ~RewriteObjC() {}
+
+    void HandleTranslationUnit(ASTContext &C) override;
+
+    void ReplaceStmt(Stmt *Old, Stmt *New) {
+      ReplaceStmtWithRange(Old, New, Old->getSourceRange());
+    }
+
+    void ReplaceStmtWithRange(Stmt *Old, Stmt *New, SourceRange SrcRange) {
+      assert(Old != nullptr && New != nullptr && "Expected non-null Stmt's");
+
+      Stmt *ReplacingStmt = ReplacedNodes[Old];
+      if (ReplacingStmt)
+        return; // We can't rewrite the same node twice.
+
+      if (DisableReplaceStmt)
+        return;
+
+      // Measure the old text.
+      int Size = Rewrite.getRangeSize(SrcRange);
+      if (Size == -1) {
+        Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                     << Old->getSourceRange();
+        return;
+      }
+      // Get the new text.
+      std::string SStr;
+      llvm::raw_string_ostream S(SStr);
+      New->printPretty(S, nullptr, PrintingPolicy(LangOpts));
+      const std::string &Str = S.str();
+
+      // If replacement succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(SrcRange.getBegin(), Size, Str)) {
+        ReplacedNodes[Old] = New;
+        return;
+      }
+      if (SilenceRewriteMacroWarning)
+        return;
+      Diags.Report(Context->getFullLoc(Old->getLocStart()), RewriteFailedDiag)
+                   << Old->getSourceRange();
+    }
+
+    void InsertText(SourceLocation Loc, StringRef Str,
+                    bool InsertAfter = true) {
+      // If insertion succeeded or warning disabled return with no warning.
+      if (!Rewrite.InsertText(Loc, Str, InsertAfter) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Loc), RewriteFailedDiag);
+    }
+
+    void ReplaceText(SourceLocation Start, unsigned OrigLength,
+                     StringRef Str) {
+      // If removal succeeded or warning disabled return with no warning.
+      if (!Rewrite.ReplaceText(Start, OrigLength, Str) ||
+          SilenceRewriteMacroWarning)
+        return;
+
+      Diags.Report(Context->getFullLoc(Start), RewriteFailedDiag);
+    }
+
+    // Syntactic Rewriting.
+    void RewriteRecordBody(RecordDecl *RD);
+    void RewriteInclude();
+    void RewriteForwardClassDecl(DeclGroupRef D);
+    void RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl, 
+                                     const std::string &typedefString);
+    void RewriteImplementations();
+    void RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                 ObjCImplementationDecl *IMD,
+                                 ObjCCategoryImplDecl *CID);
+    void RewriteInterfaceDecl(ObjCInterfaceDecl *Dcl);
+    void RewriteImplementationDecl(Decl *Dcl);
+    void RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                               ObjCMethodDecl *MDecl, std::string &ResultStr);
+    void RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                               const FunctionType *&FPRetType);
+    void RewriteByRefString(std::string &ResultStr, const std::string &Name,
+                            ValueDecl *VD, bool def=false);
+    void RewriteCategoryDecl(ObjCCategoryDecl *Dcl);
+    void RewriteProtocolDecl(ObjCProtocolDecl *Dcl);
+    void RewriteForwardProtocolDecl(DeclGroupRef D);
+    void RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG);
+    void RewriteMethodDeclaration(ObjCMethodDecl *Method);
+    void RewriteProperty(ObjCPropertyDecl *prop);
+    void RewriteFunctionDecl(FunctionDecl *FD);
+    void RewriteBlockPointerType(std::string& Str, QualType Type);
+    void RewriteBlockPointerTypeVariable(std::string& Str, ValueDecl *VD);
+    void RewriteBlockLiteralFunctionDecl(FunctionDecl *FD);
+    void RewriteObjCQualifiedInterfaceTypes(Decl *Dcl);
+    void RewriteTypeOfDecl(VarDecl *VD);
+    void RewriteObjCQualifiedInterfaceTypes(Expr *E);
+  
+    // Expression Rewriting.
+    Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
+    Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
+    Stmt *RewritePropertyOrImplicitGetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewritePropertyOrImplicitSetter(PseudoObjectExpr *Pseudo);
+    Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
+    Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
+    Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
+    void RewriteTryReturnStmts(Stmt *S);
+    void RewriteSyncReturnStmts(Stmt *S, std::string buf);
+    Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
+    Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
+    Stmt *RewriteObjCThrowStmt(ObjCAtThrowStmt *S);
+    Stmt *RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                       SourceLocation OrigEnd);
+    Stmt *RewriteBreakStmt(BreakStmt *S);
+    Stmt *RewriteContinueStmt(ContinueStmt *S);
+    void RewriteCastExpr(CStyleCastExpr *CE);
+    
+    // Block rewriting.
+    void RewriteBlocksInFunctionProtoType(QualType funcType, NamedDecl *D);
+    
+    // Block specific rewrite rules.
+    void RewriteBlockPointerDecl(NamedDecl *VD);
+    void RewriteByRefVar(VarDecl *VD);
+    Stmt *RewriteBlockDeclRefExpr(DeclRefExpr *VD);
+    Stmt *RewriteLocalVariableExternalStorage(DeclRefExpr *DRE);
+    void RewriteBlockPointerFunctionArgs(FunctionDecl *FD);
+    
+    void RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                      std::string &Result);
+
+    void Initialize(ASTContext &context) override = 0;
+
+    // Metadata Rewriting.
+    virtual void RewriteMetaDataIntoBuffer(std::string &Result) = 0;
+    virtual void RewriteObjCProtocolListMetaData(const ObjCList<ObjCProtocolDecl> &Prots,
+                                                 StringRef prefix,
+                                                 StringRef ClassName,
+                                                 std::string &Result) = 0;
+    virtual void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                             std::string &Result) = 0;
+    virtual void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     StringRef prefix,
+                                     StringRef ClassName,
+                                     std::string &Result) = 0;
+    virtual void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                          std::string &Result) = 0;
+    
+    // Rewriting ivar access
+    virtual Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) = 0;
+    virtual void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                         std::string &Result) = 0;
+    
+    // Misc. AST transformation routines. Sometimes they end up calling
+    // rewriting routines on the new ASTs.
+    CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD,
+                                           Expr **args, unsigned nargs,
+                                           SourceLocation StartLoc=SourceLocation(),
+                                           SourceLocation EndLoc=SourceLocation());
+    CallExpr *SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                        QualType msgSendType, 
+                                        QualType returnType, 
+                                        SmallVectorImpl<QualType> &ArgTypes,
+                                        SmallVectorImpl<Expr*> &MsgExprs,
+                                        ObjCMethodDecl *Method);
+    Stmt *SynthMessageExpr(ObjCMessageExpr *Exp,
+                           SourceLocation StartLoc=SourceLocation(),
+                           SourceLocation EndLoc=SourceLocation());
+    
+    void SynthCountByEnumWithState(std::string &buf);
+    void SynthMsgSendFunctionDecl();
+    void SynthMsgSendSuperFunctionDecl();
+    void SynthMsgSendStretFunctionDecl();
+    void SynthMsgSendFpretFunctionDecl();
+    void SynthMsgSendSuperStretFunctionDecl();
+    void SynthGetClassFunctionDecl();
+    void SynthGetMetaClassFunctionDecl();
+    void SynthGetSuperClassFunctionDecl();
+    void SynthSelGetUidFunctionDecl();
+    void SynthSuperConstructorFunctionDecl();
+    
+    std::string SynthesizeByrefCopyDestroyHelper(VarDecl *VD, int flag);
+    std::string SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                      StringRef funcName, std::string Tag);
+    std::string SynthesizeBlockImpl(BlockExpr *CE, 
+                                    std::string Tag, std::string Desc);
+    std::string SynthesizeBlockDescriptor(std::string DescTag, 
+                                          std::string ImplTag,
+                                          int i, StringRef funcName,
+                                          unsigned hasCopy);
+    Stmt *SynthesizeBlockCall(CallExpr *Exp, const Expr* BlockExp);
+    void SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                 StringRef FunName);
+    FunctionDecl *SynthBlockInitFunctionDecl(StringRef name);
+    Stmt *SynthBlockInitExpr(BlockExpr *Exp,
+            const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs);
+
+    // Misc. helper routines.
+    QualType getProtocolType();
+    void WarnAboutReturnGotoStmts(Stmt *S);
+    void HasReturnStmts(Stmt *S, bool &hasReturns);
+    void CheckFunctionPointerDecl(QualType dType, NamedDecl *ND);
+    void InsertBlockLiteralsWithinFunction(FunctionDecl *FD);
+    void InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD);
+
+    bool IsDeclStmtInForeachHeader(DeclStmt *DS);
+    void CollectBlockDeclRefInfo(BlockExpr *Exp);
+    void GetBlockDeclRefExprs(Stmt *S);
+    void GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts);
+
+    // We avoid calling Type::isBlockPointerType(), since it operates on the
+    // canonical type. We only care if the top-level type is a closure pointer.
+    bool isTopLevelBlockPointerType(QualType T) {
+      return isa<BlockPointerType>(T);
+    }
+
+    /// convertBlockPointerToFunctionPointer - Converts a block-pointer type
+    /// to a function pointer type and upon success, returns true; false
+    /// otherwise.
+    bool convertBlockPointerToFunctionPointer(QualType &T) {
+      if (isTopLevelBlockPointerType(T)) {
+        const BlockPointerType *BPT = T->getAs<BlockPointerType>();
+        T = Context->getPointerType(BPT->getPointeeType());
+        return true;
+      }
+      return false;
+    }
+    
+    bool needToScanForQualifiers(QualType T);
+    QualType getSuperStructType();
+    QualType getConstantStringStructType();
+    QualType convertFunctionTypeOfBlocks(const FunctionType *FT);
+    bool BufferContainsPPDirectives(const char *startBuf, const char *endBuf);
+    
+    void convertToUnqualifiedObjCType(QualType &T) {
+      if (T->isObjCQualifiedIdType())
+        T = Context->getObjCIdType();
+      else if (T->isObjCQualifiedClassType())
+        T = Context->getObjCClassType();
+      else if (T->isObjCObjectPointerType() &&
+               T->getPointeeType()->isObjCQualifiedInterfaceType()) {
+        if (const ObjCObjectPointerType * OBJPT =
+              T->getAsObjCInterfacePointerType()) {
+          const ObjCInterfaceType *IFaceT = OBJPT->getInterfaceType();
+          T = QualType(IFaceT, 0);
+          T = Context->getPointerType(T);
+        }
+     }
+    }
+    
+    // FIXME: This predicate seems like it would be useful to add to ASTContext.
+    bool isObjCType(QualType T) {
+      if (!LangOpts.ObjC1 && !LangOpts.ObjC2)
+        return false;
+
+      QualType OCT = Context->getCanonicalType(T).getUnqualifiedType();
+
+      if (OCT == Context->getCanonicalType(Context->getObjCIdType()) ||
+          OCT == Context->getCanonicalType(Context->getObjCClassType()))
+        return true;
+
+      if (const PointerType *PT = OCT->getAs<PointerType>()) {
+        if (isa<ObjCInterfaceType>(PT->getPointeeType()) ||
+            PT->getPointeeType()->isObjCQualifiedIdType())
+          return true;
+      }
+      return false;
+    }
+    bool PointerTypeTakesAnyBlockArguments(QualType QT);
+    bool PointerTypeTakesAnyObjCQualifiedType(QualType QT);
+    void GetExtentOfArgList(const char *Name, const char *&LParen,
+                            const char *&RParen);
+    
+    void QuoteDoublequotes(std::string &From, std::string &To) {
+      for (unsigned i = 0; i < From.length(); i++) {
+        if (From[i] == '"')
+          To += "\\\"";
+        else
+          To += From[i];
+      }
+    }
+
+    QualType getSimpleFunctionType(QualType result,
+                                   ArrayRef<QualType> args,
+                                   bool variadic = false) {
+      if (result == Context->getObjCInstanceType())
+        result =  Context->getObjCIdType();
+      FunctionProtoType::ExtProtoInfo fpi;
+      fpi.Variadic = variadic;
+      return Context->getFunctionType(result, args, fpi);
+    }
+
+    // Helper function: create a CStyleCastExpr with trivial type source info.
+    CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty,
+                                             CastKind Kind, Expr *E) {
+      TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation());
+      return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, nullptr,
+                                    TInfo, SourceLocation(), SourceLocation());
+    }
+
+    StringLiteral *getStringLiteral(StringRef Str) {
+      QualType StrType = Context->getConstantArrayType(
+          Context->CharTy, llvm::APInt(32, Str.size() + 1), ArrayType::Normal,
+          0);
+      return StringLiteral::Create(*Context, Str, StringLiteral::Ascii,
+                                   /*Pascal=*/false, StrType, SourceLocation());
+    }
+  };
+  
+  class RewriteObjCFragileABI : public RewriteObjC {
+  public:
+    
+    RewriteObjCFragileABI(std::string inFile, raw_ostream *OS,
+                DiagnosticsEngine &D, const LangOptions &LOpts,
+                bool silenceMacroWarn) : RewriteObjC(inFile, OS,
+                                                     D, LOpts,
+                                                     silenceMacroWarn) {}
+    
+    ~RewriteObjCFragileABI() {}
+    void Initialize(ASTContext &context) override;
+
+    // Rewriting metadata
+    template<typename MethodIterator>
+    void RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                    MethodIterator MethodEnd,
+                                    bool IsInstanceMethod,
+                                    StringRef prefix,
+                                    StringRef ClassName,
+                                    std::string &Result);
+    void RewriteObjCProtocolMetaData(ObjCProtocolDecl *Protocol,
+                                     StringRef prefix, StringRef ClassName,
+                                     std::string &Result) override;
+    void RewriteObjCProtocolListMetaData(
+          const ObjCList<ObjCProtocolDecl> &Prots,
+          StringRef prefix, StringRef ClassName, std::string &Result) override;
+    void RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                  std::string &Result) override;
+    void RewriteMetaDataIntoBuffer(std::string &Result) override;
+    void RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *CDecl,
+                                     std::string &Result) override;
+
+    // Rewriting ivar
+    void RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                      std::string &Result) override;
+    Stmt *RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) override;
+  };
+}
+
+void RewriteObjC::RewriteBlocksInFunctionProtoType(QualType funcType,
+                                                   NamedDecl *D) {
+  if (const FunctionProtoType *fproto
+      = dyn_cast<FunctionProtoType>(funcType.IgnoreParens())) {
+    for (const auto &I : fproto->param_types())
+      if (isTopLevelBlockPointerType(I)) {
+        // All the args are checked/rewritten. Don't call twice!
+        RewriteBlockPointerDecl(D);
+        break;
+      }
+  }
+}
+
+void RewriteObjC::CheckFunctionPointerDecl(QualType funcType, NamedDecl *ND) {
+  const PointerType *PT = funcType->getAs<PointerType>();
+  if (PT && PointerTypeTakesAnyBlockArguments(funcType))
+    RewriteBlocksInFunctionProtoType(PT->getPointeeType(), ND);
+}
+
+static bool IsHeaderFile(const std::string &Filename) {
+  std::string::size_type DotPos = Filename.rfind('.');
+
+  if (DotPos == std::string::npos) {
+    // no file extension
+    return false;
+  }
+
+  std::string Ext = std::string(Filename.begin()+DotPos+1, Filename.end());
+  // C header: .h
+  // C++ header: .hh or .H;
+  return Ext == "h" || Ext == "hh" || Ext == "H";
+}
+
+RewriteObjC::RewriteObjC(std::string inFile, raw_ostream* OS,
+                         DiagnosticsEngine &D, const LangOptions &LOpts,
+                         bool silenceMacroWarn)
+      : Diags(D), LangOpts(LOpts), InFileName(inFile), OutFile(OS),
+        SilenceRewriteMacroWarning(silenceMacroWarn) {
+  IsHeader = IsHeaderFile(inFile);
+  RewriteFailedDiag = Diags.getCustomDiagID(DiagnosticsEngine::Warning,
+               "rewriting sub-expression within a macro (may not be correct)");
+  TryFinallyContainsReturnDiag = Diags.getCustomDiagID(
+               DiagnosticsEngine::Warning,
+               "rewriter doesn't support user-specified control flow semantics "
+               "for @try/@finally (code may not execute properly)");
+}
+
+std::unique_ptr<ASTConsumer>
+clang::CreateObjCRewriter(const std::string &InFile, raw_ostream *OS,
+                          DiagnosticsEngine &Diags, const LangOptions &LOpts,
+                          bool SilenceRewriteMacroWarning) {
+  return llvm::make_unique<RewriteObjCFragileABI>(InFile, OS, Diags, LOpts,
+                                                  SilenceRewriteMacroWarning);
+}
+
+void RewriteObjC::InitializeCommon(ASTContext &context) {
+  Context = &context;
+  SM = &Context->getSourceManager();
+  TUDecl = Context->getTranslationUnitDecl();
+  MsgSendFunctionDecl = nullptr;
+  MsgSendSuperFunctionDecl = nullptr;
+  MsgSendStretFunctionDecl = nullptr;
+  MsgSendSuperStretFunctionDecl = nullptr;
+  MsgSendFpretFunctionDecl = nullptr;
+  GetClassFunctionDecl = nullptr;
+  GetMetaClassFunctionDecl = nullptr;
+  GetSuperClassFunctionDecl = nullptr;
+  SelGetUidFunctionDecl = nullptr;
+  CFStringFunctionDecl = nullptr;
+  ConstantStringClassReference = nullptr;
+  NSStringRecord = nullptr;
+  CurMethodDef = nullptr;
+  CurFunctionDef = nullptr;
+  CurFunctionDeclToDeclareForBlock = nullptr;
+  GlobalVarDecl = nullptr;
+  SuperStructDecl = nullptr;
+  ProtocolTypeDecl = nullptr;
+  ConstantStringDecl = nullptr;
+  BcLabelCount = 0;
+  SuperConstructorFunctionDecl = nullptr;
+  NumObjCStringLiterals = 0;
+  PropParentMap = nullptr;
+  CurrentBody = nullptr;
+  DisableReplaceStmt = false;
+  objc_impl_method = false;
+
+  // Get the ID and start/end of the main file.
+  MainFileID = SM->getMainFileID();
+  const llvm::MemoryBuffer *MainBuf = SM->getBuffer(MainFileID);
+  MainFileStart = MainBuf->getBufferStart();
+  MainFileEnd = MainBuf->getBufferEnd();
+
+  Rewrite.setSourceMgr(Context->getSourceManager(), Context->getLangOpts());
+}
+
+//===----------------------------------------------------------------------===//
+// Top Level Driver Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  // Two cases: either the decl could be in the main file, or it could be in a
+  // #included file.  If the former, rewrite it now.  If the later, check to see
+  // if we rewrote the #include/#import.
+  SourceLocation Loc = D->getLocation();
+  Loc = SM->getExpansionLoc(Loc);
+
+  // If this is for a builtin, ignore it.
+  if (Loc.isInvalid()) return;
+
+  // Look for built-in declarations that we need to refer during the rewrite.
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    RewriteFunctionDecl(FD);
+  } else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (FVD->getName() == "_NSConstantStringClassReference") {
+      ConstantStringClassReference = FVD;
+      return;
+    }
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    if (ID->isThisDeclarationADefinition())
+      RewriteInterfaceDecl(ID);
+  } else if (ObjCCategoryDecl *CD = dyn_cast<ObjCCategoryDecl>(D)) {
+    RewriteCategoryDecl(CD);
+  } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+    if (PD->isThisDeclarationADefinition())
+      RewriteProtocolDecl(PD);
+  } else if (LinkageSpecDecl *LSD = dyn_cast<LinkageSpecDecl>(D)) {
+    // Recurse into linkage specifications
+    for (DeclContext::decl_iterator DI = LSD->decls_begin(),
+                                 DIEnd = LSD->decls_end();
+         DI != DIEnd; ) {
+      if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>((*DI))) {
+        if (!IFace->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = IFace->getLocStart();
+          do {
+            if (isa<ObjCInterfaceDecl>(*DI) &&
+                !cast<ObjCInterfaceDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardClassDecl(DG);
+          continue;
+        }
+      }
+
+      if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>((*DI))) {
+        if (!Proto->isThisDeclarationADefinition()) {
+          SmallVector<Decl *, 8> DG;
+          SourceLocation StartLoc = Proto->getLocStart();
+          do {
+            if (isa<ObjCProtocolDecl>(*DI) &&
+                !cast<ObjCProtocolDecl>(*DI)->isThisDeclarationADefinition() &&
+                StartLoc == (*DI)->getLocStart())
+              DG.push_back(*DI);
+            else
+              break;
+            
+            ++DI;
+          } while (DI != DIEnd);
+          RewriteForwardProtocolDecl(DG);
+          continue;
+        }
+      }
+      
+      HandleTopLevelSingleDecl(*DI);
+      ++DI;
+    }
+  }
+  // If we have a decl in the main file, see if we should rewrite it.
+  if (SM->isWrittenInMainFile(Loc))
+    return HandleDeclInMainFile(D);
+}
+
+//===----------------------------------------------------------------------===//
+// Syntactic (non-AST) Rewriting Code
+//===----------------------------------------------------------------------===//
+
+void RewriteObjC::RewriteInclude() {
+  SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
+  StringRef MainBuf = SM->getBufferData(MainFileID);
+  const char *MainBufStart = MainBuf.begin();
+  const char *MainBufEnd = MainBuf.end();
+  size_t ImportLen = strlen("import");
+
+  // Loop over the whole file, looking for includes.
+  for (const char *BufPtr = MainBufStart; BufPtr < MainBufEnd; ++BufPtr) {
+    if (*BufPtr == '#') {
+      if (++BufPtr == MainBufEnd)
+        return;
+      while (*BufPtr == ' ' || *BufPtr == '\t')
+        if (++BufPtr == MainBufEnd)
+          return;
+      if (!strncmp(BufPtr, "import", ImportLen)) {
+        // replace import with include
+        SourceLocation ImportLoc =
+          LocStart.getLocWithOffset(BufPtr-MainBufStart);
+        ReplaceText(ImportLoc, ImportLen, "include");
+        BufPtr += ImportLen;
+      }
+    }
+  }
+}
+
+static std::string getIvarAccessString(ObjCIvarDecl *OID) {
+  const ObjCInterfaceDecl *ClassDecl = OID->getContainingInterface();
+  std::string S;
+  S = "((struct ";
+  S += ClassDecl->getIdentifier()->getName();
+  S += "_IMPL *)self)->";
+  S += OID->getName();
+  return S;
+}
+
+void RewriteObjC::RewritePropertyImplDecl(ObjCPropertyImplDecl *PID,
+                                          ObjCImplementationDecl *IMD,
+                                          ObjCCategoryImplDecl *CID) {
+  static bool objcGetPropertyDefined = false;
+  static bool objcSetPropertyDefined = false;
+  SourceLocation startLoc = PID->getLocStart();
+  InsertText(startLoc, "// ");
+  const char *startBuf = SM->getCharacterData(startLoc);
+  assert((*startBuf == '@') && "bogus @synthesize location");
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@synthesize: can't find ';'");
+  SourceLocation onePastSemiLoc =
+    startLoc.getLocWithOffset(semiBuf-startBuf+1);
+
+  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+    return; // FIXME: is this correct?
+
+  // Generate the 'getter' function.
+  ObjCPropertyDecl *PD = PID->getPropertyDecl();
+  ObjCIvarDecl *OID = PID->getPropertyIvarDecl();
+
+  if (!OID)
+    return;
+  unsigned Attributes = PD->getPropertyAttributes();
+  if (!PD->getGetterMethodDecl()->isDefined()) {
+    bool GenGetProperty = !(Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic) &&
+                          (Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                         ObjCPropertyDecl::OBJC_PR_copy));
+    std::string Getr;
+    if (GenGetProperty && !objcGetPropertyDefined) {
+      objcGetPropertyDefined = true;
+      // FIXME. Is this attribute correct in all cases?
+      Getr = "\nextern \"C\" __declspec(dllimport) "
+            "id objc_getProperty(id, SEL, long, bool);\n";
+    }
+    RewriteObjCMethodDecl(OID->getContainingInterface(),  
+                          PD->getGetterMethodDecl(), Getr);
+    Getr += "{ ";
+    // Synthesize an explicit cast to gain access to the ivar.
+    // See objc-act.c:objc_synthesize_new_getter() for details.
+    if (GenGetProperty) {
+      // return objc_getProperty(self, _cmd, offsetof(ClassDecl, OID), 1)
+      Getr += "typedef ";
+      const FunctionType *FPRetType = nullptr;
+      RewriteTypeIntoString(PD->getGetterMethodDecl()->getReturnType(), Getr,
+                            FPRetType);
+      Getr += " _TYPE";
+      if (FPRetType) {
+        Getr += ")"; // close the precedence "scope" for "*".
+      
+        // Now, emit the argument types (if any).
+        if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)){
+          Getr += "(";
+          for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+            if (i) Getr += ", ";
+            std::string ParamStr =
+                FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+            Getr += ParamStr;
+          }
+          if (FT->isVariadic()) {
+            if (FT->getNumParams())
+              Getr += ", ";
+            Getr += "...";
+          }
+          Getr += ")";
+        } else
+          Getr += "()";
+      }
+      Getr += ";\n";
+      Getr += "return (_TYPE)";
+      Getr += "objc_getProperty(self, _cmd, ";
+      RewriteIvarOffsetComputation(OID, Getr);
+      Getr += ", 1)";
+    }
+    else
+      Getr += "return " + getIvarAccessString(OID);
+    Getr += "; }";
+    InsertText(onePastSemiLoc, Getr);
+  }
+  
+  if (PD->isReadOnly() || PD->getSetterMethodDecl()->isDefined())
+    return;
+
+  // Generate the 'setter' function.
+  std::string Setr;
+  bool GenSetProperty = Attributes & (ObjCPropertyDecl::OBJC_PR_retain | 
+                                      ObjCPropertyDecl::OBJC_PR_copy);
+  if (GenSetProperty && !objcSetPropertyDefined) {
+    objcSetPropertyDefined = true;
+    // FIXME. Is this attribute correct in all cases?
+    Setr = "\nextern \"C\" __declspec(dllimport) "
+    "void objc_setProperty (id, SEL, long, id, bool, bool);\n";
+  }
+  
+  RewriteObjCMethodDecl(OID->getContainingInterface(), 
+                        PD->getSetterMethodDecl(), Setr);
+  Setr += "{ ";
+  // Synthesize an explicit cast to initialize the ivar.
+  // See objc-act.c:objc_synthesize_new_setter() for details.
+  if (GenSetProperty) {
+    Setr += "objc_setProperty (self, _cmd, ";
+    RewriteIvarOffsetComputation(OID, Setr);
+    Setr += ", (id)";
+    Setr += PD->getName();
+    Setr += ", ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_nonatomic)
+      Setr += "0, ";
+    else
+      Setr += "1, ";
+    if (Attributes & ObjCPropertyDecl::OBJC_PR_copy)
+      Setr += "1)";
+    else
+      Setr += "0)";
+  }
+  else {
+    Setr += getIvarAccessString(OID) + " = ";
+    Setr += PD->getName();
+  }
+  Setr += "; }";
+  InsertText(onePastSemiLoc, Setr);
+}
+
+static void RewriteOneForwardClassDecl(ObjCInterfaceDecl *ForwardDecl,
+                                       std::string &typedefString) {
+  typedefString += "#ifndef _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "#define _REWRITER_typedef_";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += "\n";
+  typedefString += "typedef struct objc_object ";
+  typedefString += ForwardDecl->getNameAsString();
+  typedefString += ";\n#endif\n";
+}
+
+void RewriteObjC::RewriteForwardClassEpilogue(ObjCInterfaceDecl *ClassDecl,
+                                              const std::string &typedefString) {
+    SourceLocation startLoc = ClassDecl->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *semiPtr = strchr(startBuf, ';'); 
+    // Replace the @class with typedefs corresponding to the classes.
+    ReplaceText(startLoc, semiPtr-startBuf+1, typedefString);  
+}
+
+void RewriteObjC::RewriteForwardClassDecl(DeclGroupRef D) {
+  std::string typedefString;
+  for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) {
+    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(*I);
+    if (I == D.begin()) {
+      // Translate to typedef's that forward reference structs with the same name
+      // as the class. As a convenience, we include the original declaration
+      // as a comment.
+      typedefString += "// @class ";
+      typedefString += ForwardDecl->getNameAsString();
+      typedefString += ";\n";
+    }
+    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+  }
+  DeclGroupRef::iterator I = D.begin();
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(*I), typedefString);
+}
+
+void RewriteObjC::RewriteForwardClassDecl(const SmallVectorImpl<Decl *> &D) {
+  std::string typedefString;
+  for (unsigned i = 0; i < D.size(); i++) {
+    ObjCInterfaceDecl *ForwardDecl = cast<ObjCInterfaceDecl>(D[i]);
+    if (i == 0) {
+      typedefString += "// @class ";
+      typedefString += ForwardDecl->getNameAsString();
+      typedefString += ";\n";
+    }
+    RewriteOneForwardClassDecl(ForwardDecl, typedefString);
+  }
+  RewriteForwardClassEpilogue(cast<ObjCInterfaceDecl>(D[0]), typedefString);
+}
+
+void RewriteObjC::RewriteMethodDeclaration(ObjCMethodDecl *Method) {
+  // When method is a synthesized one, such as a getter/setter there is
+  // nothing to rewrite.
+  if (Method->isImplicit())
+    return;
+  SourceLocation LocStart = Method->getLocStart();
+  SourceLocation LocEnd = Method->getLocEnd();
+
+  if (SM->getExpansionLineNumber(LocEnd) >
+      SM->getExpansionLineNumber(LocStart)) {
+    InsertText(LocStart, "#if 0\n");
+    ReplaceText(LocEnd, 1, ";\n#endif\n");
+  } else {
+    InsertText(LocStart, "// ");
+  }
+}
+
+void RewriteObjC::RewriteProperty(ObjCPropertyDecl *prop) {
+  SourceLocation Loc = prop->getAtLoc();
+
+  ReplaceText(Loc, 0, "// ");
+  // FIXME: handle properties that are declared across multiple lines.
+}
+
+void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
+  SourceLocation LocStart = CatDecl->getLocStart();
+
+  // FIXME: handle category headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (auto *I : CatDecl->properties())
+    RewriteProperty(I);  
+  for (auto *I : CatDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : CatDecl->class_methods())
+    RewriteMethodDeclaration(I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(CatDecl->getAtEndRange().getBegin(), 
+              strlen("@end"), "/* @end */");
+}
+
+void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
+  SourceLocation LocStart = PDecl->getLocStart();
+  assert(PDecl->isThisDeclarationADefinition());
+  
+  // FIXME: handle protocol headers that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+
+  for (auto *I : PDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->class_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : PDecl->properties())
+    RewriteProperty(I);
+  
+  // Lastly, comment out the @end.
+  SourceLocation LocEnd = PDecl->getAtEndRange().getBegin();
+  ReplaceText(LocEnd, strlen("@end"), "/* @end */");
+
+  // Must comment out @optional/@required
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  for (const char *p = startBuf; p < endBuf; p++) {
+    if (*p == '@' && !strncmp(p+1, "optional", strlen("optional"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@optional"), "/* @optional */");
+
+    }
+    else if (*p == '@' && !strncmp(p+1, "required", strlen("required"))) {
+      SourceLocation OptionalLoc = LocStart.getLocWithOffset(p-startBuf);
+      ReplaceText(OptionalLoc, strlen("@required"), "/* @required */");
+
+    }
+  }
+}
+
+void RewriteObjC::RewriteForwardProtocolDecl(DeclGroupRef D) {
+  SourceLocation LocStart = (*D.begin())->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void 
+RewriteObjC::RewriteForwardProtocolDecl(const SmallVectorImpl<Decl *> &DG) {
+  SourceLocation LocStart = DG[0]->getLocStart();
+  if (LocStart.isInvalid())
+    llvm_unreachable("Invalid SourceLocation");
+  // FIXME: handle forward protocol that are declared across multiple lines.
+  ReplaceText(LocStart, 0, "// ");
+}
+
+void RewriteObjC::RewriteTypeIntoString(QualType T, std::string &ResultStr,
+                                        const FunctionType *&FPRetType) {
+  if (T->isObjCQualifiedIdType())
+    ResultStr += "id";
+  else if (T->isFunctionPointerType() ||
+           T->isBlockPointerType()) {
+    // needs special handling, since pointer-to-functions have special
+    // syntax (where a decaration models use).
+    QualType retType = T;
+    QualType PointeeTy;
+    if (const PointerType* PT = retType->getAs<PointerType>())
+      PointeeTy = PT->getPointeeType();
+    else if (const BlockPointerType *BPT = retType->getAs<BlockPointerType>())
+      PointeeTy = BPT->getPointeeType();
+    if ((FPRetType = PointeeTy->getAs<FunctionType>())) {
+      ResultStr +=
+          FPRetType->getReturnType().getAsString(Context->getPrintingPolicy());
+      ResultStr += "(*";
+    }
+  } else
+    ResultStr += T.getAsString(Context->getPrintingPolicy());
+}
+
+void RewriteObjC::RewriteObjCMethodDecl(const ObjCInterfaceDecl *IDecl,
+                                        ObjCMethodDecl *OMD,
+                                        std::string &ResultStr) {
+  //fprintf(stderr,"In RewriteObjCMethodDecl\n");
+  const FunctionType *FPRetType = nullptr;
+  ResultStr += "\nstatic ";
+  RewriteTypeIntoString(OMD->getReturnType(), ResultStr, FPRetType);
+  ResultStr += " ";
+
+  // Unique method name
+  std::string NameStr;
+
+  if (OMD->isInstanceMethod())
+    NameStr += "_I_";
+  else
+    NameStr += "_C_";
+
+  NameStr += IDecl->getNameAsString();
+  NameStr += "_";
+
+  if (ObjCCategoryImplDecl *CID =
+      dyn_cast<ObjCCategoryImplDecl>(OMD->getDeclContext())) {
+    NameStr += CID->getNameAsString();
+    NameStr += "_";
+  }
+  // Append selector names, replacing ':' with '_'
+  {
+    std::string selString = OMD->getSelector().getAsString();
+    int len = selString.size();
+    for (int i = 0; i < len; i++)
+      if (selString[i] == ':')
+        selString[i] = '_';
+    NameStr += selString;
+  }
+  // Remember this name for metadata emission
+  MethodInternalNames[OMD] = NameStr;
+  ResultStr += NameStr;
+
+  // Rewrite arguments
+  ResultStr += "(";
+
+  // invisible arguments
+  if (OMD->isInstanceMethod()) {
+    QualType selfTy = Context->getObjCInterfaceType(IDecl);
+    selfTy = Context->getPointerType(selfTy);
+    if (!LangOpts.MicrosoftExt) {
+      if (ObjCSynthesizedStructs.count(const_cast<ObjCInterfaceDecl*>(IDecl)))
+        ResultStr += "struct ";
+    }
+    // When rewriting for Microsoft, explicitly omit the structure name.
+    ResultStr += IDecl->getNameAsString();
+    ResultStr += " *";
+  }
+  else
+    ResultStr += Context->getObjCClassType().getAsString(
+      Context->getPrintingPolicy());
+
+  ResultStr += " self, ";
+  ResultStr += Context->getObjCSelType().getAsString(Context->getPrintingPolicy());
+  ResultStr += " _cmd";
+
+  // Method arguments.
+  for (const auto *PDecl : OMD->params()) {
+    ResultStr += ", ";
+    if (PDecl->getType()->isObjCQualifiedIdType()) {
+      ResultStr += "id ";
+      ResultStr += PDecl->getNameAsString();
+    } else {
+      std::string Name = PDecl->getNameAsString();
+      QualType QT = PDecl->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      ResultStr += Name;
+    }
+  }
+  if (OMD->isVariadic())
+    ResultStr += ", ...";
+  ResultStr += ") ";
+
+  if (FPRetType) {
+    ResultStr += ")"; // close the precedence "scope" for "*".
+
+    // Now, emit the argument types (if any).
+    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(FPRetType)) {
+      ResultStr += "(";
+      for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) {
+        if (i) ResultStr += ", ";
+        std::string ParamStr =
+            FT->getParamType(i).getAsString(Context->getPrintingPolicy());
+        ResultStr += ParamStr;
+      }
+      if (FT->isVariadic()) {
+        if (FT->getNumParams())
+          ResultStr += ", ";
+        ResultStr += "...";
+      }
+      ResultStr += ")";
+    } else {
+      ResultStr += "()";
+    }
+  }
+}
+void RewriteObjC::RewriteImplementationDecl(Decl *OID) {
+  ObjCImplementationDecl *IMD = dyn_cast<ObjCImplementationDecl>(OID);
+  ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(OID);
+
+  InsertText(IMD ? IMD->getLocStart() : CID->getLocStart(), "// ");
+
+  for (auto *OMD : IMD ? IMD->instance_methods() : CID->instance_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+
+  for (auto *OMD : IMD ? IMD->class_methods() : CID->class_methods()) {
+    std::string ResultStr;
+    RewriteObjCMethodDecl(OMD->getClassInterface(), OMD, ResultStr);
+    SourceLocation LocStart = OMD->getLocStart();
+    SourceLocation LocEnd = OMD->getCompoundBody()->getLocStart();
+
+    const char *startBuf = SM->getCharacterData(LocStart);
+    const char *endBuf = SM->getCharacterData(LocEnd);
+    ReplaceText(LocStart, endBuf-startBuf, ResultStr);
+  }
+  for (auto *I : IMD ? IMD->property_impls() : CID->property_impls())
+    RewritePropertyImplDecl(I, IMD, CID);
+
+  InsertText(IMD ? IMD->getLocEnd() : CID->getLocEnd(), "// ");
+}
+
+void RewriteObjC::RewriteInterfaceDecl(ObjCInterfaceDecl *ClassDecl) {
+  std::string ResultStr;
+  if (!ObjCForwardDecls.count(ClassDecl->getCanonicalDecl())) {
+    // we haven't seen a forward decl - generate a typedef.
+    ResultStr = "#ifndef _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "#define _REWRITER_typedef_";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += "\n";
+    ResultStr += "typedef struct objc_object ";
+    ResultStr += ClassDecl->getNameAsString();
+    ResultStr += ";\n#endif\n";
+    // Mark this typedef as having been generated.
+    ObjCForwardDecls.insert(ClassDecl->getCanonicalDecl());
+  }
+  RewriteObjCInternalStruct(ClassDecl, ResultStr);
+
+  for (auto *I : ClassDecl->properties())
+    RewriteProperty(I);
+  for (auto *I : ClassDecl->instance_methods())
+    RewriteMethodDeclaration(I);
+  for (auto *I : ClassDecl->class_methods())
+    RewriteMethodDeclaration(I);
+
+  // Lastly, comment out the @end.
+  ReplaceText(ClassDecl->getAtEndRange().getBegin(), strlen("@end"), 
+              "/* @end */");
+}
+
+Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getSemanticExpr(
+                            PseudoOp->getNumSemanticExprs() - 1));
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base, *RHS;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    Base = nullptr;
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+
+    // Rebuild the RHS.
+    RHS = cast<BinaryOperator>(PseudoOp->getSyntacticForm())->getRHS();
+    RHS = cast<OpaqueValueExpr>(RHS)->getSourceExpr();
+    RHS = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(RHS));
+  }
+
+  // TODO: avoid this copy.
+  SmallVector<SourceLocation, 1> SelLocs;
+  OldMsg->getSelectorLocs(SelLocs);
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     RHS,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(PseudoObjectExpr *PseudoOp) {
+  SourceRange OldRange = PseudoOp->getSourceRange();
+
+  // We just magically know some things about the structure of this
+  // expression.
+  ObjCMessageExpr *OldMsg =
+    cast<ObjCMessageExpr>(PseudoOp->getResultExpr()->IgnoreImplicit());
+
+  // Because the rewriter doesn't allow us to rewrite rewritten code,
+  // we need to suppress rewriting the sub-statements.
+  Expr *Base = nullptr;
+  {
+    DisableReplaceStmtScope S(*this);
+
+    // Rebuild the base expression if we have one.
+    if (OldMsg->getReceiverKind() == ObjCMessageExpr::Instance) {
+      Base = OldMsg->getInstanceReceiver();
+      Base = cast<OpaqueValueExpr>(Base)->getSourceExpr();
+      Base = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(Base));
+    }
+  }
+
+  // Intentionally empty.
+  SmallVector<SourceLocation, 1> SelLocs;
+  SmallVector<Expr*, 1> Args;
+
+  ObjCMessageExpr *NewMsg = nullptr;
+  switch (OldMsg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getClassReceiverTypeInfo(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::Instance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     Base,
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    NewMsg = ObjCMessageExpr::Create(*Context, OldMsg->getType(),
+                                     OldMsg->getValueKind(),
+                                     OldMsg->getLeftLoc(),
+                                     OldMsg->getSuperLoc(),
+                 OldMsg->getReceiverKind() == ObjCMessageExpr::SuperInstance,
+                                     OldMsg->getSuperType(),
+                                     OldMsg->getSelector(),
+                                     SelLocs,
+                                     OldMsg->getMethodDecl(),
+                                     Args,
+                                     OldMsg->getRightLoc(),
+                                     OldMsg->isImplicit());
+    break;
+  }
+
+  Stmt *Replacement = SynthMessageExpr(NewMsg);
+  ReplaceStmtWithRange(PseudoOp, Replacement, OldRange);
+  return Replacement;
+}
+
+/// SynthCountByEnumWithState - To print:
+/// ((unsigned int (*)
+///  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+///  (void *)objc_msgSend)((id)l_collection,
+///                        sel_registerName(
+///                          "countByEnumeratingWithState:objects:count:"),
+///                        &enumState,
+///                        (id *)__rw_items, (unsigned int)16)
+///
+void RewriteObjC::SynthCountByEnumWithState(std::string &buf) {
+  buf += "((unsigned int (*) (id, SEL, struct __objcFastEnumerationState *, "
+  "id *, unsigned int))(void *)objc_msgSend)";
+  buf += "\n\t\t";
+  buf += "((id)l_collection,\n\t\t";
+  buf += "sel_registerName(\"countByEnumeratingWithState:objects:count:\"),";
+  buf += "\n\t\t";
+  buf += "&enumState, "
+         "(id *)__rw_items, (unsigned int)16)";
+}
+
+/// RewriteBreakStmt - Rewrite for a break-stmt inside an ObjC2's foreach
+/// statement to exit to its outer synthesized loop.
+///
+Stmt *RewriteObjC::RewriteBreakStmt(BreakStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace break with goto __break_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("break"), buf);
+
+  return nullptr;
+}
+
+/// RewriteContinueStmt - Rewrite for a continue-stmt inside an ObjC2's foreach
+/// statement to continue with its inner synthesized loop.
+///
+Stmt *RewriteObjC::RewriteContinueStmt(ContinueStmt *S) {
+  if (Stmts.empty() || !isa<ObjCForCollectionStmt>(Stmts.back()))
+    return S;
+  // replace continue with goto __continue_label
+  std::string buf;
+
+  SourceLocation startLoc = S->getLocStart();
+  buf = "goto __continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  ReplaceText(startLoc, strlen("continue"), buf);
+
+  return nullptr;
+}
+
+/// RewriteObjCForCollectionStmt - Rewriter for ObjC2's foreach statement.
+///  It rewrites:
+/// for ( type elem in collection) { stmts; }
+
+/// Into:
+/// {
+///   type elem;
+///   struct __objcFastEnumerationState enumState = { 0 };
+///   id __rw_items[16];
+///   id l_collection = (id)collection;
+///   unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+///                                       objects:__rw_items count:16];
+/// if (limit) {
+///   unsigned long startMutations = *enumState.mutationsPtr;
+///   do {
+///        unsigned long counter = 0;
+///        do {
+///             if (startMutations != *enumState.mutationsPtr)
+///               objc_enumerationMutation(l_collection);
+///             elem = (type)enumState.itemsPtr[counter++];
+///             stmts;
+///             __continue_label: ;
+///        } while (counter < limit);
+///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
+///                                  objects:__rw_items count:16]);
+///   elem = nil;
+///   __break_label: ;
+///  }
+///  else
+///       elem = nil;
+///  }
+///
+Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
+                                                SourceLocation OrigEnd) {
+  assert(!Stmts.empty() && "ObjCForCollectionStmt - Statement stack empty");
+  assert(isa<ObjCForCollectionStmt>(Stmts.back()) &&
+         "ObjCForCollectionStmt Statement stack mismatch");
+  assert(!ObjCBcLabelNo.empty() &&
+         "ObjCForCollectionStmt - Label No stack empty");
+
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+  StringRef elementName;
+  std::string elementTypeAsString;
+  std::string buf;
+  buf = "\n{\n\t";
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S->getElement())) {
+    // type elem;
+    NamedDecl* D = cast<NamedDecl>(DS->getSingleDecl());
+    QualType ElementType = cast<ValueDecl>(D)->getType();
+    if (ElementType->isObjCQualifiedIdType() ||
+        ElementType->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = ElementType.getAsString(Context->getPrintingPolicy());
+    buf += elementTypeAsString;
+    buf += " ";
+    elementName = D->getName();
+    buf += elementName;
+    buf += ";\n\t";
+  }
+  else {
+    DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
+    elementName = DR->getDecl()->getName();
+    ValueDecl *VD = cast<ValueDecl>(DR->getDecl());
+    if (VD->getType()->isObjCQualifiedIdType() ||
+        VD->getType()->isObjCQualifiedInterfaceType())
+      // Simply use 'id' for all qualified types.
+      elementTypeAsString = "id";
+    else
+      elementTypeAsString = VD->getType().getAsString(Context->getPrintingPolicy());
+  }
+
+  // struct __objcFastEnumerationState enumState = { 0 };
+  buf += "struct __objcFastEnumerationState enumState = { 0 };\n\t";
+  // id __rw_items[16];
+  buf += "id __rw_items[16];\n\t";
+  // id l_collection = (id)
+  buf += "id l_collection = (id)";
+  // Find start location of 'collection' the hard way!
+  const char *startCollectionBuf = startBuf;
+  startCollectionBuf += 3;  // skip 'for'
+  startCollectionBuf = strchr(startCollectionBuf, '(');
+  startCollectionBuf++; // skip '('
+  // find 'in' and skip it.
+  while (*startCollectionBuf != ' ' ||
+         *(startCollectionBuf+1) != 'i' || *(startCollectionBuf+2) != 'n' ||
+         (*(startCollectionBuf+3) != ' ' &&
+          *(startCollectionBuf+3) != '[' && *(startCollectionBuf+3) != '('))
+    startCollectionBuf++;
+  startCollectionBuf += 3;
+
+  // Replace: "for (type element in" with string constructed thus far.
+  ReplaceText(startLoc, startCollectionBuf - startBuf, buf);
+  // Replace ')' in for '(' type elem in collection ')' with ';'
+  SourceLocation rightParenLoc = S->getRParenLoc();
+  const char *rparenBuf = SM->getCharacterData(rightParenLoc);
+  SourceLocation lparenLoc = startLoc.getLocWithOffset(rparenBuf-startBuf);
+  buf = ";\n\t";
+
+  // unsigned long limit = [l_collection countByEnumeratingWithState:&enumState
+  //                                   objects:__rw_items count:16];
+  // which is synthesized into:
+  // unsigned int limit =
+  // ((unsigned int (*)
+  //  (id, SEL, struct __objcFastEnumerationState *, id *, unsigned int))
+  //  (void *)objc_msgSend)((id)l_collection,
+  //                        sel_registerName(
+  //                          "countByEnumeratingWithState:objects:count:"),
+  //                        (struct __objcFastEnumerationState *)&state,
+  //                        (id *)__rw_items, (unsigned int)16);
+  buf += "unsigned long limit =\n\t\t";
+  SynthCountByEnumWithState(buf);
+  buf += ";\n\t";
+  /// if (limit) {
+  ///   unsigned long startMutations = *enumState.mutationsPtr;
+  ///   do {
+  ///        unsigned long counter = 0;
+  ///        do {
+  ///             if (startMutations != *enumState.mutationsPtr)
+  ///               objc_enumerationMutation(l_collection);
+  ///             elem = (type)enumState.itemsPtr[counter++];
+  buf += "if (limit) {\n\t";
+  buf += "unsigned long startMutations = *enumState.mutationsPtr;\n\t";
+  buf += "do {\n\t\t";
+  buf += "unsigned long counter = 0;\n\t\t";
+  buf += "do {\n\t\t\t";
+  buf += "if (startMutations != *enumState.mutationsPtr)\n\t\t\t\t";
+  buf += "objc_enumerationMutation(l_collection);\n\t\t\t";
+  buf += elementName;
+  buf += " = (";
+  buf += elementTypeAsString;
+  buf += ")enumState.itemsPtr[counter++];";
+  // Replace ')' in for '(' type elem in collection ')' with all of these.
+  ReplaceText(lparenLoc, 1, buf);
+
+  ///            __continue_label: ;
+  ///        } while (counter < limit);
+  ///   } while (limit = [l_collection countByEnumeratingWithState:&enumState
+  ///                                  objects:__rw_items count:16]);
+  ///   elem = nil;
+  ///   __break_label: ;
+  ///  }
+  ///  else
+  ///       elem = nil;
+  ///  }
+  ///
+  buf = ";\n\t";
+  buf += "__continue_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;";
+  buf += "\n\t\t";
+  buf += "} while (counter < limit);\n\t";
+  buf += "} while (limit = ";
+  SynthCountByEnumWithState(buf);
+  buf += ");\n\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "__break_label_";
+  buf += utostr(ObjCBcLabelNo.back());
+  buf += ": ;\n\t";
+  buf += "}\n\t";
+  buf += "else\n\t\t";
+  buf += elementName;
+  buf += " = ((";
+  buf += elementTypeAsString;
+  buf += ")0);\n\t";
+  buf += "}\n";
+
+  // Insert all these *after* the statement body.
+  // FIXME: If this should support Obj-C++, support CXXTryStmt
+  if (isa<CompoundStmt>(S->getBody())) {
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(1);
+    InsertText(endBodyLoc, buf);
+  } else {
+    /* Need to treat single statements specially. For example:
+     *
+     *     for (A *a in b) if (stuff()) break;
+     *     for (A *a in b) xxxyy;
+     *
+     * The following code simply scans ahead to the semi to find the actual end.
+     */
+    const char *stmtBuf = SM->getCharacterData(OrigEnd);
+    const char *semiBuf = strchr(stmtBuf, ';');
+    assert(semiBuf && "Can't find ';'");
+    SourceLocation endBodyLoc = OrigEnd.getLocWithOffset(semiBuf-stmtBuf+1);
+    InsertText(endBodyLoc, buf);
+  }
+  Stmts.pop_back();
+  ObjCBcLabelNo.pop_back();
+  return nullptr;
+}
+
+/// RewriteObjCSynchronizedStmt -
+/// This routine rewrites @synchronized(expr) stmt;
+/// into:
+/// objc_sync_enter(expr);
+/// @try stmt @finally { objc_sync_exit(expr); }
+///
+Stmt *RewriteObjC::RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @synchronized location");
+
+  std::string buf;
+  buf = "objc_sync_enter((id)";
+  const char *lparenBuf = startBuf;
+  while (*lparenBuf != '(') lparenBuf++;
+  ReplaceText(startLoc, lparenBuf-startBuf+1, buf);
+  // We can't use S->getSynchExpr()->getLocEnd() to find the end location, since
+  // the sync expression is typically a message expression that's already
+  // been rewritten! (which implies the SourceLocation's are invalid).
+  SourceLocation endLoc = S->getSynchBody()->getLocStart();
+  const char *endBuf = SM->getCharacterData(endLoc);
+  while (*endBuf != ')') endBuf--;
+  SourceLocation rparenLoc = startLoc.getLocWithOffset(endBuf-startBuf);
+  buf = ");\n";
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf += "/* @try scope begin */ \n{ struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+  ReplaceText(rparenLoc, 1, buf);
+  startLoc = S->getSynchBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @synchronized block");
+  SourceLocation lastCurlyLoc = startLoc;
+  buf = "}\nelse {\n";
+  buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+  buf += "}\n";
+  buf += "{ /* implicit finally clause */\n";
+  buf += "  if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+  
+  std::string syncBuf;
+  syncBuf += " objc_sync_exit(";
+
+  Expr *syncExpr = S->getSynchExpr();
+  CastKind CK = syncExpr->getType()->isObjCObjectPointerType()
+                  ? CK_BitCast :
+                syncExpr->getType()->isBlockPointerType()
+                  ? CK_BlockPointerToObjCPointerCast
+                  : CK_CPointerToObjCPointerCast;
+  syncExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                      CK, syncExpr);
+  std::string syncExprBufS;
+  llvm::raw_string_ostream syncExprBuf(syncExprBufS);
+  assert(syncExpr != nullptr && "Expected non-null Expr");
+  syncExpr->printPretty(syncExprBuf, nullptr, PrintingPolicy(LangOpts));
+  syncBuf += syncExprBuf.str();
+  syncBuf += ");";
+  
+  buf += syncBuf;
+  buf += "\n  if (_rethrow) objc_exception_throw(_rethrow);\n";
+  buf += "}\n";
+  buf += "}";
+
+  ReplaceText(lastCurlyLoc, 1, buf);
+
+  bool hasReturns = false;
+  HasReturnStmts(S->getSynchBody(), hasReturns);
+  if (hasReturns)
+    RewriteSyncReturnStmts(S->getSynchBody(), syncBuf);
+
+  return nullptr;
+}
+
+void RewriteObjC::WarnAboutReturnGotoStmts(Stmt *S)
+{
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI)
+      WarnAboutReturnGotoStmts(*CI);
+
+  if (isa<ReturnStmt>(S) || isa<GotoStmt>(S)) {
+    Diags.Report(Context->getFullLoc(S->getLocStart()),
+                 TryFinallyContainsReturnDiag);
+  }
+  return;
+}
+
+void RewriteObjC::HasReturnStmts(Stmt *S, bool &hasReturns) 
+{  
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+   if (*CI)
+     HasReturnStmts(*CI, hasReturns);
+
+ if (isa<ReturnStmt>(S))
+   hasReturns = true;
+ return;
+}
+
+void RewriteObjC::RewriteTryReturnStmts(Stmt *S) {
+ // Perform a bottom up traversal of all children.
+ for (Stmt::child_range CI = S->children(); CI; ++CI)
+   if (*CI) {
+     RewriteTryReturnStmts(*CI);
+   }
+ if (isa<ReturnStmt>(S)) {
+   SourceLocation startLoc = S->getLocStart();
+   const char *startBuf = SM->getCharacterData(startLoc);
+
+   const char *semiBuf = strchr(startBuf, ';');
+   assert((*semiBuf == ';') && "RewriteTryReturnStmts: can't find ';'");
+   SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
+
+   std::string buf;
+   buf = "{ objc_exception_try_exit(&_stack); return";
+   
+   ReplaceText(startLoc, 6, buf);
+   InsertText(onePastSemiLoc, "}");
+ }
+ return;
+}
+
+void RewriteObjC::RewriteSyncReturnStmts(Stmt *S, std::string syncExitBuf) {
+  // Perform a bottom up traversal of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      RewriteSyncReturnStmts(*CI, syncExitBuf);
+    }
+  if (isa<ReturnStmt>(S)) {
+    SourceLocation startLoc = S->getLocStart();
+    const char *startBuf = SM->getCharacterData(startLoc);
+
+    const char *semiBuf = strchr(startBuf, ';');
+    assert((*semiBuf == ';') && "RewriteSyncReturnStmts: can't find ';'");
+    SourceLocation onePastSemiLoc = startLoc.getLocWithOffset(semiBuf-startBuf+1);
+
+    std::string buf;
+    buf = "{ objc_exception_try_exit(&_stack);";
+    buf += syncExitBuf;
+    buf += " return";
+    
+    ReplaceText(startLoc, 6, buf);
+    InsertText(onePastSemiLoc, "}");
+  }
+  return;
+}
+
+Stmt *RewriteObjC::RewriteObjCTryStmt(ObjCAtTryStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @try location");
+
+  std::string buf;
+  // declare a new scope with two variables, _stack and _rethrow.
+  buf = "/* @try scope begin */ { struct _objc_exception_data {\n";
+  buf += "int buf[18/*32-bit i386*/];\n";
+  buf += "char *pointers[4];} _stack;\n";
+  buf += "id volatile _rethrow = 0;\n";
+  buf += "objc_exception_try_enter(&_stack);\n";
+  buf += "if (!_setjmp(_stack.buf)) /* @try block continue */\n";
+
+  ReplaceText(startLoc, 4, buf);
+
+  startLoc = S->getTryBody()->getLocEnd();
+  startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '}') && "bogus @try block");
+
+  SourceLocation lastCurlyLoc = startLoc;
+  if (S->getNumCatchStmts()) {
+    startLoc = startLoc.getLocWithOffset(1);
+    buf = " /* @catch begin */ else {\n";
+    buf += " id _caught = objc_exception_extract(&_stack);\n";
+    buf += " objc_exception_try_enter (&_stack);\n";
+    buf += " if (_setjmp(_stack.buf))\n";
+    buf += "   _rethrow = objc_exception_extract(&_stack);\n";
+    buf += " else { /* @catch continue */";
+
+    InsertText(startLoc, buf);
+  } else { /* no catch list */
+    buf = "}\nelse {\n";
+    buf += "  _rethrow = objc_exception_extract(&_stack);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf);
+  }
+  Stmt *lastCatchBody = nullptr;
+  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
+    ObjCAtCatchStmt *Catch = S->getCatchStmt(I);
+    VarDecl *catchDecl = Catch->getCatchParamDecl();
+
+    if (I == 0)
+      buf = "if ("; // we are generating code for the first catch clause
+    else
+      buf = "else if (";
+    startLoc = Catch->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+
+    assert((*startBuf == '@') && "bogus @catch location");
+
+    const char *lParenLoc = strchr(startBuf, '(');
+
+    if (Catch->hasEllipsis()) {
+      // Now rewrite the body...
+      lastCatchBody = Catch->getCatchBody();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      assert(*SM->getCharacterData(Catch->getRParenLoc()) == ')' &&
+             "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+
+      buf += "1) { id _tmp = _caught;";
+      Rewrite.ReplaceText(startLoc, bodyBuf-startBuf+1, buf);
+    } else if (catchDecl) {
+      QualType t = catchDecl->getType();
+      if (t == Context->getObjCIdType()) {
+        buf += "1) { ";
+        ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+      } else if (const ObjCObjectPointerType *Ptr =
+                   t->getAs<ObjCObjectPointerType>()) {
+        // Should be a pointer to a class.
+        ObjCInterfaceDecl *IDecl = Ptr->getObjectType()->getInterface();
+        if (IDecl) {
+          buf += "objc_exception_match((struct objc_class *)objc_getClass(\"";
+          buf += IDecl->getNameAsString();
+          buf += "\"), (struct objc_object *)_caught)) { ";
+          ReplaceText(startLoc, lParenLoc-startBuf+1, buf);
+        }
+      }
+      // Now rewrite the body...
+      lastCatchBody = Catch->getCatchBody();
+      SourceLocation rParenLoc = Catch->getRParenLoc();
+      SourceLocation bodyLoc = lastCatchBody->getLocStart();
+      const char *bodyBuf = SM->getCharacterData(bodyLoc);
+      const char *rParenBuf = SM->getCharacterData(rParenLoc);
+      assert((*rParenBuf == ')') && "bogus @catch paren location");
+      assert((*bodyBuf == '{') && "bogus @catch body location");
+
+      // Here we replace ") {" with "= _caught;" (which initializes and
+      // declares the @catch parameter).
+      ReplaceText(rParenLoc, bodyBuf-rParenBuf+1, " = _caught;");
+    } else {
+      llvm_unreachable("@catch rewrite bug");
+    }
+  }
+  // Complete the catch list...
+  if (lastCatchBody) {
+    SourceLocation bodyLoc = lastCatchBody->getLocEnd();
+    assert(*SM->getCharacterData(bodyLoc) == '}' &&
+           "bogus @catch body location");
+
+    // Insert the last (implicit) else clause *before* the right curly brace.
+    bodyLoc = bodyLoc.getLocWithOffset(-1);
+    buf = "} /* last catch end */\n";
+    buf += "else {\n";
+    buf += " _rethrow = _caught;\n";
+    buf += " objc_exception_try_exit(&_stack);\n";
+    buf += "} } /* @catch end */\n";
+    if (!S->getFinallyStmt())
+      buf += "}\n";
+    InsertText(bodyLoc, buf);
+
+    // Set lastCurlyLoc
+    lastCurlyLoc = lastCatchBody->getLocEnd();
+  }
+  if (ObjCAtFinallyStmt *finalStmt = S->getFinallyStmt()) {
+    startLoc = finalStmt->getLocStart();
+    startBuf = SM->getCharacterData(startLoc);
+    assert((*startBuf == '@') && "bogus @finally start");
+
+    ReplaceText(startLoc, 8, "/* @finally */");
+
+    Stmt *body = finalStmt->getFinallyBody();
+    SourceLocation startLoc = body->getLocStart();
+    SourceLocation endLoc = body->getLocEnd();
+    assert(*SM->getCharacterData(startLoc) == '{' &&
+           "bogus @finally body location");
+    assert(*SM->getCharacterData(endLoc) == '}' &&
+           "bogus @finally body location");
+
+    startLoc = startLoc.getLocWithOffset(1);
+    InsertText(startLoc, " if (!_rethrow) objc_exception_try_exit(&_stack);\n");
+    endLoc = endLoc.getLocWithOffset(-1);
+    InsertText(endLoc, " if (_rethrow) objc_exception_throw(_rethrow);\n");
+
+    // Set lastCurlyLoc
+    lastCurlyLoc = body->getLocEnd();
+
+    // Now check for any return/continue/go statements within the @try.
+    WarnAboutReturnGotoStmts(S->getTryBody());
+  } else { /* no finally clause - make sure we synthesize an implicit one */
+    buf = "{ /* implicit finally clause */\n";
+    buf += " if (!_rethrow) objc_exception_try_exit(&_stack);\n";
+    buf += " if (_rethrow) objc_exception_throw(_rethrow);\n";
+    buf += "}";
+    ReplaceText(lastCurlyLoc, 1, buf);
+    
+    // Now check for any return/continue/go statements within the @try.
+    // The implicit finally clause won't called if the @try contains any
+    // jump statements.
+    bool hasReturns = false;
+    HasReturnStmts(S->getTryBody(), hasReturns);
+    if (hasReturns)
+      RewriteTryReturnStmts(S->getTryBody());
+  }
+  // Now emit the final closing curly brace...
+  lastCurlyLoc = lastCurlyLoc.getLocWithOffset(1);
+  InsertText(lastCurlyLoc, " } /* @try scope end */\n");
+  return nullptr;
+}
+
+// This can't be done with ReplaceStmt(S, ThrowExpr), since
+// the throw expression is typically a message expression that's already
+// been rewritten! (which implies the SourceLocation's are invalid).
+Stmt *RewriteObjC::RewriteObjCThrowStmt(ObjCAtThrowStmt *S) {
+  // Get the start location and compute the semi location.
+  SourceLocation startLoc = S->getLocStart();
+  const char *startBuf = SM->getCharacterData(startLoc);
+
+  assert((*startBuf == '@') && "bogus @throw location");
+
+  std::string buf;
+  /* void objc_exception_throw(id) __attribute__((noreturn)); */
+  if (S->getThrowExpr())
+    buf = "objc_exception_throw(";
+  else // add an implicit argument
+    buf = "objc_exception_throw(_caught";
+
+  // handle "@  throw" correctly.
+  const char *wBuf = strchr(startBuf, 'w');
+  assert((*wBuf == 'w') && "@throw: can't find 'w'");
+  ReplaceText(startLoc, wBuf-startBuf+1, buf);
+
+  const char *semiBuf = strchr(startBuf, ';');
+  assert((*semiBuf == ';') && "@throw: can't find ';'");
+  SourceLocation semiLoc = startLoc.getLocWithOffset(semiBuf-startBuf);
+  ReplaceText(semiLoc, 1, ");");
+  return nullptr;
+}
+
+Stmt *RewriteObjC::RewriteAtEncode(ObjCEncodeExpr *Exp) {
+  // Create a new string expression.
+  std::string StrEncoding;
+  Context->getObjCEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = getStringLiteral(StrEncoding);
+  ReplaceStmt(Exp, Replacement);
+
+  // Replace this subexpr in the parent.
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return Replacement;
+}
+
+Stmt *RewriteObjC::RewriteAtSelector(ObjCSelectorExpr *Exp) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
+  // Create a call to sel_registerName("selName").
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size());
+  ReplaceStmt(Exp, SelExp);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return SelExp;
+}
+
+CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl(
+  FunctionDecl *FD, Expr **args, unsigned nargs, SourceLocation StartLoc,
+                                                    SourceLocation EndLoc) {
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = FD->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+
+  // Now, we cast the reference to a pointer to the objc_msgSend type.
+  QualType pToFunc = Context->getPointerType(msgSendType);
+  ImplicitCastExpr *ICE =
+    ImplicitCastExpr::Create(*Context, pToFunc, CK_FunctionToPointerDecay,
+                             DRE, nullptr, VK_RValue);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+
+  CallExpr *Exp =  
+    new (Context) CallExpr(*Context, ICE, llvm::makeArrayRef(args, nargs),
+                           FT->getCallResultType(*Context),
+                           VK_RValue, EndLoc);
+  return Exp;
+}
+
+static bool scanForProtocolRefs(const char *startBuf, const char *endBuf,
+                                const char *&startRef, const char *&endRef) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '<')
+      startRef = startBuf; // mark the start.
+    if (*startBuf == '>') {
+      if (startRef && *startRef == '<') {
+        endRef = startBuf; // mark the end.
+        return true;
+      }
+      return false;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+static void scanToNextArgument(const char *&argRef) {
+  int angle = 0;
+  while (*argRef != ')' && (*argRef != ',' || angle > 0)) {
+    if (*argRef == '<')
+      angle++;
+    else if (*argRef == '>')
+      angle--;
+    argRef++;
+  }
+  assert(angle == 0 && "scanToNextArgument - bad protocol type syntax");
+}
+
+bool RewriteObjC::needToScanForQualifiers(QualType T) {
+  if (T->isObjCQualifiedIdType())
+    return true;
+  if (const PointerType *PT = T->getAs<PointerType>()) {
+    if (PT->getPointeeType()->isObjCQualifiedIdType())
+      return true;
+  }
+  if (T->isObjCObjectPointerType()) {
+    T = T->getPointeeType();
+    return T->isObjCQualifiedInterfaceType();
+  }
+  if (T->isArrayType()) {
+    QualType ElemTy = Context->getBaseElementType(T);
+    return needToScanForQualifiers(ElemTy);
+  }
+  return false;
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Expr *E) {
+  QualType Type = E->getType();
+  if (needToScanForQualifiers(Type)) {
+    SourceLocation Loc, EndLoc;
+
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E)) {
+      Loc = ECE->getLParenLoc();
+      EndLoc = ECE->getRParenLoc();
+    } else {
+      Loc = E->getLocStart();
+      EndLoc = E->getLocEnd();
+    }
+    // This will defend against trying to rewrite synthesized expressions.
+    if (Loc.isInvalid() || EndLoc.isInvalid())
+      return;
+
+    const char *startBuf = SM->getCharacterData(Loc);
+    const char *endBuf = SM->getCharacterData(EndLoc);
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-startBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-startBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+}
+
+void RewriteObjC::RewriteObjCQualifiedInterfaceTypes(Decl *Dcl) {
+  SourceLocation Loc;
+  QualType Type;
+  const FunctionProtoType *proto = nullptr;
+  if (VarDecl *VD = dyn_cast<VarDecl>(Dcl)) {
+    Loc = VD->getLocation();
+    Type = VD->getType();
+  }
+  else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    // Check for ObjC 'id' and class types that have been adorned with protocol
+    // information (id<p>, C<p>*). The protocol references need to be rewritten!
+    const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+    assert(funcType && "missing function type");
+    proto = dyn_cast<FunctionProtoType>(funcType);
+    if (!proto)
+      return;
+    Type = proto->getReturnType();
+  }
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(Dcl)) {
+    Loc = FD->getLocation();
+    Type = FD->getType();
+  }
+  else
+    return;
+
+  if (needToScanForQualifiers(Type)) {
+    // Since types are unique, we need to scan the buffer.
+
+    const char *endBuf = SM->getCharacterData(Loc);
+    const char *startBuf = endBuf;
+    while (*startBuf != ';' && *startBuf != '<' && startBuf != MainFileStart)
+      startBuf--; // scan backward (from the decl location) for return type.
+    const char *startRef = nullptr, *endRef = nullptr;
+    if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+      // Get the locations of the startRef, endRef.
+      SourceLocation LessLoc = Loc.getLocWithOffset(startRef-endBuf);
+      SourceLocation GreaterLoc = Loc.getLocWithOffset(endRef-endBuf+1);
+      // Comment out the protocol references.
+      InsertText(LessLoc, "/*");
+      InsertText(GreaterLoc, "*/");
+    }
+  }
+  if (!proto)
+      return; // most likely, was a variable
+  // Now check arguments.
+  const char *startBuf = SM->getCharacterData(Loc);
+  const char *startFuncBuf = startBuf;
+  for (unsigned i = 0; i < proto->getNumParams(); i++) {
+    if (needToScanForQualifiers(proto->getParamType(i))) {
+      // Since types are unique, we need to scan the buffer.
+
+      const char *endBuf = startBuf;
+      // scan forward (from the decl location) for argument types.
+      scanToNextArgument(endBuf);
+      const char *startRef = nullptr, *endRef = nullptr;
+      if (scanForProtocolRefs(startBuf, endBuf, startRef, endRef)) {
+        // Get the locations of the startRef, endRef.
+        SourceLocation LessLoc =
+          Loc.getLocWithOffset(startRef-startFuncBuf);
+        SourceLocation GreaterLoc =
+          Loc.getLocWithOffset(endRef-startFuncBuf+1);
+        // Comment out the protocol references.
+        InsertText(LessLoc, "/*");
+        InsertText(GreaterLoc, "*/");
+      }
+      startBuf = ++endBuf;
+    }
+    else {
+      // If the function name is derived from a macro expansion, then the
+      // argument buffer will not follow the name. Need to speak with Chris.
+      while (*startBuf && *startBuf != ')' && *startBuf != ',')
+        startBuf++; // scan forward (from the decl location) for argument types.
+      startBuf++;
+    }
+  }
+}
+
+void RewriteObjC::RewriteTypeOfDecl(VarDecl *ND) {
+  QualType QT = ND->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (!isa<TypeOfExprType>(TypePtr))
+    return;
+  while (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    TypePtr = QT->getAs<Type>();
+  }
+  // FIXME. This will not work for multiple declarators; as in:
+  // __typeof__(a) b,c,d;
+  std::string TypeAsString(QT.getAsString(Context->getPrintingPolicy()));
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  if (ND->getInit()) {
+    std::string Name(ND->getNameAsString());
+    TypeAsString += " " + Name + " = ";
+    Expr *E = ND->getInit();
+    SourceLocation startLoc;
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    const char *endBuf = SM->getCharacterData(startLoc);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+  else {
+    SourceLocation X = ND->getLocEnd();
+    X = SM->getExpansionLoc(X);
+    const char *endBuf = SM->getCharacterData(X);
+    ReplaceText(DeclLoc, endBuf-startBuf-1, TypeAsString);
+  }
+}
+
+// SynthSelGetUidFunctionDecl - SEL sel_registerName(const char *str);
+void RewriteObjC::SynthSelGetUidFunctionDecl() {
+  IdentifierInfo *SelGetUidIdent = &Context->Idents.get("sel_registerName");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getFuncType =
+    getSimpleFunctionType(Context->getObjCSelType(), ArgTys);
+  SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                               SourceLocation(),
+                                               SourceLocation(),
+                                               SelGetUidIdent, getFuncType,
+                                               nullptr, SC_Extern);
+}
+
+void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
+  // declared in <objc/objc.h>
+  if (FD->getIdentifier() &&
+      FD->getName() == "sel_registerName") {
+    SelGetUidFunctionDecl = FD;
+    return;
+  }
+  RewriteObjCQualifiedInterfaceTypes(FD);
+}
+
+void RewriteObjC::RewriteBlockPointerType(std::string& Str, QualType Type) {
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  if (!strchr(argPtr, '^')) {
+    Str += TypeString;
+    return;
+  }
+  while (*argPtr) {
+    Str += (*argPtr == '^' ? '*' : *argPtr);
+    argPtr++;
+  }
+}
+
+// FIXME. Consolidate this routine with RewriteBlockPointerType.
+void RewriteObjC::RewriteBlockPointerTypeVariable(std::string& Str,
+                                                  ValueDecl *VD) {
+  QualType Type = VD->getType();
+  std::string TypeString(Type.getAsString(Context->getPrintingPolicy()));
+  const char *argPtr = TypeString.c_str();
+  int paren = 0;
+  while (*argPtr) {
+    switch (*argPtr) {
+      case '(':
+        Str += *argPtr;
+        paren++;
+        break;
+      case ')':
+        Str += *argPtr;
+        paren--;
+        break;
+      case '^':
+        Str += '*';
+        if (paren == 1)
+          Str += VD->getNameAsString();
+        break;
+      default:
+        Str += *argPtr;
+        break;
+    }
+    argPtr++;
+  }
+}
+
+
+void RewriteObjC::RewriteBlockLiteralFunctionDecl(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  const FunctionType *funcType = FD->getType()->getAs<FunctionType>();
+  const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(funcType);
+  if (!proto)
+    return;
+  QualType Type = proto->getReturnType();
+  std::string FdStr = Type.getAsString(Context->getPrintingPolicy());
+  FdStr += " ";
+  FdStr += FD->getName();
+  FdStr +=  "(";
+  unsigned numArgs = proto->getNumParams();
+  for (unsigned i = 0; i < numArgs; i++) {
+    QualType ArgType = proto->getParamType(i);
+    RewriteBlockPointerType(FdStr, ArgType);
+    if (i+1 < numArgs)
+      FdStr += ", ";
+  }
+  FdStr +=  ");\n";
+  InsertText(FunLocStart, FdStr);
+  CurFunctionDeclToDeclareForBlock = nullptr;
+}
+
+// SynthSuperConstructorFunctionDecl - id objc_super(id obj, id super);
+void RewriteObjC::SynthSuperConstructorFunctionDecl() {
+  if (SuperConstructorFunctionDecl)
+    return;
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("__rw_objc_super");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys);
+  SuperConstructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                     SourceLocation(),
+                                                     SourceLocation(),
+                                                     msgSendIdent, msgSendType,
+                                                     nullptr, SC_Extern);
+}
+
+// SynthMsgSendFunctionDecl - id objc_msgSend(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                             SourceLocation(),
+                                             SourceLocation(),
+                                             msgSendIdent, msgSendType,
+                                             nullptr, SC_Extern);
+}
+
+// SynthMsgSendSuperFunctionDecl - id objc_msgSendSuper(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSendSuper");
+  SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendStretFunctionDecl - id objc_msgSend_stret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_stret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthMsgSendSuperStretFunctionDecl -
+// id objc_msgSendSuper_stret(struct objc_super *, SEL op, ...);
+void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() {
+  IdentifierInfo *msgSendIdent =
+    &Context->Idents.get("objc_msgSendSuper_stret");
+  SmallVector<QualType, 16> ArgTys;
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("objc_super"));
+  QualType argT = Context->getPointerType(Context->getTagDeclType(RD));
+  assert(!argT.isNull() && "Can't build 'struct objc_super *' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->getObjCIdType(),
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                       SourceLocation(),
+                                                       SourceLocation(),
+                                                       msgSendIdent,
+                                                       msgSendType, nullptr,
+                                                       SC_Extern);
+}
+
+// SynthMsgSendFpretFunctionDecl - double objc_msgSend_fpret(id self, SEL op, ...);
+void RewriteObjC::SynthMsgSendFpretFunctionDecl() {
+  IdentifierInfo *msgSendIdent = &Context->Idents.get("objc_msgSend_fpret");
+  SmallVector<QualType, 16> ArgTys;
+  QualType argT = Context->getObjCIdType();
+  assert(!argT.isNull() && "Can't find 'id' type");
+  ArgTys.push_back(argT);
+  argT = Context->getObjCSelType();
+  assert(!argT.isNull() && "Can't find 'SEL' type");
+  ArgTys.push_back(argT);
+  QualType msgSendType = getSimpleFunctionType(Context->DoubleTy,
+                                               ArgTys, /*isVariadic=*/true);
+  MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  msgSendIdent, msgSendType,
+                                                  nullptr, SC_Extern);
+}
+
+// SynthGetClassFunctionDecl - id objc_getClass(const char *name);
+void RewriteObjC::SynthGetClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
+                                                ArgTys);
+  GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                              SourceLocation(),
+                                              SourceLocation(),
+                                              getClassIdent, getClassType,
+                                              nullptr, SC_Extern);
+}
+
+// SynthGetSuperClassFunctionDecl - Class class_getSuperclass(Class cls);
+void RewriteObjC::SynthGetSuperClassFunctionDecl() {
+  IdentifierInfo *getSuperClassIdent = 
+    &Context->Idents.get("class_getSuperclass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getObjCClassType());
+  QualType getClassType = getSimpleFunctionType(Context->getObjCClassType(),
+                                                ArgTys);
+  GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                   SourceLocation(),
+                                                   SourceLocation(),
+                                                   getSuperClassIdent,
+                                                   getClassType, nullptr,
+                                                   SC_Extern);
+}
+
+// SynthGetMetaClassFunctionDecl - id objc_getMetaClass(const char *name);
+void RewriteObjC::SynthGetMetaClassFunctionDecl() {
+  IdentifierInfo *getClassIdent = &Context->Idents.get("objc_getMetaClass");
+  SmallVector<QualType, 16> ArgTys;
+  ArgTys.push_back(Context->getPointerType(Context->CharTy.withConst()));
+  QualType getClassType = getSimpleFunctionType(Context->getObjCIdType(),
+                                                ArgTys);
+  GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl,
+                                                  SourceLocation(),
+                                                  SourceLocation(),
+                                                  getClassIdent, getClassType,
+                                                  nullptr, SC_Extern);
+}
+
+Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  assert(Exp != nullptr && "Expected non-null ObjCStringLiteral");
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+
+  std::string tmpName = InFileName;
+  unsigned i;
+  for (i=0; i < tmpName.length(); i++) {
+    char c = tmpName.at(i);
+    // replace any non-alphanumeric characters with '_'.
+    if (!isAlphanumeric(c))
+      tmpName[i] = '_';
+  }
+  S += tmpName;
+  S += "_";
+  S += utostr(NumObjCStringLiterals++);
+
+  Preamble += "static __NSConstantStringImpl " + S;
+  Preamble += " __attribute__ ((section (\"__DATA, __cfstring\"))) = {__CFConstantStringClassReference,";
+  Preamble += "0x000007c8,"; // utf8_str
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::string prettyBufS;
+  llvm::raw_string_ostream prettyBuf(prettyBufS);
+  Exp->getString()->printPretty(prettyBuf, nullptr, PrintingPolicy(LangOpts));
+  Preamble += prettyBuf.str();
+  Preamble += ",";
+  Preamble += utostr(Exp->getString()->getByteLength()) + "};\n";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                   SourceLocation(), &Context->Idents.get(S),
+                                   strType, nullptr, SC_Static);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, false, strType, VK_LValue,
+                                               SourceLocation());
+  Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                                 Context->getPointerType(DRE->getType()),
+                                           VK_RValue, OK_Ordinary,
+                                           SourceLocation());
+  // cast to NSConstantString *
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(),
+                                            CK_CPointerToObjCPointerCast, Unop);
+  ReplaceStmt(Exp, cast);
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return cast;
+}
+
+// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
+QualType RewriteObjC::getSuperStructType() {
+  if (!SuperStructDecl) {
+    SuperStructDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                         SourceLocation(), SourceLocation(),
+                                         &Context->Idents.get("objc_super"));
+    QualType FieldTypes[2];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // struct objc_class *super;
+    FieldTypes[1] = Context->getObjCClassType();
+
+    // Create fields
+    for (unsigned i = 0; i < 2; ++i) {
+      SuperStructDecl->addDecl(FieldDecl::Create(*Context, SuperStructDecl,
+                                                 SourceLocation(),
+                                                 SourceLocation(), nullptr,
+                                                 FieldTypes[i], nullptr,
+                                                 /*BitWidth=*/nullptr,
+                                                 /*Mutable=*/false,
+                                                 ICIS_NoInit));
+    }
+
+    SuperStructDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(SuperStructDecl);
+}
+
+QualType RewriteObjC::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                            SourceLocation(), SourceLocation(),
+                         &Context->Idents.get("__NSConstantStringImpl"));
+    QualType FieldTypes[4];
+
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();
+    // int flags;
+    FieldTypes[1] = Context->IntTy;
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);
+    // long length;
+    FieldTypes[3] = Context->LongTy;
+
+    // Create fields
+    for (unsigned i = 0; i < 4; ++i) {
+      ConstantStringDecl->addDecl(FieldDecl::Create(*Context,
+                                                    ConstantStringDecl,
+                                                    SourceLocation(),
+                                                    SourceLocation(), nullptr,
+                                                    FieldTypes[i], nullptr,
+                                                    /*BitWidth=*/nullptr,
+                                                    /*Mutable=*/true,
+                                                    ICIS_NoInit));
+    }
+
+    ConstantStringDecl->completeDefinition();
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
+CallExpr *RewriteObjC::SynthMsgSendStretCallExpr(FunctionDecl *MsgSendStretFlavor,
+                                                QualType msgSendType, 
+                                                QualType returnType, 
+                                                SmallVectorImpl<QualType> &ArgTypes,
+                                                SmallVectorImpl<Expr*> &MsgExprs,
+                                                ObjCMethodDecl *Method) {
+  // Create a reference to the objc_msgSend_stret() declaration.
+  DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor,
+                                                 false, msgSendType,
+                                                 VK_LValue, SourceLocation());
+  // Need to cast objc_msgSend_stret to "void *" (see above comment).
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, STDRE);
+  // Now do the "normal" pointer to function cast.
+  QualType castType = getSimpleFunctionType(returnType, ArgTypes,
+                                            Method ? Method->isVariadic()
+                                                   : false);
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                            cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *STCE = new (Context) CallExpr(
+      *Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, SourceLocation());
+  return STCE;
+  
+}
+
+
+Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp,
+                                    SourceLocation StartLoc,
+                                    SourceLocation EndLoc) {
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!MsgSendSuperFunctionDecl)
+    SynthMsgSendSuperFunctionDecl();
+  if (!MsgSendStretFunctionDecl)
+    SynthMsgSendStretFunctionDecl();
+  if (!MsgSendSuperStretFunctionDecl)
+    SynthMsgSendSuperStretFunctionDecl();
+  if (!MsgSendFpretFunctionDecl)
+    SynthMsgSendFpretFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  if (!GetSuperClassFunctionDecl)
+    SynthGetSuperClassFunctionDecl();
+  if (!GetMetaClassFunctionDecl)
+    SynthGetMetaClassFunctionDecl();
+
+  // default to objc_msgSend().
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  // May need to use objc_msgSend_stret() as well.
+  FunctionDecl *MsgSendStretFlavor = nullptr;
+  if (ObjCMethodDecl *mDecl = Exp->getMethodDecl()) {
+    QualType resultType = mDecl->getReturnType();
+    if (resultType->isRecordType())
+      MsgSendStretFlavor = MsgSendStretFunctionDecl;
+    else if (resultType->isRealFloatingType())
+      MsgSendFlavor = MsgSendFpretFunctionDecl;
+  }
+
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 8> MsgExprs;
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+    SmallVector<Expr*, 4> InitExprs;
+
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue,
+                                             SourceLocation()))
+                        ); // set the 'receiver'.
+
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                             Context->getObjCClassType(),
+                                             CK_BitCast, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CK_BitCast, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue,
+                                        SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CK_BitCast, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_LValue,
+                                                   ILE, false);
+      // struct objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                                             VK_RValue, OK_Ordinary,
+                                             SourceLocation());
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Class: {
+    SmallVector<Expr*, 8> ClsExprs;
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(getStringLiteral(clsName->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    MsgExprs.push_back(Cls);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                             false,
+                                             Context->getObjCIdType(),
+                                             VK_RValue, SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    SmallVector<Expr*, 8> ClsExprs;
+    ClsExprs.push_back(getStringLiteral(ClassDecl->getIdentifier()->getName()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCClassType(),
+                                                 CK_BitCast, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CK_BitCast, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.MicrosoftExt) {
+      SynthSuperConstructorFunctionDecl();
+      // Simulate a constructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperConstructorFunctionDecl,
+                                                   false, superType, VK_LValue,
+                                                   SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                        superType, VK_LValue, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               VK_RValue, OK_Ordinary,
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CK_BitCast, SuperRep);
+    } else {
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(), InitExprs,
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, VK_RValue, ILE,
+                                                   false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    CastKind CK = recExpr->getType()->isObjCObjectPointerType()
+                    ? CK_BitCast : recExpr->getType()->isBlockPointerType()
+                                     ? CK_BlockPointerToObjCPointerCast
+                                     : CK_CPointerToObjCPointerCast;
+
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CK, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
+  }
+
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
+  SmallVector<Expr*, 8> SelExprs;
+  SelExprs.push_back(getStringLiteral(Exp->getSelector().getAsString()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                 &SelExprs[0], SelExprs.size(),
+                                                  StartLoc,
+                                                  EndLoc);
+  MsgExprs.push_back(SelExp);
+
+  // Now push any user supplied arguments.
+  for (unsigned i = 0; i < Exp->getNumArgs(); i++) {
+    Expr *userExpr = Exp->getArg(i);
+    // Make all implicit casts explicit...ICE comes in handy:-)
+    if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+      // Reuse the ICE type, it is exactly what the doctor ordered.
+      QualType type = ICE->getType();
+      if (needToScanForQualifiers(type))
+        type = Context->getObjCIdType();
+      // Make sure we convert "type (^)(...)" to "type (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(type);
+      const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+      CastKind CK;
+      if (SubExpr->getType()->isIntegralType(*Context) && 
+          type->isBooleanType()) {
+        CK = CK_IntegralToBoolean;
+      } else if (type->isObjCObjectPointerType()) {
+        if (SubExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (SubExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+      } else {
+        CK = CK_BitCast;
+      }
+
+      userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
+    }
+    // Make id<P...> cast into an 'id' cast.
+    else if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(userExpr)) {
+      if (CE->getType()->isObjCQualifiedIdType()) {
+        while ((CE = dyn_cast<CStyleCastExpr>(userExpr)))
+          userExpr = CE->getSubExpr();
+        CastKind CK;
+        if (userExpr->getType()->isIntegralType(*Context)) {
+          CK = CK_IntegralToPointer;
+        } else if (userExpr->getType()->isBlockPointerType()) {
+          CK = CK_BlockPointerToObjCPointerCast;
+        } else if (userExpr->getType()->isPointerType()) {
+          CK = CK_CPointerToObjCPointerCast;
+        } else {
+          CK = CK_BitCast;
+        }
+        userExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                            CK, userExpr);
+      }
+    }
+    MsgExprs.push_back(userExpr);
+    // We've transferred the ownership to MsgExprs. For now, we *don't* null
+    // out the argument in the original expression (since we aren't deleting
+    // the ObjCMessageExpr). See RewritePropertyOrImplicitSetter() usage for more info.
+    //Exp->setArg(i, 0);
+  }
+  // Generate the funky cast.
+  CastExpr *cast;
+  SmallVector<QualType, 8> ArgTypes;
+  QualType returnType;
+
+  // Push 'id' and 'SEL', the 2 implicit arguments.
+  if (MsgSendFlavor == MsgSendSuperFunctionDecl)
+    ArgTypes.push_back(Context->getPointerType(getSuperStructType()));
+  else
+    ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  if (ObjCMethodDecl *OMD = Exp->getMethodDecl()) {
+    // Push any user argument types.
+    for (const auto *PI : OMD->params()) {
+      QualType t = PI->getType()->isObjCQualifiedIdType()
+                     ? Context->getObjCIdType()
+                     : PI->getType();
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      (void)convertBlockPointerToFunctionPointer(t);
+      ArgTypes.push_back(t);
+    }
+    returnType = Exp->getType();
+    convertToUnqualifiedObjCType(returnType);
+    (void)convertBlockPointerToFunctionPointer(returnType);
+  } else {
+    returnType = Context->getObjCIdType();
+  }
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+
+  // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid).
+  // If we don't do this cast, we get the following bizarre warning/note:
+  // xx.m:13: warning: function called through a non-compatible type
+  // xx.m:13: note: if this code is reached, the program will abort
+  cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, DRE);
+
+  // Now do the "normal" pointer to function cast.
+  // If we don't have a method decl, force a variadic cast.
+  const ObjCMethodDecl *MD = Exp->getMethodDecl();
+  QualType castType =
+    getSimpleFunctionType(returnType, ArgTypes, MD ? MD->isVariadic() : true);
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context)
+      CallExpr(*Context, PE, MsgExprs, FT->getReturnType(), VK_RValue, EndLoc);
+  Stmt *ReplacingStmt = CE;
+  if (MsgSendStretFlavor) {
+    // We have the method which returns a struct/union. Must also generate
+    // call to objc_msgSend_stret and hang both varieties on a conditional
+    // expression which dictate which one to envoke depending on size of
+    // method's return type.
+    
+    CallExpr *STCE = SynthMsgSendStretCallExpr(MsgSendStretFlavor, 
+                                               msgSendType, returnType, 
+                                               ArgTypes, MsgExprs,
+                                               Exp->getMethodDecl());
+
+    // Build sizeof(returnType)
+    UnaryExprOrTypeTraitExpr *sizeofExpr =
+       new (Context) UnaryExprOrTypeTraitExpr(UETT_SizeOf,
+                                 Context->getTrivialTypeSourceInfo(returnType),
+                                 Context->getSizeType(), SourceLocation(),
+                                 SourceLocation());
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    // FIXME: Value of 8 is base on ppc32/x86 ABI for the most common cases.
+    // For X86 it is more complicated and some kind of target specific routine
+    // is needed to decide what to do.
+    unsigned IntSize =
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    IntegerLiteral *limit = IntegerLiteral::Create(*Context,
+                                                   llvm::APInt(IntSize, 8),
+                                                   Context->IntTy,
+                                                   SourceLocation());
+    BinaryOperator *lessThanExpr = 
+      new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
+                                   VK_RValue, OK_Ordinary, SourceLocation(),
+                                   false);
+    // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(lessThanExpr,
+                                        SourceLocation(), CE,
+                                        SourceLocation(), STCE,
+                                        returnType, VK_RValue, OK_Ordinary);
+    ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                            CondExpr);
+  }
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+Stmt *RewriteObjC::RewriteMessageExpr(ObjCMessageExpr *Exp) {
+  Stmt *ReplacingStmt = SynthMessageExpr(Exp, Exp->getLocStart(),
+                                         Exp->getLocEnd());
+
+  // Now do the actual rewrite.
+  ReplaceStmt(Exp, ReplacingStmt);
+
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return ReplacingStmt;
+}
+
+// typedef struct objc_object Protocol;
+QualType RewriteObjC::getProtocolType() {
+  if (!ProtocolTypeDecl) {
+    TypeSourceInfo *TInfo
+      = Context->getTrivialTypeSourceInfo(Context->getObjCIdType());
+    ProtocolTypeDecl = TypedefDecl::Create(*Context, TUDecl,
+                                           SourceLocation(), SourceLocation(),
+                                           &Context->Idents.get("Protocol"),
+                                           TInfo);
+  }
+  return Context->getTypeDeclType(ProtocolTypeDecl);
+}
+
+/// RewriteObjCProtocolExpr - Rewrite a protocol expression into
+/// a synthesized/forward data reference (to the protocol's metadata).
+/// The forward references (and metadata) are generated in
+/// RewriteObjC::HandleTranslationUnit().
+Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
+  std::string Name = "_OBJC_PROTOCOL_" + Exp->getProtocol()->getNameAsString();
+  IdentifierInfo *ID = &Context->Idents.get(Name);
+  VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(),
+                                SourceLocation(), ID, getProtocolType(),
+                                nullptr, SC_Extern);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, false, getProtocolType(),
+                                               VK_LValue, SourceLocation());
+  Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf,
+                             Context->getPointerType(DRE->getType()),
+                             VK_RValue, OK_Ordinary, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(),
+                                                CK_BitCast,
+                                                DerefExpr);
+  ReplaceStmt(Exp, castExpr);
+  ProtocolExprDecls.insert(Exp->getProtocol()->getCanonicalDecl());
+  // delete Exp; leak for now, see RewritePropertyOrImplicitSetter() usage for more info.
+  return castExpr;
+
+}
+
+bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
+                                             const char *endBuf) {
+  while (startBuf < endBuf) {
+    if (*startBuf == '#') {
+      // Skip whitespace.
+      for (++startBuf; startBuf[0] == ' ' || startBuf[0] == '\t'; ++startBuf)
+        ;
+      if (!strncmp(startBuf, "if", strlen("if")) ||
+          !strncmp(startBuf, "ifdef", strlen("ifdef")) ||
+          !strncmp(startBuf, "ifndef", strlen("ifndef")) ||
+          !strncmp(startBuf, "define", strlen("define")) ||
+          !strncmp(startBuf, "undef", strlen("undef")) ||
+          !strncmp(startBuf, "else", strlen("else")) ||
+          !strncmp(startBuf, "elif", strlen("elif")) ||
+          !strncmp(startBuf, "endif", strlen("endif")) ||
+          !strncmp(startBuf, "pragma", strlen("pragma")) ||
+          !strncmp(startBuf, "include", strlen("include")) ||
+          !strncmp(startBuf, "import", strlen("import")) ||
+          !strncmp(startBuf, "include_next", strlen("include_next")))
+        return true;
+    }
+    startBuf++;
+  }
+  return false;
+}
+
+/// RewriteObjCInternalStruct - Rewrite one internal struct corresponding to
+/// an objective-c class with ivars.
+void RewriteObjC::RewriteObjCInternalStruct(ObjCInterfaceDecl *CDecl,
+                                               std::string &Result) {
+  assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
+  assert(CDecl->getName() != "" &&
+         "Name missing in SynthesizeObjCInternalStruct");
+  // Do not synthesize more than once.
+  if (ObjCSynthesizedStructs.count(CDecl))
+    return;
+  ObjCInterfaceDecl *RCDecl = CDecl->getSuperClass();
+  int NumIvars = CDecl->ivar_size();
+  SourceLocation LocStart = CDecl->getLocStart();
+  SourceLocation LocEnd = CDecl->getEndOfDefinitionLoc();
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+
+  // If no ivars and no root or if its root, directly or indirectly,
+  // have no ivars (thus not synthesized) then no need to synthesize this class.
+  if ((!CDecl->isThisDeclarationADefinition() || NumIvars == 0) &&
+      (!RCDecl || !ObjCSynthesizedStructs.count(RCDecl))) {
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+    return;
+  }
+
+  // FIXME: This has potential of causing problem. If
+  // SynthesizeObjCInternalStruct is ever called recursively.
+  Result += "\nstruct ";
+  Result += CDecl->getNameAsString();
+  if (LangOpts.MicrosoftExt)
+    Result += "_IMPL";
+
+  if (NumIvars > 0) {
+    const char *cursor = strchr(startBuf, '{');
+    assert((cursor && endBuf)
+           && "SynthesizeObjCInternalStruct - malformed @interface");
+    // If the buffer contains preprocessor directives, we do more fine-grained
+    // rewrites. This is intended to fix code that looks like (which occurs in
+    // NSURL.h, for example):
+    //
+    // #ifdef XYZ
+    // @interface Foo : NSObject
+    // #else
+    // @interface FooBar : NSObject
+    // #endif
+    // {
+    //    int i;
+    // }
+    // @end
+    //
+    // This clause is segregated to avoid breaking the common case.
+    if (BufferContainsPPDirectives(startBuf, cursor)) {
+      SourceLocation L = RCDecl ? CDecl->getSuperClassLoc() :
+                                  CDecl->getAtStartLoc();
+      const char *endHeader = SM->getCharacterData(L);
+      endHeader += Lexer::MeasureTokenLength(L, *SM, LangOpts);
+
+      if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+        // advance to the end of the referenced protocols.
+        while (endHeader < cursor && *endHeader != '>') endHeader++;
+        endHeader++;
+      }
+      // rewrite the original header
+      ReplaceText(LocStart, endHeader-startBuf, Result);
+    } else {
+      // rewrite the original header *without* disturbing the '{'
+      ReplaceText(LocStart, cursor-startBuf, Result);
+    }
+    if (RCDecl && ObjCSynthesizedStructs.count(RCDecl)) {
+      Result = "\n    struct ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IMPL ";
+      Result += RCDecl->getNameAsString();
+      Result += "_IVARS;\n";
+
+      // insert the super class structure definition.
+      SourceLocation OnePastCurly =
+        LocStart.getLocWithOffset(cursor-startBuf+1);
+      InsertText(OnePastCurly, Result);
+    }
+    cursor++; // past '{'
+
+    // Now comment out any visibility specifiers.
+    while (cursor < endBuf) {
+      if (*cursor == '@') {
+        SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        // Skip whitespace.
+        for (++cursor; cursor[0] == ' ' || cursor[0] == '\t'; ++cursor)
+          /*scan*/;
+
+        // FIXME: presence of @public, etc. inside comment results in
+        // this transformation as well, which is still correct c-code.
+        if (!strncmp(cursor, "public", strlen("public")) ||
+            !strncmp(cursor, "private", strlen("private")) ||
+            !strncmp(cursor, "package", strlen("package")) ||
+            !strncmp(cursor, "protected", strlen("protected")))
+          InsertText(atLoc, "// ");
+      }
+      // FIXME: If there are cases where '<' is used in ivar declaration part
+      // of user code, then scan the ivar list and use needToScanForQualifiers
+      // for type checking.
+      else if (*cursor == '<') {
+        SourceLocation atLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, "/* ");
+        cursor = strchr(cursor, '>');
+        cursor++;
+        atLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        InsertText(atLoc, " */");
+      } else if (*cursor == '^') { // rewrite block specifier.
+        SourceLocation caretLoc = LocStart.getLocWithOffset(cursor-startBuf);
+        ReplaceText(caretLoc, 1, "*");
+      }
+      cursor++;
+    }
+    // Don't forget to add a ';'!!
+    InsertText(LocEnd.getLocWithOffset(1), ";");
+  } else { // we don't have any instance variables - insert super struct.
+    endBuf += Lexer::MeasureTokenLength(LocEnd, *SM, LangOpts);
+    Result += " {\n    struct ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IMPL ";
+    Result += RCDecl->getNameAsString();
+    Result += "_IVARS;\n};\n";
+    ReplaceText(LocStart, endBuf-startBuf, Result);
+  }
+  // Mark this struct as having been generated.
+  if (!ObjCSynthesizedStructs.insert(CDecl).second)
+    llvm_unreachable("struct already synthesize- SynthesizeObjCInternalStruct");
+}
+
+//===----------------------------------------------------------------------===//
+// Meta Data Emission
+//===----------------------------------------------------------------------===//
+
+
+/// RewriteImplementations - This routine rewrites all method implementations
+/// and emits meta-data.
+
+void RewriteObjC::RewriteImplementations() {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+
+  // Rewrite implemented methods
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteImplementationDecl(ClassImplementation[i]);
+
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteImplementationDecl(CategoryImplementation[i]);
+}
+
+void RewriteObjC::RewriteByRefString(std::string &ResultStr, 
+                                     const std::string &Name,
+                                     ValueDecl *VD, bool def) {
+  assert(BlockByRefDeclNo.count(VD) && 
+         "RewriteByRefString: ByRef decl missing");
+  if (def)
+    ResultStr += "struct ";
+  ResultStr += "__Block_byref_" + Name + 
+    "_" + utostr(BlockByRefDeclNo[VD]) ;
+}
+
+static bool HasLocalVariableExternalStorage(ValueDecl *VD) {
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    return (Var->isFunctionOrMethodVarDecl() && !Var->hasLocalStorage());
+  return false;
+}
+
+std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  const FunctionType *AFT = CE->getFunctionType();
+  QualType RT = AFT->getReturnType();
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static " + RT.getAsString(Context->getPrintingPolicy()) + " __" +
+                  funcName.str() + "_" + "block_func_" + utostr(i);
+
+  BlockDecl *BD = CE->getBlockDecl();
+
+  if (isa<FunctionNoProtoType>(AFT)) {
+    // No user-supplied arguments. Still need to pass in a pointer to the
+    // block (to reference imported block decl refs).
+    S += "(" + StructRef + " *__cself)";
+  } else if (BD->param_empty()) {
+    S += "(" + StructRef + " *__cself)";
+  } else {
+    const FunctionProtoType *FT = cast<FunctionProtoType>(AFT);
+    assert(FT && "SynthesizeBlockFunc: No function proto");
+    S += '(';
+    // first add the implicit argument.
+    S += StructRef + " *__cself, ";
+    std::string ParamStr;
+    for (BlockDecl::param_iterator AI = BD->param_begin(),
+         E = BD->param_end(); AI != E; ++AI) {
+      if (AI != BD->param_begin()) S += ", ";
+      ParamStr = (*AI)->getNameAsString();
+      QualType QT = (*AI)->getType();
+      (void)convertBlockPointerToFunctionPointer(QT);
+      QT.getAsStringInternal(ParamStr, Context->getPrintingPolicy());
+      S += ParamStr;
+    }
+    if (FT->isVariadic()) {
+      if (!BD->param_empty()) S += ", ";
+      S += "...";
+    }
+    S += ')';
+  }
+  S += " {\n";
+
+  // Create local declarations to avoid rewriting all closure decl ref exprs.
+  // First, emit a declaration for all "by ref" decls.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+       E = BlockByRefDecls.end(); I != E; ++I) {
+    S += "  ";
+    std::string Name = (*I)->getNameAsString();
+    std::string TypeString;
+    RewriteByRefString(TypeString, Name, (*I));
+    TypeString += " *";
+    Name = TypeString + Name;
+    S += Name + " = __cself->" + (*I)->getNameAsString() + "; // bound by ref\n";
+  }
+  // Next, emit a declaration for all "by copy" declarations.
+  for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+       E = BlockByCopyDecls.end(); I != E; ++I) {
+    S += "  ";
+    // Handle nested closure invocation. For example:
+    //
+    //   void (^myImportedClosure)(void);
+    //   myImportedClosure  = ^(void) { setGlobalInt(x + y); };
+    //
+    //   void (^anotherClosure)(void);
+    //   anotherClosure = ^(void) {
+    //     myImportedClosure(); // import and invoke the closure
+    //   };
+    //
+    if (isTopLevelBlockPointerType((*I)->getType())) {
+      RewriteBlockPointerTypeVariable(S, (*I));
+      S += " = (";
+      RewriteBlockPointerType(S, (*I)->getType());
+      S += ")";
+      S += "__cself->" + (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+    else {
+      std::string Name = (*I)->getNameAsString();
+      QualType QT = (*I)->getType();
+      if (HasLocalVariableExternalStorage(*I))
+        QT = Context->getPointerType(QT);
+      QT.getAsStringInternal(Name, Context->getPrintingPolicy());
+      S += Name + " = __cself->" + 
+                              (*I)->getNameAsString() + "; // bound by copy\n";
+    }
+  }
+  std::string RewrittenStr = RewrittenBlockExprs[CE];
+  const char *cstr = RewrittenStr.c_str();
+  while (*cstr++ != '{') ;
+  S += cstr;
+  S += "\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockHelperFuncs(BlockExpr *CE, int i,
+                                                   StringRef funcName,
+                                                   std::string Tag) {
+  std::string StructRef = "struct " + Tag;
+  std::string S = "static void __";
+
+  S += funcName;
+  S += "_block_copy_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*dst, " + StructRef;
+  S += "*src) {";
+  for (ValueDecl *VD : ImportedBlockDecls) {
+    S += "_Block_object_assign((void*)&dst->";
+    S += VD->getNameAsString();
+    S += ", (void*)src->";
+    S += VD->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count(VD))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  
+  S += "\nstatic void __";
+  S += funcName;
+  S += "_block_dispose_" + utostr(i);
+  S += "(" + StructRef;
+  S += "*src) {";
+  for (ValueDecl *VD : ImportedBlockDecls) {
+    S += "_Block_object_dispose((void*)src->";
+    S += VD->getNameAsString();
+    if (BlockByRefDeclsPtrSet.count(VD))
+      S += ", " + utostr(BLOCK_FIELD_IS_BYREF) + "/*BLOCK_FIELD_IS_BYREF*/);";
+    else if (VD->getType()->isBlockPointerType())
+      S += ", " + utostr(BLOCK_FIELD_IS_BLOCK) + "/*BLOCK_FIELD_IS_BLOCK*/);";
+    else
+      S += ", " + utostr(BLOCK_FIELD_IS_OBJECT) + "/*BLOCK_FIELD_IS_OBJECT*/);";
+  }
+  S += "}\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockImpl(BlockExpr *CE, std::string Tag, 
+                                             std::string Desc) {
+  std::string S = "\nstruct " + Tag;
+  std::string Constructor = "  " + Tag;
+
+  S += " {\n  struct __block_impl impl;\n";
+  S += "  struct " + Desc;
+  S += "* Desc;\n";
+
+  Constructor += "(void *fp, "; // Invoke function pointer.
+  Constructor += "struct " + Desc; // Descriptor pointer.
+  Constructor += " *desc";
+
+  if (BlockDeclRefs.size()) {
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      // Handle nested closure invocation. For example:
+      //
+      //   void (^myImportedBlock)(void);
+      //   myImportedBlock  = ^(void) { setGlobalInt(x + y); };
+      //
+      //   void (^anotherBlock)(void);
+      //   anotherBlock = ^(void) {
+      //     myImportedBlock(); // import and invoke the closure
+      //   };
+      //
+      if (isTopLevelBlockPointerType((*I)->getType())) {
+        S += "struct __block_impl *";
+        Constructor += ", void *" + ArgName;
+      } else {
+        QualType QT = (*I)->getType();
+        if (HasLocalVariableExternalStorage(*I))
+          QT = Context->getPointerType(QT);
+        QT.getAsStringInternal(FieldName, Context->getPrintingPolicy());
+        QT.getAsStringInternal(ArgName, Context->getPrintingPolicy());
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + ";\n";
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      S += "  ";
+      std::string FieldName = (*I)->getNameAsString();
+      std::string ArgName = "_" + FieldName;
+      {
+        std::string TypeString;
+        RewriteByRefString(TypeString, FieldName, (*I));
+        TypeString += " *";
+        FieldName = TypeString + FieldName;
+        ArgName = TypeString + ArgName;
+        Constructor += ", " + ArgName;
+      }
+      S += FieldName + "; // by ref\n";
+    }
+    // Finish writing the constructor.
+    Constructor += ", int flags=0)";
+    // Initialize all "by copy" arguments.
+    bool firsTime = true;
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+        if (firsTime) {
+          Constructor += " : ";
+          firsTime = false;
+        }
+        else
+          Constructor += ", ";
+        if (isTopLevelBlockPointerType((*I)->getType()))
+          Constructor += Name + "((struct __block_impl *)_" + Name + ")";
+        else
+          Constructor += Name + "(_" + Name + ")";
+    }
+    // Initialize all "by ref" arguments.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      std::string Name = (*I)->getNameAsString();
+      if (firsTime) {
+        Constructor += " : ";
+        firsTime = false;
+      }
+      else
+        Constructor += ", ";
+      Constructor += Name + "(_" + Name + "->__forwarding)";
+    }
+    
+    Constructor += " {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+
+    Constructor += "    Desc = desc;\n";
+  } else {
+    // Finish writing the constructor.
+    Constructor += ", int flags=0) {\n";
+    if (GlobalVarDecl)
+      Constructor += "    impl.isa = &_NSConcreteGlobalBlock;\n";
+    else
+      Constructor += "    impl.isa = &_NSConcreteStackBlock;\n";
+    Constructor += "    impl.Flags = flags;\n    impl.FuncPtr = fp;\n";
+    Constructor += "    Desc = desc;\n";
+  }
+  Constructor += "  ";
+  Constructor += "}\n";
+  S += Constructor;
+  S += "};\n";
+  return S;
+}
+
+std::string RewriteObjC::SynthesizeBlockDescriptor(std::string DescTag, 
+                                                   std::string ImplTag, int i,
+                                                   StringRef FunName,
+                                                   unsigned hasCopy) {
+  std::string S = "\nstatic struct " + DescTag;
+  
+  S += " {\n  unsigned long reserved;\n";
+  S += "  unsigned long Block_size;\n";
+  if (hasCopy) {
+    S += "  void (*copy)(struct ";
+    S += ImplTag; S += "*, struct ";
+    S += ImplTag; S += "*);\n";
+    
+    S += "  void (*dispose)(struct ";
+    S += ImplTag; S += "*);\n";
+  }
+  S += "} ";
+
+  S += DescTag + "_DATA = { 0, sizeof(struct ";
+  S += ImplTag + ")";
+  if (hasCopy) {
+    S += ", __" + FunName.str() + "_block_copy_" + utostr(i);
+    S += ", __" + FunName.str() + "_block_dispose_" + utostr(i);
+  }
+  S += "};\n";
+  return S;
+}
+
+void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
+                                          StringRef FunName) {
+  // Insert declaration for the function in which block literal is used.
+  if (CurFunctionDeclToDeclareForBlock && !Blocks.empty())
+    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
+  bool RewriteSC = (GlobalVarDecl &&
+                    !Blocks.empty() &&
+                    GlobalVarDecl->getStorageClass() == SC_Static &&
+                    GlobalVarDecl->getType().getCVRQualifiers());
+  if (RewriteSC) {
+    std::string SC(" void __");
+    SC += GlobalVarDecl->getNameAsString();
+    SC += "() {}";
+    InsertText(FunLocStart, SC);
+  }
+  
+  // Insert closures that were part of the function.
+  for (unsigned i = 0, count=0; i < Blocks.size(); i++) {
+    CollectBlockDeclRefInfo(Blocks[i]);
+    // Need to copy-in the inner copied-in variables not actually used in this
+    // block.
+    for (int j = 0; j < InnerDeclRefsCount[i]; j++) {
+      DeclRefExpr *Exp = InnerDeclRefs[count++];
+      ValueDecl *VD = Exp->getDecl();
+      BlockDeclRefs.push_back(Exp);
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+      // imported objects in the inner blocks not used in the outer
+      // blocks must be copied/disposed in the outer block as well.
+      if (VD->hasAttr<BlocksAttr>() ||
+          VD->getType()->isObjCObjectPointerType() || 
+          VD->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(VD);
+    }
+
+    std::string ImplTag = "__" + FunName.str() + "_block_impl_" + utostr(i);
+    std::string DescTag = "__" + FunName.str() + "_block_desc_" + utostr(i);
+
+    std::string CI = SynthesizeBlockImpl(Blocks[i], ImplTag, DescTag);
+
+    InsertText(FunLocStart, CI);
+
+    std::string CF = SynthesizeBlockFunc(Blocks[i], i, FunName, ImplTag);
+
+    InsertText(FunLocStart, CF);
+
+    if (ImportedBlockDecls.size()) {
+      std::string HF = SynthesizeBlockHelperFuncs(Blocks[i], i, FunName, ImplTag);
+      InsertText(FunLocStart, HF);
+    }
+    std::string BD = SynthesizeBlockDescriptor(DescTag, ImplTag, i, FunName,
+                                               ImportedBlockDecls.size() > 0);
+    InsertText(FunLocStart, BD);
+
+    BlockDeclRefs.clear();
+    BlockByRefDecls.clear();
+    BlockByRefDeclsPtrSet.clear();
+    BlockByCopyDecls.clear();
+    BlockByCopyDeclsPtrSet.clear();
+    ImportedBlockDecls.clear();
+  }
+  if (RewriteSC) {
+    // Must insert any 'const/volatile/static here. Since it has been
+    // removed as result of rewriting of block literals.
+    std::string SC;
+    if (GlobalVarDecl->getStorageClass() == SC_Static)
+      SC = "static ";
+    if (GlobalVarDecl->getType().isConstQualified())
+      SC += "const ";
+    if (GlobalVarDecl->getType().isVolatileQualified())
+      SC += "volatile ";
+    if (GlobalVarDecl->getType().isRestrictQualified())
+      SC += "restrict ";
+    InsertText(FunLocStart, SC);
+  }
+  
+  Blocks.clear();
+  InnerDeclRefsCount.clear();
+  InnerDeclRefs.clear();
+  RewrittenBlockExprs.clear();
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
+  SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
+  StringRef FuncName = FD->getName();
+
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+static void BuildUniqueMethodName(std::string &Name,
+                                  ObjCMethodDecl *MD) {
+  ObjCInterfaceDecl *IFace = MD->getClassInterface();
+  Name = IFace->getName();
+  Name += "__" + MD->getSelector().getAsString();
+  // Convert colons to underscores.
+  std::string::size_type loc = 0;
+  while ((loc = Name.find(":", loc)) != std::string::npos)
+    Name.replace(loc, 1, "_");
+}
+
+void RewriteObjC::InsertBlockLiteralsWithinMethod(ObjCMethodDecl *MD) {
+  //fprintf(stderr,"In InsertBlockLiteralsWitinMethod\n");
+  //SourceLocation FunLocStart = MD->getLocStart();
+  SourceLocation FunLocStart = MD->getLocStart();
+  std::string FuncName;
+  BuildUniqueMethodName(FuncName, MD);
+  SynthesizeBlockLiterals(FunLocStart, FuncName);
+}
+
+void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI))
+        GetBlockDeclRefExprs(CBE->getBody());
+      else
+        GetBlockDeclRefExprs(*CI);
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      // FIXME: Handle enums.
+      if (!isa<FunctionDecl>(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+      if (HasLocalVariableExternalStorage(DRE->getDecl()))
+        BlockDeclRefs.push_back(DRE);
+    }
+  }
+  
+  return;
+}
+
+void RewriteObjC::GetInnerBlockDeclRefExprs(Stmt *S,
+                SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs,
+                llvm::SmallPtrSetImpl<const DeclContext *> &InnerContexts) {
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) {
+        InnerContexts.insert(cast<DeclContext>(CBE->getBlockDecl()));
+        GetInnerBlockDeclRefExprs(CBE->getBody(),
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+      }
+      else
+        GetInnerBlockDeclRefExprs(*CI,
+                                  InnerBlockDeclRefs,
+                                  InnerContexts);
+
+    }
+  // Handle specific things.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (DRE->refersToEnclosingLocal()) {
+      if (!isa<FunctionDecl>(DRE->getDecl()) &&
+          !InnerContexts.count(DRE->getDecl()->getDeclContext()))
+        InnerBlockDeclRefs.push_back(DRE);
+      if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl()))
+        if (Var->isFunctionOrMethodVarDecl())
+          ImportedLocalExternalDecls.insert(Var);
+    }
+  }
+  
+  return;
+}
+
+/// convertFunctionTypeOfBlocks - This routine converts a function type
+/// whose result type may be a block pointer or whose argument type(s)
+/// might be block pointers to an equivalent function type replacing
+/// all block pointers to function pointers.
+QualType RewriteObjC::convertFunctionTypeOfBlocks(const FunctionType *FT) {
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+  QualType Res = FT->getReturnType();
+  bool HasBlockType = convertBlockPointerToFunctionPointer(Res);
+  
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (convertBlockPointerToFunctionPointer(t))
+        HasBlockType = true;
+      ArgTypes.push_back(t);
+    }
+  }
+  QualType FuncType;
+  // FIXME. Does this work if block takes no argument but has a return type
+  // which is of block type?
+  if (HasBlockType)
+    FuncType = getSimpleFunctionType(Res, ArgTypes);
+  else FuncType = QualType(FT, 0);
+  return FuncType;
+}
+
+Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) {
+  // Navigate to relevant type information.
+  const BlockPointerType *CPT = nullptr;
+
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BlockExp)) {
+    CPT = DRE->getType()->getAs<BlockPointerType>();
+  } else if (const MemberExpr *MExpr = dyn_cast<MemberExpr>(BlockExp)) {
+    CPT = MExpr->getType()->getAs<BlockPointerType>();
+  } 
+  else if (const ParenExpr *PRE = dyn_cast<ParenExpr>(BlockExp)) {
+    return SynthesizeBlockCall(Exp, PRE->getSubExpr());
+  }
+  else if (const ImplicitCastExpr *IEXPR = dyn_cast<ImplicitCastExpr>(BlockExp)) 
+    CPT = IEXPR->getType()->getAs<BlockPointerType>();
+  else if (const ConditionalOperator *CEXPR = 
+            dyn_cast<ConditionalOperator>(BlockExp)) {
+    Expr *LHSExp = CEXPR->getLHS();
+    Stmt *LHSStmt = SynthesizeBlockCall(Exp, LHSExp);
+    Expr *RHSExp = CEXPR->getRHS();
+    Stmt *RHSStmt = SynthesizeBlockCall(Exp, RHSExp);
+    Expr *CONDExp = CEXPR->getCond();
+    ConditionalOperator *CondExpr =
+      new (Context) ConditionalOperator(CONDExp,
+                                      SourceLocation(), cast<Expr>(LHSStmt),
+                                      SourceLocation(), cast<Expr>(RHSStmt),
+                                      Exp->getType(), VK_RValue, OK_Ordinary);
+    return CondExpr;
+  } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) {
+    CPT = IRE->getType()->getAs<BlockPointerType>();
+  } else if (const PseudoObjectExpr *POE
+               = dyn_cast<PseudoObjectExpr>(BlockExp)) {
+    CPT = POE->getType()->castAs<BlockPointerType>();
+  } else {
+    assert(1 && "RewriteBlockClass: Bad type");
+  }
+  assert(CPT && "RewriteBlockClass: Bad type");
+  const FunctionType *FT = CPT->getPointeeType()->getAs<FunctionType>();
+  assert(FT && "RewriteBlockClass: Bad type");
+  const FunctionProtoType *FTP = dyn_cast<FunctionProtoType>(FT);
+  // FTP will be null for closures that don't take arguments.
+
+  RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                      SourceLocation(), SourceLocation(),
+                                      &Context->Idents.get("__block_impl"));
+  QualType PtrBlock = Context->getPointerType(Context->getTagDeclType(RD));
+
+  // Generate a funky cast.
+  SmallVector<QualType, 8> ArgTypes;
+
+  // Push the block argument type.
+  ArgTypes.push_back(PtrBlock);
+  if (FTP) {
+    for (auto &I : FTP->param_types()) {
+      QualType t = I;
+      // Make sure we convert "t (^)(...)" to "t (*)(...)".
+      if (!convertBlockPointerToFunctionPointer(t))
+        convertToUnqualifiedObjCType(t);
+      ArgTypes.push_back(t);
+    }
+  }
+  // Now do the pointer to function cast.
+  QualType PtrToFuncCastType = getSimpleFunctionType(Exp->getType(), ArgTypes);
+
+  PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType);
+
+  CastExpr *BlkCast = NoTypeInfoCStyleCastExpr(Context, PtrBlock,
+                                               CK_BitCast,
+                                               const_cast<Expr*>(BlockExp));
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(),
+                                          BlkCast);
+  //PE->dump();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("FuncPtr"),
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  
+  CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType,
+                                                CK_BitCast, ME);
+  PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), FunkCast);
+
+  SmallVector<Expr*, 8> BlkExprs;
+  // Add the implicit argument.
+  BlkExprs.push_back(BlkCast);
+  // Add the user arguments.
+  for (CallExpr::arg_iterator I = Exp->arg_begin(),
+       E = Exp->arg_end(); I != E; ++I) {
+    BlkExprs.push_back(*I);
+  }
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, BlkExprs,
+                                        Exp->getType(), VK_RValue,
+                                        SourceLocation());
+  return CE;
+}
+
+// We need to return the rewritten expression to handle cases where the
+// BlockDeclRefExpr is embedded in another expression being rewritten.
+// For example:
+//
+// int main() {
+//    __block Foo *f;
+//    __block int i;
+//
+//    void (^myblock)() = ^() {
+//        [f test]; // f is a BlockDeclRefExpr embedded in a message (which is being rewritten).
+//        i = 77;
+//    };
+//}
+Stmt *RewriteObjC::RewriteBlockDeclRefExpr(DeclRefExpr *DeclRefExp) {
+  // Rewrite the byref variable into BYREFVAR->__forwarding->BYREFVAR 
+  // for each DeclRefExp where BYREFVAR is name of the variable.
+  ValueDecl *VD = DeclRefExp->getDecl();
+  bool isArrow = DeclRefExp->refersToEnclosingLocal();
+
+  FieldDecl *FD = FieldDecl::Create(*Context, nullptr, SourceLocation(),
+                                    SourceLocation(),
+                                    &Context->Idents.get("__forwarding"), 
+                                    Context->VoidPtrTy, nullptr,
+                                    /*BitWidth=*/nullptr, /*Mutable=*/true,
+                                    ICIS_NoInit);
+  MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow,
+                                            FD, SourceLocation(),
+                                            FD->getType(), VK_LValue,
+                                            OK_Ordinary);
+
+  StringRef Name = VD->getName();
+  FD = FieldDecl::Create(*Context, nullptr, SourceLocation(), SourceLocation(),
+                         &Context->Idents.get(Name), 
+                         Context->VoidPtrTy, nullptr,
+                         /*BitWidth=*/nullptr, /*Mutable=*/true,
+                         ICIS_NoInit);
+  ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(),
+                                DeclRefExp->getType(), VK_LValue, OK_Ordinary);
+  
+  
+  
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(DeclRefExp->getExprLoc(), 
+                                          DeclRefExp->getExprLoc(), 
+                                          ME);
+  ReplaceStmt(DeclRefExp, PE);
+  return PE;
+}
+
+// Rewrites the imported local variable V with external storage 
+// (static, extern, etc.) as *V
+//
+Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) {
+  ValueDecl *VD = DRE->getDecl();
+  if (VarDecl *Var = dyn_cast<VarDecl>(VD))
+    if (!ImportedLocalExternalDecls.count(Var))
+      return DRE;
+  Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(),
+                                          VK_LValue, OK_Ordinary,
+                                          DRE->getLocation());
+  // Need parens to enforce precedence.
+  ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), 
+                                          Exp);
+  ReplaceStmt(DRE, PE);
+  return PE;
+}
+
+void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) {
+  SourceLocation LocStart = CE->getLParenLoc();
+  SourceLocation LocEnd = CE->getRParenLoc();
+
+  // Need to avoid trying to rewrite synthesized casts.
+  if (LocStart.isInvalid())
+    return;
+  // Need to avoid trying to rewrite casts contained in macros.
+  if (!Rewriter::isRewritable(LocStart) || !Rewriter::isRewritable(LocEnd))
+    return;
+
+  const char *startBuf = SM->getCharacterData(LocStart);
+  const char *endBuf = SM->getCharacterData(LocEnd);
+  QualType QT = CE->getType();
+  const Type* TypePtr = QT->getAs<Type>();
+  if (isa<TypeOfExprType>(TypePtr)) {
+    const TypeOfExprType *TypeOfExprTypePtr = cast<TypeOfExprType>(TypePtr);
+    QT = TypeOfExprTypePtr->getUnderlyingExpr()->getType();
+    std::string TypeAsString = "(";
+    RewriteBlockPointerType(TypeAsString, QT);
+    TypeAsString += ")";
+    ReplaceText(LocStart, endBuf-startBuf+1, TypeAsString);
+    return;
+  }
+  // advance the location to startArgList.
+  const char *argPtr = startBuf;
+
+  while (*argPtr++ && (argPtr < endBuf)) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      LocStart = LocStart.getLocWithOffset(argPtr-startBuf);
+      ReplaceText(LocStart, 1, "*");
+      break;
+    }
+  }
+  return;
+}
+
+void RewriteObjC::RewriteBlockPointerFunctionArgs(FunctionDecl *FD) {
+  SourceLocation DeclLoc = FD->getLocation();
+  unsigned parenCount = 0;
+
+  // We have 1 or more arguments that have closure pointers.
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *startArgList = strchr(startBuf, '(');
+
+  assert((*startArgList == '(') && "Rewriter fuzzy parser confused");
+
+  parenCount++;
+  // advance the location to startArgList.
+  DeclLoc = DeclLoc.getLocWithOffset(startArgList-startBuf);
+  assert((DeclLoc.isValid()) && "Invalid DeclLoc");
+
+  const char *argPtr = startArgList;
+
+  while (*argPtr++ && parenCount) {
+    switch (*argPtr) {
+    case '^':
+      // Replace the '^' with '*'.
+      DeclLoc = DeclLoc.getLocWithOffset(argPtr-startArgList);
+      ReplaceText(DeclLoc, 1, "*");
+      break;
+    case '(':
+      parenCount++;
+      break;
+    case ')':
+      parenCount--;
+      break;
+    }
+  }
+  return;
+}
+
+bool RewriteObjC::PointerTypeTakesAnyBlockArguments(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types())
+      if (isTopLevelBlockPointerType(I))
+        return true;
+  }
+  return false;
+}
+
+bool RewriteObjC::PointerTypeTakesAnyObjCQualifiedType(QualType QT) {
+  const FunctionProtoType *FTP;
+  const PointerType *PT = QT->getAs<PointerType>();
+  if (PT) {
+    FTP = PT->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    const BlockPointerType *BPT = QT->getAs<BlockPointerType>();
+    assert(BPT && "BlockPointerTypeTakeAnyBlockArguments(): not a block pointer type");
+    FTP = BPT->getPointeeType()->getAs<FunctionProtoType>();
+  }
+  if (FTP) {
+    for (const auto &I : FTP->param_types()) {
+      if (I->isObjCQualifiedIdType())
+        return true;
+      if (I->isObjCObjectPointerType() &&
+          I->getPointeeType()->isObjCQualifiedInterfaceType())
+        return true;
+    }
+        
+  }
+  return false;
+}
+
+void RewriteObjC::GetExtentOfArgList(const char *Name, const char *&LParen,
+                                     const char *&RParen) {
+  const char *argPtr = strchr(Name, '(');
+  assert((*argPtr == '(') && "Rewriter fuzzy parser confused");
+
+  LParen = argPtr; // output the start.
+  argPtr++; // skip past the left paren.
+  unsigned parenCount = 1;
+
+  while (*argPtr && parenCount) {
+    switch (*argPtr) {
+    case '(': parenCount++; break;
+    case ')': parenCount--; break;
+    default: break;
+    }
+    if (parenCount) argPtr++;
+  }
+  assert((*argPtr == ')') && "Rewriter fuzzy parser confused");
+  RParen = argPtr; // output the end
+}
+
+void RewriteObjC::RewriteBlockPointerDecl(NamedDecl *ND) {
+  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+    RewriteBlockPointerFunctionArgs(FD);
+    return;
+  }
+  // Handle Variables and Typedefs.
+  SourceLocation DeclLoc = ND->getLocation();
+  QualType DeclT;
+  if (VarDecl *VD = dyn_cast<VarDecl>(ND))
+    DeclT = VD->getType();
+  else if (TypedefNameDecl *TDD = dyn_cast<TypedefNameDecl>(ND))
+    DeclT = TDD->getUnderlyingType();
+  else if (FieldDecl *FD = dyn_cast<FieldDecl>(ND))
+    DeclT = FD->getType();
+  else
+    llvm_unreachable("RewriteBlockPointerDecl(): Decl type not yet handled");
+
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  const char *endBuf = startBuf;
+  // scan backward (from the decl location) for the end of the previous decl.
+  while (*startBuf != '^' && *startBuf != ';' && startBuf != MainFileStart)
+    startBuf--;
+  SourceLocation Start = DeclLoc.getLocWithOffset(startBuf-endBuf);
+  std::string buf;
+  unsigned OrigLength=0;
+  // *startBuf != '^' if we are dealing with a pointer to function that
+  // may take block argument types (which will be handled below).
+  if (*startBuf == '^') {
+    // Replace the '^' with '*', computing a negative offset.
+    buf = '*';
+    startBuf++;
+    OrigLength++;
+  }
+  while (*startBuf != ')') {
+    buf += *startBuf;
+    startBuf++;
+    OrigLength++;
+  }
+  buf += ')';
+  OrigLength++;
+  
+  if (PointerTypeTakesAnyBlockArguments(DeclT) ||
+      PointerTypeTakesAnyObjCQualifiedType(DeclT)) {
+    // Replace the '^' with '*' for arguments.
+    // Replace id<P> with id/*<>*/
+    DeclLoc = ND->getLocation();
+    startBuf = SM->getCharacterData(DeclLoc);
+    const char *argListBegin, *argListEnd;
+    GetExtentOfArgList(startBuf, argListBegin, argListEnd);
+    while (argListBegin < argListEnd) {
+      if (*argListBegin == '^')
+        buf += '*';
+      else if (*argListBegin ==  '<') {
+        buf += "/*"; 
+        buf += *argListBegin++;
+        OrigLength++;
+        while (*argListBegin != '>') {
+          buf += *argListBegin++;
+          OrigLength++;
+        }
+        buf += *argListBegin;
+        buf += "*/";
+      }
+      else
+        buf += *argListBegin;
+      argListBegin++;
+      OrigLength++;
+    }
+    buf += ')';
+    OrigLength++;
+  }
+  ReplaceText(Start, OrigLength, buf);
+  
+  return;
+}
+
+
+/// SynthesizeByrefCopyDestroyHelper - This routine synthesizes:
+/// void __Block_byref_id_object_copy(struct Block_byref_id_object *dst,
+///                    struct Block_byref_id_object *src) {
+///  _Block_object_assign (&_dest->object, _src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_assign(&_dest->object, _src->object, 
+///                       BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                       [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+/// And:
+/// void __Block_byref_id_object_dispose(struct Block_byref_id_object *_src) {
+///  _Block_object_dispose(_src->object, 
+///                        BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT
+///                        [|BLOCK_FIELD_IS_WEAK]) // object
+///  _Block_object_dispose(_src->object, 
+///                         BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK
+///                         [|BLOCK_FIELD_IS_WEAK]) // block
+/// }
+
+std::string RewriteObjC::SynthesizeByrefCopyDestroyHelper(VarDecl *VD,
+                                                          int flag) {
+  std::string S;
+  if (CopyDestroyCache.count(flag))
+    return S;
+  CopyDestroyCache.insert(flag);
+  S = "static void __Block_byref_id_object_copy_";
+  S += utostr(flag);
+  S += "(void *dst, void *src) {\n";
+  
+  // offset into the object pointer is computed as:
+  // void * + void* + int + int + void* + void *
+  unsigned IntSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+  unsigned VoidPtrSize = 
+  static_cast<unsigned>(Context->getTypeSize(Context->VoidPtrTy));
+  
+  unsigned offset = (VoidPtrSize*4 + IntSize + IntSize)/Context->getCharWidth();
+  S += " _Block_object_assign((char*)dst + ";
+  S += utostr(offset);
+  S += ", *(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  
+  S += "static void __Block_byref_id_object_dispose_";
+  S += utostr(flag);
+  S += "(void *src) {\n";
+  S += " _Block_object_dispose(*(void * *) ((char*)src + ";
+  S += utostr(offset);
+  S += "), ";
+  S += utostr(flag);
+  S += ");\n}\n";
+  return S;
+}
+
+/// RewriteByRefVar - For each __block typex ND variable this routine transforms
+/// the declaration into:
+/// struct __Block_byref_ND {
+/// void *__isa;                  // NULL for everything except __weak pointers
+/// struct __Block_byref_ND *__forwarding;
+/// int32_t __flags;
+/// int32_t __size;
+/// void *__Block_byref_id_object_copy; // If variable is __block ObjC object
+/// void *__Block_byref_id_object_dispose; // If variable is __block ObjC object
+/// typex ND;
+/// };
+///
+/// It then replaces declaration of ND variable with:
+/// struct __Block_byref_ND ND = {__isa=0B, __forwarding=&ND, __flags=some_flag, 
+///                               __size=sizeof(struct __Block_byref_ND), 
+///                               ND=initializer-if-any};
+///
+///
+void RewriteObjC::RewriteByRefVar(VarDecl *ND) {
+  // Insert declaration for the function in which block literal is
+  // used.
+  if (CurFunctionDeclToDeclareForBlock)
+    RewriteBlockLiteralFunctionDecl(CurFunctionDeclToDeclareForBlock);
+  int flag = 0;
+  int isa = 0;
+  SourceLocation DeclLoc = ND->getTypeSpecStartLoc();
+  if (DeclLoc.isInvalid())
+    // If type location is missing, it is because of missing type (a warning).
+    // Use variable's location which is good for this case.
+    DeclLoc = ND->getLocation();
+  const char *startBuf = SM->getCharacterData(DeclLoc);
+  SourceLocation X = ND->getLocEnd();
+  X = SM->getExpansionLoc(X);
+  const char *endBuf = SM->getCharacterData(X);
+  std::string Name(ND->getNameAsString());
+  std::string ByrefType;
+  RewriteByRefString(ByrefType, Name, ND, true);
+  ByrefType += " {\n";
+  ByrefType += "  void *__isa;\n";
+  RewriteByRefString(ByrefType, Name, ND);
+  ByrefType += " *__forwarding;\n";
+  ByrefType += " int __flags;\n";
+  ByrefType += " int __size;\n";
+  // Add void *__Block_byref_id_object_copy; 
+  // void *__Block_byref_id_object_dispose; if needed.
+  QualType Ty = ND->getType();
+  bool HasCopyAndDispose = Context->BlockRequiresCopying(Ty, ND);
+  if (HasCopyAndDispose) {
+    ByrefType += " void (*__Block_byref_id_object_copy)(void*, void*);\n";
+    ByrefType += " void (*__Block_byref_id_object_dispose)(void*);\n";
+  }
+
+  QualType T = Ty;
+  (void)convertBlockPointerToFunctionPointer(T);
+  T.getAsStringInternal(Name, Context->getPrintingPolicy());
+    
+  ByrefType += " " + Name + ";\n";
+  ByrefType += "};\n";
+  // Insert this type in global scope. It is needed by helper function.
+  SourceLocation FunLocStart;
+  if (CurFunctionDef)
+     FunLocStart = CurFunctionDef->getTypeSpecStartLoc();
+  else {
+    assert(CurMethodDef && "RewriteByRefVar - CurMethodDef is null");
+    FunLocStart = CurMethodDef->getLocStart();
+  }
+  InsertText(FunLocStart, ByrefType);
+  if (Ty.isObjCGCWeak()) {
+    flag |= BLOCK_FIELD_IS_WEAK;
+    isa = 1;
+  }
+  
+  if (HasCopyAndDispose) {
+    flag = BLOCK_BYREF_CALLER;
+    QualType Ty = ND->getType();
+    // FIXME. Handle __weak variable (BLOCK_FIELD_IS_WEAK) as well.
+    if (Ty->isBlockPointerType())
+      flag |= BLOCK_FIELD_IS_BLOCK;
+    else
+      flag |= BLOCK_FIELD_IS_OBJECT;
+    std::string HF = SynthesizeByrefCopyDestroyHelper(ND, flag);
+    if (!HF.empty())
+      InsertText(FunLocStart, HF);
+  }
+  
+  // struct __Block_byref_ND ND = 
+  // {0, &ND, some_flag, __size=sizeof(struct __Block_byref_ND), 
+  //  initializer-if-any};
+  bool hasInit = (ND->getInit() != nullptr);
+  unsigned flags = 0;
+  if (HasCopyAndDispose)
+    flags |= BLOCK_HAS_COPY_DISPOSE;
+  Name = ND->getNameAsString();
+  ByrefType.clear();
+  RewriteByRefString(ByrefType, Name, ND);
+  std::string ForwardingCastType("(");
+  ForwardingCastType += ByrefType + " *)";
+  if (!hasInit) {
+    ByrefType += " " + Name + " = {(void*)";
+    ByrefType += utostr(isa);
+    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+    ByrefType += utostr(flags);
+    ByrefType += ", ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += ")";
+    if (HasCopyAndDispose) {
+      ByrefType += ", __Block_byref_id_object_copy_";
+      ByrefType += utostr(flag);
+      ByrefType += ", __Block_byref_id_object_dispose_";
+      ByrefType += utostr(flag);
+    }
+    ByrefType += "};\n";
+    unsigned nameSize = Name.size();
+    // for block or function pointer declaration. Name is aleady
+    // part of the declaration.
+    if (Ty->isBlockPointerType() || Ty->isFunctionPointerType())
+      nameSize = 1;
+    ReplaceText(DeclLoc, endBuf-startBuf+nameSize, ByrefType);
+  }
+  else {
+    SourceLocation startLoc;
+    Expr *E = ND->getInit();
+    if (const CStyleCastExpr *ECE = dyn_cast<CStyleCastExpr>(E))
+      startLoc = ECE->getLParenLoc();
+    else
+      startLoc = E->getLocStart();
+    startLoc = SM->getExpansionLoc(startLoc);
+    endBuf = SM->getCharacterData(startLoc);
+    ByrefType += " " + Name;
+    ByrefType += " = {(void*)";
+    ByrefType += utostr(isa);
+    ByrefType += "," +  ForwardingCastType + "&" + Name + ", ";
+    ByrefType += utostr(flags);
+    ByrefType += ", ";
+    ByrefType += "sizeof(";
+    RewriteByRefString(ByrefType, Name, ND);
+    ByrefType += "), ";
+    if (HasCopyAndDispose) {
+      ByrefType += "__Block_byref_id_object_copy_";
+      ByrefType += utostr(flag);
+      ByrefType += ", __Block_byref_id_object_dispose_";
+      ByrefType += utostr(flag);
+      ByrefType += ", ";
+    }
+    ReplaceText(DeclLoc, endBuf-startBuf, ByrefType);
+    
+    // Complete the newly synthesized compound expression by inserting a right
+    // curly brace before the end of the declaration.
+    // FIXME: This approach avoids rewriting the initializer expression. It
+    // also assumes there is only one declarator. For example, the following
+    // isn't currently supported by this routine (in general):
+    // 
+    // double __block BYREFVAR = 1.34, BYREFVAR2 = 1.37;
+    //
+    const char *startInitializerBuf = SM->getCharacterData(startLoc);
+    const char *semiBuf = strchr(startInitializerBuf, ';');
+    assert((*semiBuf == ';') && "RewriteByRefVar: can't find ';'");
+    SourceLocation semiLoc =
+      startLoc.getLocWithOffset(semiBuf-startInitializerBuf);
+
+    InsertText(semiLoc, "}");
+  }
+  return;
+}
+
+void RewriteObjC::CollectBlockDeclRefInfo(BlockExpr *Exp) {
+  // Add initializers for any closure decl refs.
+  GetBlockDeclRefExprs(Exp->getBody());
+  if (BlockDeclRefs.size()) {
+    // Unique all "by copy" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (!BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByCopyDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByCopyDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByCopyDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Unique all "by ref" declarations.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>()) {
+        if (!BlockByRefDeclsPtrSet.count(BlockDeclRefs[i]->getDecl())) {
+          BlockByRefDeclsPtrSet.insert(BlockDeclRefs[i]->getDecl());
+          BlockByRefDecls.push_back(BlockDeclRefs[i]->getDecl());
+        }
+      }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < BlockDeclRefs.size(); i++)
+      if (BlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          BlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          BlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(BlockDeclRefs[i]->getDecl());
+  }
+}
+
+FunctionDecl *RewriteObjC::SynthBlockInitFunctionDecl(StringRef name) {
+  IdentifierInfo *ID = &Context->Idents.get(name);
+  QualType FType = Context->getFunctionNoProtoType(Context->VoidPtrTy);
+  return FunctionDecl::Create(*Context, TUDecl, SourceLocation(),
+                              SourceLocation(), ID, FType, nullptr, SC_Extern,
+                              false, false);
+}
+
+Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp,
+                     const SmallVectorImpl<DeclRefExpr *> &InnerBlockDeclRefs) {
+  const BlockDecl *block = Exp->getBlockDecl();
+  Blocks.push_back(Exp);
+
+  CollectBlockDeclRefInfo(Exp);
+  
+  // Add inner imported variables now used in current block.
+ int countOfInnerDecls = 0;
+  if (!InnerBlockDeclRefs.empty()) {
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++) {
+      DeclRefExpr *Exp = InnerBlockDeclRefs[i];
+      ValueDecl *VD = Exp->getDecl();
+      if (!VD->hasAttr<BlocksAttr>() && !BlockByCopyDeclsPtrSet.count(VD)) {
+      // We need to save the copied-in variables in nested
+      // blocks because it is needed at the end for some of the API generations.
+      // See SynthesizeBlockLiterals routine.
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByCopyDeclsPtrSet.insert(VD);
+        BlockByCopyDecls.push_back(VD);
+      }
+      if (VD->hasAttr<BlocksAttr>() && !BlockByRefDeclsPtrSet.count(VD)) {
+        InnerDeclRefs.push_back(Exp); countOfInnerDecls++;
+        BlockDeclRefs.push_back(Exp);
+        BlockByRefDeclsPtrSet.insert(VD);
+        BlockByRefDecls.push_back(VD);
+      }
+    }
+    // Find any imported blocks...they will need special attention.
+    for (unsigned i = 0; i < InnerBlockDeclRefs.size(); i++)
+      if (InnerBlockDeclRefs[i]->getDecl()->hasAttr<BlocksAttr>() ||
+          InnerBlockDeclRefs[i]->getType()->isObjCObjectPointerType() || 
+          InnerBlockDeclRefs[i]->getType()->isBlockPointerType())
+        ImportedBlockDecls.insert(InnerBlockDeclRefs[i]->getDecl());
+  }
+  InnerDeclRefsCount.push_back(countOfInnerDecls);
+  
+  std::string FuncName;
+
+  if (CurFunctionDef)
+    FuncName = CurFunctionDef->getNameAsString();
+  else if (CurMethodDef)
+    BuildUniqueMethodName(FuncName, CurMethodDef);
+  else if (GlobalVarDecl)
+    FuncName = std::string(GlobalVarDecl->getNameAsString());
+
+  std::string BlockNumber = utostr(Blocks.size()-1);
+
+  std::string Tag = "__" + FuncName + "_block_impl_" + BlockNumber;
+  std::string Func = "__" + FuncName + "_block_func_" + BlockNumber;
+
+  // Get a pointer to the function type so we can cast appropriately.
+  QualType BFT = convertFunctionTypeOfBlocks(Exp->getFunctionType());
+  QualType FType = Context->getPointerType(BFT);
+
+  FunctionDecl *FD;
+  Expr *NewRep;
+
+  // Simulate a constructor call...
+  FD = SynthBlockInitFunctionDecl(Tag);
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, false, FType, VK_RValue,
+                                               SourceLocation());
+
+  SmallVector<Expr*, 4> InitExprs;
+
+  // Initialize the block function.
+  FD = SynthBlockInitFunctionDecl(Func);
+  DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, false, FD->getType(),
+                                               VK_LValue, SourceLocation());
+  CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                                CK_BitCast, Arg);
+  InitExprs.push_back(castExpr);
+
+  // Initialize the block descriptor.
+  std::string DescData = "__" + FuncName + "_block_desc_" + BlockNumber + "_DATA";
+
+  VarDecl *NewVD = VarDecl::Create(*Context, TUDecl,
+                                   SourceLocation(), SourceLocation(),
+                                   &Context->Idents.get(DescData.c_str()),
+                                   Context->VoidPtrTy, nullptr,
+                                   SC_Static);
+  UnaryOperator *DescRefExpr =
+    new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, false,
+                                                          Context->VoidPtrTy,
+                                                          VK_LValue,
+                                                          SourceLocation()), 
+                                UO_AddrOf,
+                                Context->getPointerType(Context->VoidPtrTy), 
+                                VK_RValue, OK_Ordinary,
+                                SourceLocation());
+  InitExprs.push_back(DescRefExpr); 
+  
+  // Add initializers for any closure decl refs.
+  if (BlockDeclRefs.size()) {
+    Expr *Exp;
+    // Output all "by copy" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByCopyDecls.begin(),
+         E = BlockByCopyDecls.end(); I != E; ++I) {
+      if (isObjCType((*I)->getType())) {
+        // FIXME: Conform to ABI ([[obj retain] autorelease]).
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                        SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+      } else if (isTopLevelBlockPointerType((*I)->getType())) {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Arg = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                        SourceLocation());
+        Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy,
+                                       CK_BitCast, Arg);
+      } else {
+        FD = SynthBlockInitFunctionDecl((*I)->getName());
+        Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                        SourceLocation());
+        if (HasLocalVariableExternalStorage(*I)) {
+          QualType QT = (*I)->getType();
+          QT = Context->getPointerType(QT);
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue,
+                                            OK_Ordinary, SourceLocation());
+        }
+        
+      }
+      InitExprs.push_back(Exp);
+    }
+    // Output all "by ref" declarations.
+    for (SmallVectorImpl<ValueDecl *>::iterator I = BlockByRefDecls.begin(),
+         E = BlockByRefDecls.end(); I != E; ++I) {
+      ValueDecl *ND = (*I);
+      std::string Name(ND->getNameAsString());
+      std::string RecName;
+      RewriteByRefString(RecName, Name, ND, true);
+      IdentifierInfo *II = &Context->Idents.get(RecName.c_str() 
+                                                + sizeof("struct"));
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "SynthBlockInitExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      
+      FD = SynthBlockInitFunctionDecl((*I)->getName());
+      Exp = new (Context) DeclRefExpr(FD, false, FD->getType(), VK_LValue,
+                                      SourceLocation());
+      bool isNestedCapturedVar = false;
+      if (block)
+        for (const auto &CI : block->captures()) {
+          const VarDecl *variable = CI.getVariable();
+          if (variable == ND && CI.isNested()) {
+            assert (CI.isByRef() && 
+                    "SynthBlockInitExpr - captured block variable is not byref");
+            isNestedCapturedVar = true;
+            break;
+          }
+        }
+      // captured nested byref variable has its address passed. Do not take
+      // its address again.
+      if (!isNestedCapturedVar)
+          Exp = new (Context) UnaryOperator(Exp, UO_AddrOf,
+                                     Context->getPointerType(Exp->getType()),
+                                     VK_RValue, OK_Ordinary, SourceLocation());
+      Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp);
+      InitExprs.push_back(Exp);
+    }
+  }
+  if (ImportedBlockDecls.size()) {
+    // generate BLOCK_HAS_COPY_DISPOSE(have helper funcs) | BLOCK_HAS_DESCRIPTOR
+    int flag = (BLOCK_HAS_COPY_DISPOSE | BLOCK_HAS_DESCRIPTOR);
+    unsigned IntSize = 
+      static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
+    Expr *FlagExp = IntegerLiteral::Create(*Context, llvm::APInt(IntSize, flag), 
+                                           Context->IntTy, SourceLocation());
+    InitExprs.push_back(FlagExp);
+  }
+  NewRep = new (Context) CallExpr(*Context, DRE, InitExprs,
+                                  FType, VK_LValue, SourceLocation());
+  NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf,
+                             Context->getPointerType(NewRep->getType()),
+                             VK_RValue, OK_Ordinary, SourceLocation());
+  NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast,
+                                    NewRep);
+  BlockDeclRefs.clear();
+  BlockByRefDecls.clear();
+  BlockByRefDeclsPtrSet.clear();
+  BlockByCopyDecls.clear();
+  BlockByCopyDeclsPtrSet.clear();
+  ImportedBlockDecls.clear();
+  return NewRep;
+}
+
+bool RewriteObjC::IsDeclStmtInForeachHeader(DeclStmt *DS) {
+  if (const ObjCForCollectionStmt * CS = 
+      dyn_cast<ObjCForCollectionStmt>(Stmts.back()))
+        return CS->getElement() == DS;
+  return false;
+}
+
+//===----------------------------------------------------------------------===//
+// Function Body / Expression rewriting
+//===----------------------------------------------------------------------===//
+
+Stmt *RewriteObjC::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) {
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S))
+    Stmts.push_back(S);
+  else if (isa<ObjCForCollectionStmt>(S)) {
+    Stmts.push_back(S);
+    ObjCBcLabelNo.push_back(++BcLabelCount);
+  }
+
+  // Pseudo-object operations and ivar references need special
+  // treatment because we're going to recursively rewrite them.
+  if (PseudoObjectExpr *PseudoOp = dyn_cast<PseudoObjectExpr>(S)) {
+    if (isa<BinaryOperator>(PseudoOp->getSyntacticForm())) {
+      return RewritePropertyOrImplicitSetter(PseudoOp);
+    } else {
+      return RewritePropertyOrImplicitGetter(PseudoOp);
+    }
+  } else if (ObjCIvarRefExpr *IvarRefExpr = dyn_cast<ObjCIvarRefExpr>(S)) {
+    return RewriteObjCIvarRefExpr(IvarRefExpr);
+  }
+
+  SourceRange OrigStmtRange = S->getSourceRange();
+
+  // Perform a bottom up rewrite of all children.
+  for (Stmt::child_range CI = S->children(); CI; ++CI)
+    if (*CI) {
+      Stmt *childStmt = (*CI);
+      Stmt *newStmt = RewriteFunctionBodyOrGlobalInitializer(childStmt);
+      if (newStmt) {
+        *CI = newStmt;
+      }
+    }
+
+  if (BlockExpr *BE = dyn_cast<BlockExpr>(S)) {
+    SmallVector<DeclRefExpr *, 8> InnerBlockDeclRefs;
+    llvm::SmallPtrSet<const DeclContext *, 8> InnerContexts;
+    InnerContexts.insert(BE->getBlockDecl());
+    ImportedLocalExternalDecls.clear();
+    GetInnerBlockDeclRefExprs(BE->getBody(),
+                              InnerBlockDeclRefs, InnerContexts);
+    // Rewrite the block body in place.
+    Stmt *SaveCurrentBody = CurrentBody;
+    CurrentBody = BE->getBody();
+    PropParentMap = nullptr;
+    // block literal on rhs of a property-dot-sytax assignment
+    // must be replaced by its synthesize ast so getRewrittenText
+    // works as expected. In this case, what actually ends up on RHS
+    // is the blockTranscribed which is the helper function for the
+    // block literal; as in: self.c = ^() {[ace ARR];};
+    bool saveDisableReplaceStmt = DisableReplaceStmt;
+    DisableReplaceStmt = false;
+    RewriteFunctionBodyOrGlobalInitializer(BE->getBody());
+    DisableReplaceStmt = saveDisableReplaceStmt;
+    CurrentBody = SaveCurrentBody;
+    PropParentMap = nullptr;
+    ImportedLocalExternalDecls.clear();
+    // Now we snarf the rewritten text and stash it away for later use.
+    std::string Str = Rewrite.getRewrittenText(BE->getSourceRange());
+    RewrittenBlockExprs[BE] = Str;
+
+    Stmt *blockTranscribed = SynthBlockInitExpr(BE, InnerBlockDeclRefs);
+                            
+    //blockTranscribed->dump();
+    ReplaceStmt(S, blockTranscribed);
+    return blockTranscribed;
+  }
+  // Handle specific things.
+  if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
+    return RewriteAtEncode(AtEncode);
+
+  if (ObjCSelectorExpr *AtSelector = dyn_cast<ObjCSelectorExpr>(S))
+    return RewriteAtSelector(AtSelector);
+
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
+
+  if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
+#if 0
+    // Before we rewrite it, put the original message expression in a comment.
+    SourceLocation startLoc = MessExpr->getLocStart();
+    SourceLocation endLoc = MessExpr->getLocEnd();
+
+    const char *startBuf = SM->getCharacterData(startLoc);
+    const char *endBuf = SM->getCharacterData(endLoc);
+
+    std::string messString;
+    messString += "// ";
+    messString.append(startBuf, endBuf-startBuf+1);
+    messString += "\n";
+
+    // FIXME: Missing definition of
+    // InsertText(clang::SourceLocation, char const*, unsigned int).
+    // InsertText(startLoc, messString.c_str(), messString.size());
+    // Tried this, but it didn't work either...
+    // ReplaceText(startLoc, 0, messString.c_str(), messString.size());
+#endif
+    return RewriteMessageExpr(MessExpr);
+  }
+
+  if (ObjCAtTryStmt *StmtTry = dyn_cast<ObjCAtTryStmt>(S))
+    return RewriteObjCTryStmt(StmtTry);
+
+  if (ObjCAtSynchronizedStmt *StmtTry = dyn_cast<ObjCAtSynchronizedStmt>(S))
+    return RewriteObjCSynchronizedStmt(StmtTry);
+
+  if (ObjCAtThrowStmt *StmtThrow = dyn_cast<ObjCAtThrowStmt>(S))
+    return RewriteObjCThrowStmt(StmtThrow);
+
+  if (ObjCProtocolExpr *ProtocolExp = dyn_cast<ObjCProtocolExpr>(S))
+    return RewriteObjCProtocolExpr(ProtocolExp);
+
+  if (ObjCForCollectionStmt *StmtForCollection =
+        dyn_cast<ObjCForCollectionStmt>(S))
+    return RewriteObjCForCollectionStmt(StmtForCollection,
+                                        OrigStmtRange.getEnd());
+  if (BreakStmt *StmtBreakStmt =
+      dyn_cast<BreakStmt>(S))
+    return RewriteBreakStmt(StmtBreakStmt);
+  if (ContinueStmt *StmtContinueStmt =
+      dyn_cast<ContinueStmt>(S))
+    return RewriteContinueStmt(StmtContinueStmt);
+
+  // Need to check for protocol refs (id <P>, Foo <P> *) in variable decls
+  // and cast exprs.
+  if (DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+    // FIXME: What we're doing here is modifying the type-specifier that
+    // precedes the first Decl.  In the future the DeclGroup should have
+    // a separate type-specifier that we can rewrite.
+    // NOTE: We need to avoid rewriting the DeclStmt if it is within
+    // the context of an ObjCForCollectionStmt. For example:
+    //   NSArray *someArray;
+    //   for (id <FooProtocol> index in someArray) ;
+    // This is because RewriteObjCForCollectionStmt() does textual rewriting 
+    // and it depends on the original text locations/positions.
+    if (Stmts.empty() || !IsDeclStmtInForeachHeader(DS))
+      RewriteObjCQualifiedInterfaceTypes(*DS->decl_begin());
+
+    // Blocks rewrite rules.
+    for (auto *SD : DS->decls()) {
+      if (ValueDecl *ND = dyn_cast<ValueDecl>(SD)) {
+        if (isTopLevelBlockPointerType(ND->getType()))
+          RewriteBlockPointerDecl(ND);
+        else if (ND->getType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(ND->getType(), ND);
+        if (VarDecl *VD = dyn_cast<VarDecl>(SD)) {
+          if (VD->hasAttr<BlocksAttr>()) {
+            static unsigned uniqueByrefDeclCount = 0;
+            assert(!BlockByRefDeclNo.count(ND) &&
+              "RewriteFunctionBodyOrGlobalInitializer: Duplicate byref decl");
+            BlockByRefDeclNo[ND] = uniqueByrefDeclCount++;
+            RewriteByRefVar(VD);
+          }
+          else           
+            RewriteTypeOfDecl(VD);
+        }
+      }
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+    }
+  }
+
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S))
+    RewriteObjCQualifiedInterfaceTypes(CE);
+
+  if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
+      isa<DoStmt>(S) || isa<ForStmt>(S)) {
+    assert(!Stmts.empty() && "Statement stack is empty");
+    assert ((isa<SwitchStmt>(Stmts.back()) || isa<WhileStmt>(Stmts.back()) ||
+             isa<DoStmt>(Stmts.back()) || isa<ForStmt>(Stmts.back()))
+            && "Statement stack mismatch");
+    Stmts.pop_back();
+  }
+  // Handle blocks rewriting.
+  if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
+    ValueDecl *VD = DRE->getDecl(); 
+    if (VD->hasAttr<BlocksAttr>())
+      return RewriteBlockDeclRefExpr(DRE);
+    if (HasLocalVariableExternalStorage(VD))
+      return RewriteLocalVariableExternalStorage(DRE);
+  }
+  
+  if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
+    if (CE->getCallee()->getType()->isBlockPointerType()) {
+      Stmt *BlockCall = SynthesizeBlockCall(CE, CE->getCallee());
+      ReplaceStmt(S, BlockCall);
+      return BlockCall;
+    }
+  }
+  if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(S)) {
+    RewriteCastExpr(CE);
+  }
+#if 0
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(S)) {
+    CastExpr *Replacement = new (Context) CastExpr(ICE->getType(),
+                                                   ICE->getSubExpr(),
+                                                   SourceLocation());
+    // Get the new text.
+    std::string SStr;
+    llvm::raw_string_ostream Buf(SStr);
+    Replacement->printPretty(Buf);
+    const std::string &Str = Buf.str();
+
+    printf("CAST = %s\n", &Str[0]);
+    InsertText(ICE->getSubExpr()->getLocStart(), &Str[0], Str.size());
+    delete S;
+    return Replacement;
+  }
+#endif
+  // Return this stmt unmodified.
+  return S;
+}
+
+void RewriteObjC::RewriteRecordBody(RecordDecl *RD) {
+  for (auto *FD : RD->fields()) {
+    if (isTopLevelBlockPointerType(FD->getType()))
+      RewriteBlockPointerDecl(FD);
+    if (FD->getType()->isObjCQualifiedIdType() ||
+        FD->getType()->isObjCQualifiedInterfaceType())
+      RewriteObjCQualifiedInterfaceTypes(FD);
+  }
+}
+
+/// HandleDeclInMainFile - This is called for each top-level decl defined in the
+/// main file of the input.
+void RewriteObjC::HandleDeclInMainFile(Decl *D) {
+  switch (D->getKind()) {
+    case Decl::Function: {
+      FunctionDecl *FD = cast<FunctionDecl>(D);
+      if (FD->isOverloadedOperator())
+        return;
+
+      // Since function prototypes don't have ParmDecl's, we check the function
+      // prototype. This enables us to rewrite function declarations and
+      // definitions using the same code.
+      RewriteBlocksInFunctionProtoType(FD->getType(), FD);
+
+      if (!FD->isThisDeclarationADefinition())
+        break;
+
+      // FIXME: If this should support Obj-C++, support CXXTryStmt
+      if (CompoundStmt *Body = dyn_cast_or_null<CompoundStmt>(FD->getBody())) {
+        CurFunctionDef = FD;
+        CurFunctionDeclToDeclareForBlock = FD;
+        CurrentBody = Body;
+        Body =
+        cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        FD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        // This synthesizes and inserts the block "impl" struct, invoke function,
+        // and any copy/dispose helper functions.
+        InsertBlockLiteralsWithinFunction(FD);
+        CurFunctionDef = nullptr;
+        CurFunctionDeclToDeclareForBlock = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
+      if (CompoundStmt *Body = MD->getCompoundBody()) {
+        CurMethodDef = MD;
+        CurrentBody = Body;
+        Body =
+          cast_or_null<CompoundStmt>(RewriteFunctionBodyOrGlobalInitializer(Body));
+        MD->setBody(Body);
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        InsertBlockLiteralsWithinMethod(MD);
+        CurMethodDef = nullptr;
+      }
+      break;
+    }
+    case Decl::ObjCImplementation: {
+      ObjCImplementationDecl *CI = cast<ObjCImplementationDecl>(D);
+      ClassImplementation.push_back(CI);
+      break;
+    }
+    case Decl::ObjCCategoryImpl: {
+      ObjCCategoryImplDecl *CI = cast<ObjCCategoryImplDecl>(D);
+      CategoryImplementation.push_back(CI);
+      break;
+    }
+    case Decl::Var: {
+      VarDecl *VD = cast<VarDecl>(D);
+      RewriteObjCQualifiedInterfaceTypes(VD);
+      if (isTopLevelBlockPointerType(VD->getType()))
+        RewriteBlockPointerDecl(VD);
+      else if (VD->getType()->isFunctionPointerType()) {
+        CheckFunctionPointerDecl(VD->getType(), VD);
+        if (VD->getInit()) {
+          if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+          }
+        }
+      } else if (VD->getType()->isRecordType()) {
+        RecordDecl *RD = VD->getType()->getAs<RecordType>()->getDecl();
+        if (RD->isCompleteDefinition())
+          RewriteRecordBody(RD);
+      }
+      if (VD->getInit()) {
+        GlobalVarDecl = VD;
+        CurrentBody = VD->getInit();
+        RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
+        CurrentBody = nullptr;
+        if (PropParentMap) {
+          delete PropParentMap;
+          PropParentMap = nullptr;
+        }
+        SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
+        GlobalVarDecl = nullptr;
+
+        // This is needed for blocks.
+        if (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(VD->getInit())) {
+            RewriteCastExpr(CE);
+        }
+      }
+      break;
+    }
+    case Decl::TypeAlias:
+    case Decl::Typedef: {
+      if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+        if (isTopLevelBlockPointerType(TD->getUnderlyingType()))
+          RewriteBlockPointerDecl(TD);
+        else if (TD->getUnderlyingType()->isFunctionPointerType())
+          CheckFunctionPointerDecl(TD->getUnderlyingType(), TD);
+      }
+      break;
+    }
+    case Decl::CXXRecord:
+    case Decl::Record: {
+      RecordDecl *RD = cast<RecordDecl>(D);
+      if (RD->isCompleteDefinition()) 
+        RewriteRecordBody(RD);
+      break;
+    }
+    default:
+      break;
+  }
+  // Nothing yet.
+}
+
+void RewriteObjC::HandleTranslationUnit(ASTContext &C) {
+  if (Diags.hasErrorOccurred())
+    return;
+
+  RewriteInclude();
+
+  // Here's a great place to add any extra declarations that may be needed.
+  // Write out meta data for each @protocol(<expr>).
+  for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls)
+    RewriteObjCProtocolMetaData(ProtDecl, "", "", Preamble);
+
+  InsertText(SM->getLocForStartOfFile(MainFileID), Preamble, false);
+  if (ClassImplementation.size() || CategoryImplementation.size())
+    RewriteImplementations();
+
+  // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
+  // we are done.
+  if (const RewriteBuffer *RewriteBuf =
+      Rewrite.getRewriteBufferFor(MainFileID)) {
+    //printf("Changed:\n");
+    *OutFile << std::string(RewriteBuf->begin(), RewriteBuf->end());
+  } else {
+    llvm::errs() << "No changes\n";
+  }
+
+  if (ClassImplementation.size() || CategoryImplementation.size() ||
+      ProtocolExprDecls.size()) {
+    // Rewrite Objective-c meta data*
+    std::string ResultStr;
+    RewriteMetaDataIntoBuffer(ResultStr);
+    // Emit metadata.
+    *OutFile << ResultStr;
+  }
+  OutFile->flush();
+}
+
+void RewriteObjCFragileABI::Initialize(ASTContext &context) {
+  InitializeCommon(context);
+  
+  // declaring objc_selector outside the parameter list removes a silly
+  // scope related warning...
+  if (IsHeader)
+    Preamble = "#pragma once\n";
+  Preamble += "struct objc_selector; struct objc_class;\n";
+  Preamble += "struct __rw_objc_super { struct objc_object *object; ";
+  Preamble += "struct objc_object *superClass; ";
+  if (LangOpts.MicrosoftExt) {
+    // Add a constructor for creating temporary objects.
+    Preamble += "__rw_objc_super(struct objc_object *o, struct objc_object *s) "
+    ": ";
+    Preamble += "object(o), superClass(s) {} ";
+  }
+  Preamble += "};\n";
+  Preamble += "#ifndef _REWRITER_typedef_Protocol\n";
+  Preamble += "typedef struct objc_object Protocol;\n";
+  Preamble += "#define _REWRITER_typedef_Protocol\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern \"C\" __declspec(dllimport)\n";
+    Preamble += "#define __OBJC_RW_STATICIMPORT extern \"C\"\n";
+  } else
+    Preamble += "#define __OBJC_RW_DLLIMPORT extern\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSend";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_msgSendSuper";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSend_stret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object* objc_msgSendSuper_stret";
+  Preamble += "(struct objc_super *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT double objc_msgSend_fpret";
+  Preamble += "(struct objc_object *, struct objc_selector *, ...);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_class *class_getSuperclass";
+  Preamble += "(struct objc_class *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_getMetaClass";
+  Preamble += "(const char *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_throw(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_enter(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_exception_try_exit(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT struct objc_object *objc_exception_extract(void *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_exception_match";
+  Preamble += "(struct objc_class *, struct objc_object *);\n";
+  // @synchronized hooks.
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_enter(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int objc_sync_exit(struct objc_object *);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT Protocol *objc_getProtocol(const char *);\n";
+  Preamble += "#ifndef __FASTENUMERATIONSTATE\n";
+  Preamble += "struct __objcFastEnumerationState {\n\t";
+  Preamble += "unsigned long state;\n\t";
+  Preamble += "void **itemsPtr;\n\t";
+  Preamble += "unsigned long *mutationsPtr;\n\t";
+  Preamble += "unsigned long extra[5];\n};\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void objc_enumerationMutation(struct objc_object *);\n";
+  Preamble += "#define __FASTENUMERATIONSTATE\n";
+  Preamble += "#endif\n";
+  Preamble += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "struct __NSConstantStringImpl {\n";
+  Preamble += "  int *isa;\n";
+  Preamble += "  int flags;\n";
+  Preamble += "  char *str;\n";
+  Preamble += "  long length;\n";
+  Preamble += "};\n";
+  Preamble += "#ifdef CF_EXPORT_CONSTANT_STRING\n";
+  Preamble += "extern \"C\" __declspec(dllexport) int __CFConstantStringClassReference[];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT int __CFConstantStringClassReference[];\n";
+  Preamble += "#endif\n";
+  Preamble += "#define __NSCONSTANTSTRINGIMPL\n";
+  Preamble += "#endif\n";
+  // Blocks preamble.
+  Preamble += "#ifndef BLOCK_IMPL\n";
+  Preamble += "#define BLOCK_IMPL\n";
+  Preamble += "struct __block_impl {\n";
+  Preamble += "  void *isa;\n";
+  Preamble += "  int Flags;\n";
+  Preamble += "  int Reserved;\n";
+  Preamble += "  void *FuncPtr;\n";
+  Preamble += "};\n";
+  Preamble += "// Runtime copy/destroy helper functions (from Block_private.h)\n";
+  Preamble += "#ifdef __OBJC_EXPORT_BLOCKS\n";
+  Preamble += "extern \"C\" __declspec(dllexport) "
+  "void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "extern \"C\" __declspec(dllexport) void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#else\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_assign(void *, const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void _Block_object_dispose(const void *, const int);\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteGlobalBlock[32];\n";
+  Preamble += "__OBJC_RW_DLLIMPORT void *_NSConcreteStackBlock[32];\n";
+  Preamble += "#endif\n";
+  Preamble += "#endif\n";
+  if (LangOpts.MicrosoftExt) {
+    Preamble += "#undef __OBJC_RW_DLLIMPORT\n";
+    Preamble += "#undef __OBJC_RW_STATICIMPORT\n";
+    Preamble += "#ifndef KEEP_ATTRIBUTES\n";  // We use this for clang tests.
+    Preamble += "#define __attribute__(X)\n";
+    Preamble += "#endif\n";
+    Preamble += "#define __weak\n";
+  }
+  else {
+    Preamble += "#define __block\n";
+    Preamble += "#define __weak\n";
+  }
+  // NOTE! Windows uses LLP64 for 64bit mode. So, cast pointer to long long
+  // as this avoids warning in any 64bit/32bit compilation model.
+  Preamble += "\n#define __OFFSETOFIVAR__(TYPE, MEMBER) ((long long) &((TYPE *)0)->MEMBER)\n";
+}
+
+/// RewriteIvarOffsetComputation - This rutine synthesizes computation of
+/// ivar offset.
+void RewriteObjCFragileABI::RewriteIvarOffsetComputation(ObjCIvarDecl *ivar,
+                                                         std::string &Result) {
+  if (ivar->isBitField()) {
+    // FIXME: The hack below doesn't work for bitfields. For now, we simply
+    // place all bitfields at offset 0.
+    Result += "0";
+  } else {
+    Result += "__OFFSETOFIVAR__(struct ";
+    Result += ivar->getContainingInterface()->getNameAsString();
+    if (LangOpts.MicrosoftExt)
+      Result += "_IMPL";
+    Result += ", ";
+    Result += ivar->getNameAsString();
+    Result += ")";
+  }
+}
+
+/// RewriteObjCProtocolMetaData - Rewrite protocols meta-data.
+void RewriteObjCFragileABI::RewriteObjCProtocolMetaData(
+                            ObjCProtocolDecl *PDecl, StringRef prefix,
+                            StringRef ClassName, std::string &Result) {
+  static bool objc_protocol_methods = false;
+  
+  // Output struct protocol_methods holder of method selector and type.
+  if (!objc_protocol_methods && PDecl->hasDefinition()) {
+    /* struct protocol_methods {
+     SEL _cmd;
+     char *method_types;
+     }
+     */
+    Result += "\nstruct _protocol_methods {\n";
+    Result += "\tstruct objc_selector *_cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "};\n";
+    
+    objc_protocol_methods = true;
+  }
+  // Do not synthesize the protocol more than once.
+  if (ObjCSynthesizedProtocols.count(PDecl->getCanonicalDecl()))
+    return;
+  
+  if (ObjCProtocolDecl *Def = PDecl->getDefinition())
+    PDecl = Def;
+  
+  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+    unsigned NumMethods = std::distance(PDecl->instmeth_begin(),
+                                        PDecl->instmeth_end());
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_inst_meth\")))= "
+    "{\n\t" + utostr(NumMethods) + "\n";
+    
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::instmeth_iterator
+         I = PDecl->instmeth_begin(), E = PDecl->instmeth_end();
+         I != E; ++I) {
+      if (I == PDecl->instmeth_begin())
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+  
+  // Output class methods declared in this protocol.
+  unsigned NumMethods = std::distance(PDecl->classmeth_begin(),
+                                      PDecl->classmeth_end());
+  if (NumMethods > 0) {
+    /* struct _objc_protocol_method_list {
+     int protocol_method_count;
+     struct protocol_methods protocols[];
+     }
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint protocol_method_count;\n";
+    Result += "\tstruct _protocol_methods protocol_methods[";
+    Result += utostr(NumMethods);
+    Result += "];\n} _OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+    "{\n\t";
+    Result += utostr(NumMethods);
+    Result += "\n";
+    
+    // Output instance methods declared in this protocol.
+    for (ObjCProtocolDecl::classmeth_iterator
+         I = PDecl->classmeth_begin(), E = PDecl->classmeth_end();
+         I != E; ++I) {
+      if (I == PDecl->classmeth_begin())
+        Result += "\t  ,{{(struct objc_selector *)\"";
+      else
+        Result += "\t  ,{(struct objc_selector *)\"";
+      Result += (*I)->getSelector().getAsString();
+      std::string MethodTypeString;
+      Context->getObjCEncodingForMethodDecl((*I), MethodTypeString);
+      Result += "\", \"";
+      Result += MethodTypeString;
+      Result += "\"}\n";
+    }
+    Result += "\t }\n};\n";
+  }
+  
+  // Output:
+  /* struct _objc_protocol {
+   // Objective-C 1.0 extensions
+   struct _objc_protocol_extension *isa;
+   char *protocol_name;
+   struct _objc_protocol **protocol_list;
+   struct _objc_protocol_method_list *instance_methods;
+   struct _objc_protocol_method_list *class_methods;
+   };
+   */
+  static bool objc_protocol = false;
+  if (!objc_protocol) {
+    Result += "\nstruct _objc_protocol {\n";
+    Result += "\tstruct _objc_protocol_extension *isa;\n";
+    Result += "\tchar *protocol_name;\n";
+    Result += "\tstruct _objc_protocol **protocol_list;\n";
+    Result += "\tstruct _objc_protocol_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_protocol_method_list *class_methods;\n";
+    Result += "};\n";
+    
+    objc_protocol = true;
+  }
+  
+  Result += "\nstatic struct _objc_protocol _OBJC_PROTOCOL_";
+  Result += PDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __protocol\")))= "
+  "{\n\t0, \"";
+  Result += PDecl->getNameAsString();
+  Result += "\", 0, ";
+  if (PDecl->instmeth_begin() != PDecl->instmeth_end()) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_INSTANCE_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += ", ";
+  }
+  else
+    Result += "0, ";
+  if (PDecl->classmeth_begin() != PDecl->classmeth_end()) {
+    Result += "(struct _objc_protocol_method_list *)&_OBJC_PROTOCOL_CLASS_METHODS_";
+    Result += PDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += "0\n";
+  Result += "};\n";
+  
+  // Mark this protocol as having been generated.
+  if (!ObjCSynthesizedProtocols.insert(PDecl->getCanonicalDecl()).second)
+    llvm_unreachable("protocol already synthesized");
+  
+}
+
+void RewriteObjCFragileABI::RewriteObjCProtocolListMetaData(
+                                const ObjCList<ObjCProtocolDecl> &Protocols,
+                                StringRef prefix, StringRef ClassName,
+                                std::string &Result) {
+  if (Protocols.empty()) return;
+  
+  for (unsigned i = 0; i != Protocols.size(); i++)
+    RewriteObjCProtocolMetaData(Protocols[i], prefix, ClassName, Result);
+  
+  // Output the top lovel protocol meta-data for the class.
+  /* struct _objc_protocol_list {
+   struct _objc_protocol_list *next;
+   int    protocol_count;
+   struct _objc_protocol *class_protocols[];
+   }
+   */
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_protocol_list *next;\n";
+  Result += "\tint    protocol_count;\n";
+  Result += "\tstruct _objc_protocol *class_protocols[";
+  Result += utostr(Protocols.size());
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += "_PROTOCOLS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __cat_cls_meth\")))= "
+  "{\n\t0, ";
+  Result += utostr(Protocols.size());
+  Result += "\n";
+  
+  Result += "\t,{&_OBJC_PROTOCOL_";
+  Result += Protocols[0]->getNameAsString();
+  Result += " \n";
+  
+  for (unsigned i = 1; i != Protocols.size(); i++) {
+    Result += "\t ,&_OBJC_PROTOCOL_";
+    Result += Protocols[i]->getNameAsString();
+    Result += "\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+void RewriteObjCFragileABI::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
+                                           std::string &Result) {
+  ObjCInterfaceDecl *CDecl = IDecl->getClassInterface();
+  
+  // Explicitly declared @interface's are already synthesized.
+  if (CDecl->isImplicitInterfaceDecl()) {
+    // FIXME: Implementation of a class with no @interface (legacy) does not
+    // produce correct synthesis as yet.
+    RewriteObjCInternalStruct(CDecl, Result);
+  }
+  
+  // Build _objc_ivar_list metadata for classes ivars if needed
+  unsigned NumIvars = !IDecl->ivar_empty()
+  ? IDecl->ivar_size()
+  : (CDecl ? CDecl->ivar_size() : 0);
+  if (NumIvars > 0) {
+    static bool objc_ivar = false;
+    if (!objc_ivar) {
+      /* struct _objc_ivar {
+       char *ivar_name;
+       char *ivar_type;
+       int ivar_offset;
+       };
+       */
+      Result += "\nstruct _objc_ivar {\n";
+      Result += "\tchar *ivar_name;\n";
+      Result += "\tchar *ivar_type;\n";
+      Result += "\tint ivar_offset;\n";
+      Result += "};\n";
+      
+      objc_ivar = true;
+    }
+    
+    /* struct {
+     int ivar_count;
+     struct _objc_ivar ivar_list[nIvars];
+     };
+     */
+    Result += "\nstatic struct {\n";
+    Result += "\tint ivar_count;\n";
+    Result += "\tstruct _objc_ivar ivar_list[";
+    Result += utostr(NumIvars);
+    Result += "];\n} _OBJC_INSTANCE_VARIABLES_";
+    Result += IDecl->getNameAsString();
+    Result += " __attribute__ ((used, section (\"__OBJC, __instance_vars\")))= "
+    "{\n\t";
+    Result += utostr(NumIvars);
+    Result += "\n";
+    
+    ObjCInterfaceDecl::ivar_iterator IVI, IVE;
+    SmallVector<ObjCIvarDecl *, 8> IVars;
+    if (!IDecl->ivar_empty()) {
+      for (auto *IV : IDecl->ivars())
+        IVars.push_back(IV);
+      IVI = IDecl->ivar_begin();
+      IVE = IDecl->ivar_end();
+    } else {
+      IVI = CDecl->ivar_begin();
+      IVE = CDecl->ivar_end();
+    }
+    Result += "\t,{{\"";
+    Result += IVI->getNameAsString();
+    Result += "\", \"";
+    std::string TmpString, StrEncoding;
+    Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI);
+    QuoteDoublequotes(TmpString, StrEncoding);
+    Result += StrEncoding;
+    Result += "\", ";
+    RewriteIvarOffsetComputation(*IVI, Result);
+    Result += "}\n";
+    for (++IVI; IVI != IVE; ++IVI) {
+      Result += "\t  ,{\"";
+      Result += IVI->getNameAsString();
+      Result += "\", \"";
+      std::string TmpString, StrEncoding;
+      Context->getObjCEncodingForType(IVI->getType(), TmpString, *IVI);
+      QuoteDoublequotes(TmpString, StrEncoding);
+      Result += StrEncoding;
+      Result += "\", ";
+      RewriteIvarOffsetComputation(*IVI, Result);
+      Result += "}\n";
+    }
+    
+    Result += "\t }\n};\n";
+  }
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      if (!Getter->isDefined())
+        InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      if (!Setter->isDefined())
+        InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "", IDecl->getName(), Result);
+  
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "", IDecl->getName(), Result);
+  
+  // Protocols referenced in class declaration?
+  RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(),
+                                  "CLASS", CDecl->getName(), Result);
+  
+  // Declaration of class/meta-class metadata
+  /* struct _objc_class {
+   struct _objc_class *isa; // or const char *root_class_name when metadata
+   const char *super_class_name;
+   char *name;
+   long version;
+   long info;
+   long instance_size;
+   struct _objc_ivar_list *ivars;
+   struct _objc_method_list *methods;
+   struct objc_cache *cache;
+   struct objc_protocol_list *protocols;
+   const char *ivar_layout;
+   struct _objc_class_ext  *ext;
+   };
+   */
+  static bool objc_class = false;
+  if (!objc_class) {
+    Result += "\nstruct _objc_class {\n";
+    Result += "\tstruct _objc_class *isa;\n";
+    Result += "\tconst char *super_class_name;\n";
+    Result += "\tchar *name;\n";
+    Result += "\tlong version;\n";
+    Result += "\tlong info;\n";
+    Result += "\tlong instance_size;\n";
+    Result += "\tstruct _objc_ivar_list *ivars;\n";
+    Result += "\tstruct _objc_method_list *methods;\n";
+    Result += "\tstruct objc_cache *cache;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tconst char *ivar_layout;\n";
+    Result += "\tstruct _objc_class_ext  *ext;\n";
+    Result += "};\n";
+    objc_class = true;
+  }
+  
+  // Meta-class metadata generation.
+  ObjCInterfaceDecl *RootClass = nullptr;
+  ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
+  while (SuperClass) {
+    RootClass = SuperClass;
+    SuperClass = SuperClass->getSuperClass();
+  }
+  SuperClass = CDecl->getSuperClass();
+  
+  Result += "\nstatic struct _objc_class _OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __meta_class\")))= "
+  "{\n\t(struct _objc_class *)\"";
+  Result += (RootClass ? RootClass->getNameAsString() : CDecl->getNameAsString());
+  Result += "\"";
+  
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // Set 'ivars' field for root class to 0. ObjC1 runtime does not use it.
+  // 'info' field is initialized to CLS_META(2) for metaclass
+  Result += ", 0,2, sizeof(struct _objc_class), 0";
+  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+    Result += "\n\t, (struct _objc_method_list *)&_OBJC_CLASS_METHODS_";
+    Result += IDecl->getNameAsString();
+    Result += "\n";
+  }
+  else
+    Result += ", 0\n";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t,0, (struct _objc_protocol_list *)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ",0,0\n";
+  }
+  else
+    Result += "\t,0,0,0,0\n";
+  Result += "};\n";
+  
+  // class metadata generation.
+  Result += "\nstatic struct _objc_class _OBJC_CLASS_";
+  Result += CDecl->getNameAsString();
+  Result += " __attribute__ ((used, section (\"__OBJC, __class\")))= "
+  "{\n\t&_OBJC_METACLASS_";
+  Result += CDecl->getNameAsString();
+  if (SuperClass) {
+    Result += ", \"";
+    Result += SuperClass->getNameAsString();
+    Result += "\", \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  else {
+    Result += ", 0, \"";
+    Result += CDecl->getNameAsString();
+    Result += "\"";
+  }
+  // 'info' field is initialized to CLS_CLASS(1) for class
+  Result += ", 0,1";
+  if (!ObjCSynthesizedStructs.count(CDecl))
+    Result += ",0";
+  else {
+    // class has size. Must synthesize its size.
+    Result += ",sizeof(struct ";
+    Result += CDecl->getNameAsString();
+    if (LangOpts.MicrosoftExt)
+      Result += "_IMPL";
+    Result += ")";
+  }
+  if (NumIvars > 0) {
+    Result += ", (struct _objc_ivar_list *)&_OBJC_INSTANCE_VARIABLES_";
+    Result += CDecl->getNameAsString();
+    Result += "\n\t";
+  }
+  else
+    Result += ",0";
+  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+    Result += ", (struct _objc_method_list *)&_OBJC_INSTANCE_METHODS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0\n\t";
+  }
+  else
+    Result += ",0,0";
+  if (CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += ", (struct _objc_protocol_list*)&_OBJC_CLASS_PROTOCOLS_";
+    Result += CDecl->getNameAsString();
+    Result += ", 0,0\n";
+  }
+  else
+    Result += ",0,0,0\n";
+  Result += "};\n";
+}
+
+void RewriteObjCFragileABI::RewriteMetaDataIntoBuffer(std::string &Result) {
+  int ClsDefCount = ClassImplementation.size();
+  int CatDefCount = CategoryImplementation.size();
+  
+  // For each implemented class, write out all its meta data.
+  for (int i = 0; i < ClsDefCount; i++)
+    RewriteObjCClassMetaData(ClassImplementation[i], Result);
+  
+  // For each implemented category, write out all its meta data.
+  for (int i = 0; i < CatDefCount; i++)
+    RewriteObjCCategoryImplDecl(CategoryImplementation[i], Result);
+  
+  // Write objc_symtab metadata
+  /*
+   struct _objc_symtab
+   {
+   long sel_ref_cnt;
+   SEL *refs;
+   short cls_def_cnt;
+   short cat_def_cnt;
+   void *defs[cls_def_cnt + cat_def_cnt];
+   };
+   */
+  
+  Result += "\nstruct _objc_symtab {\n";
+  Result += "\tlong sel_ref_cnt;\n";
+  Result += "\tSEL *refs;\n";
+  Result += "\tshort cls_def_cnt;\n";
+  Result += "\tshort cat_def_cnt;\n";
+  Result += "\tvoid *defs[" + utostr(ClsDefCount + CatDefCount)+ "];\n";
+  Result += "};\n\n";
+  
+  Result += "static struct _objc_symtab "
+  "_OBJC_SYMBOLS __attribute__((used, section (\"__OBJC, __symbols\")))= {\n";
+  Result += "\t0, 0, " + utostr(ClsDefCount)
+  + ", " + utostr(CatDefCount) + "\n";
+  for (int i = 0; i < ClsDefCount; i++) {
+    Result += "\t,&_OBJC_CLASS_";
+    Result += ClassImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+  
+  for (int i = 0; i < CatDefCount; i++) {
+    Result += "\t,&_OBJC_CATEGORY_";
+    Result += CategoryImplementation[i]->getClassInterface()->getNameAsString();
+    Result += "_";
+    Result += CategoryImplementation[i]->getNameAsString();
+    Result += "\n";
+  }
+  
+  Result += "};\n\n";
+  
+  // Write objc_module metadata
+  
+  /*
+   struct _objc_module {
+   long version;
+   long size;
+   const char *name;
+   struct _objc_symtab *symtab;
+   }
+   */
+  
+  Result += "\nstruct _objc_module {\n";
+  Result += "\tlong version;\n";
+  Result += "\tlong size;\n";
+  Result += "\tconst char *name;\n";
+  Result += "\tstruct _objc_symtab *symtab;\n";
+  Result += "};\n\n";
+  Result += "static struct _objc_module "
+  "_OBJC_MODULES __attribute__ ((used, section (\"__OBJC, __module_info\")))= {\n";
+  Result += "\t" + utostr(OBJC_ABI_VERSION) +
+  ", sizeof(struct _objc_module), \"\", &_OBJC_SYMBOLS\n";
+  Result += "};\n\n";
+  
+  if (LangOpts.MicrosoftExt) {
+    if (ProtocolExprDecls.size()) {
+      Result += "#pragma section(\".objc_protocol$B\",long,read,write)\n";
+      Result += "#pragma data_seg(push, \".objc_protocol$B\")\n";
+      for (ObjCProtocolDecl *ProtDecl : ProtocolExprDecls) {
+        Result += "static struct _objc_protocol *_POINTER_OBJC_PROTOCOL_";
+        Result += ProtDecl->getNameAsString();
+        Result += " = &_OBJC_PROTOCOL_";
+        Result += ProtDecl->getNameAsString();
+        Result += ";\n";
+      }
+      Result += "#pragma data_seg(pop)\n\n";
+    }
+    Result += "#pragma section(\".objc_module_info$B\",long,read,write)\n";
+    Result += "#pragma data_seg(push, \".objc_module_info$B\")\n";
+    Result += "static struct _objc_module *_POINTER_OBJC_MODULES = ";
+    Result += "&_OBJC_MODULES;\n";
+    Result += "#pragma data_seg(pop)\n\n";
+  }
+}
+
+/// RewriteObjCCategoryImplDecl - Rewrite metadata for each category
+/// implementation.
+void RewriteObjCFragileABI::RewriteObjCCategoryImplDecl(ObjCCategoryImplDecl *IDecl,
+                                              std::string &Result) {
+  ObjCInterfaceDecl *ClassDecl = IDecl->getClassInterface();
+  // Find category declaration for this implementation.
+  ObjCCategoryDecl *CDecl
+    = ClassDecl->FindCategoryDeclaration(IDecl->getIdentifier());
+  
+  std::string FullCategoryName = ClassDecl->getNameAsString();
+  FullCategoryName += '_';
+  FullCategoryName += IDecl->getNameAsString();
+  
+  // Build _objc_method_list for class's instance methods if needed
+  SmallVector<ObjCMethodDecl *, 32> InstanceMethods(IDecl->instance_methods());
+  
+  // If any of our property implementations have associated getters or
+  // setters, produce metadata for them as well.
+  for (const auto *Prop : IDecl->property_impls()) {
+    if (Prop->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+      continue;
+    if (!Prop->getPropertyIvarDecl())
+      continue;
+    ObjCPropertyDecl *PD = Prop->getPropertyDecl();
+    if (!PD)
+      continue;
+    if (ObjCMethodDecl *Getter = PD->getGetterMethodDecl())
+      InstanceMethods.push_back(Getter);
+    if (PD->isReadOnly())
+      continue;
+    if (ObjCMethodDecl *Setter = PD->getSetterMethodDecl())
+      InstanceMethods.push_back(Setter);
+  }
+  RewriteObjCMethodsMetaData(InstanceMethods.begin(), InstanceMethods.end(),
+                             true, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+  
+  // Build _objc_method_list for class's class methods if needed
+  RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
+                             false, "CATEGORY_", FullCategoryName.c_str(),
+                             Result);
+  
+  // Protocols referenced in class declaration?
+  // Null CDecl is case of a category implementation with no category interface
+  if (CDecl)
+    RewriteObjCProtocolListMetaData(CDecl->getReferencedProtocols(), "CATEGORY",
+                                    FullCategoryName, Result);
+  /* struct _objc_category {
+   char *category_name;
+   char *class_name;
+   struct _objc_method_list *instance_methods;
+   struct _objc_method_list *class_methods;
+   struct _objc_protocol_list *protocols;
+   // Objective-C 1.0 extensions
+   uint32_t size;     // sizeof (struct _objc_category)
+   struct _objc_property_list *instance_properties;  // category's own
+   // @property decl.
+   };
+   */
+  
+  static bool objc_category = false;
+  if (!objc_category) {
+    Result += "\nstruct _objc_category {\n";
+    Result += "\tchar *category_name;\n";
+    Result += "\tchar *class_name;\n";
+    Result += "\tstruct _objc_method_list *instance_methods;\n";
+    Result += "\tstruct _objc_method_list *class_methods;\n";
+    Result += "\tstruct _objc_protocol_list *protocols;\n";
+    Result += "\tunsigned int size;\n";
+    Result += "\tstruct _objc_property_list *instance_properties;\n";
+    Result += "};\n";
+    objc_category = true;
+  }
+  Result += "\nstatic struct _objc_category _OBJC_CATEGORY_";
+  Result += FullCategoryName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __category\")))= {\n\t\"";
+  Result += IDecl->getNameAsString();
+  Result += "\"\n\t, \"";
+  Result += ClassDecl->getNameAsString();
+  Result += "\"\n";
+  
+  if (IDecl->instmeth_begin() != IDecl->instmeth_end()) {
+    Result += "\t, (struct _objc_method_list *)"
+    "&_OBJC_CATEGORY_INSTANCE_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  if (IDecl->classmeth_begin() != IDecl->classmeth_end()) {
+    Result += "\t, (struct _objc_method_list *)"
+    "&_OBJC_CATEGORY_CLASS_METHODS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  
+  if (CDecl && CDecl->protocol_begin() != CDecl->protocol_end()) {
+    Result += "\t, (struct _objc_protocol_list *)&_OBJC_CATEGORY_PROTOCOLS_";
+    Result += FullCategoryName;
+    Result += "\n";
+  }
+  else
+    Result += "\t, 0\n";
+  Result += "\t, sizeof(struct _objc_category), 0\n};\n";
+}
+
+// RewriteObjCMethodsMetaData - Rewrite methods metadata for instance or
+/// class methods.
+template<typename MethodIterator>
+void RewriteObjCFragileABI::RewriteObjCMethodsMetaData(MethodIterator MethodBegin,
+                                             MethodIterator MethodEnd,
+                                             bool IsInstanceMethod,
+                                             StringRef prefix,
+                                             StringRef ClassName,
+                                             std::string &Result) {
+  if (MethodBegin == MethodEnd) return;
+  
+  if (!objc_impl_method) {
+    /* struct _objc_method {
+     SEL _cmd;
+     char *method_types;
+     void *_imp;
+     }
+     */
+    Result += "\nstruct _objc_method {\n";
+    Result += "\tSEL _cmd;\n";
+    Result += "\tchar *method_types;\n";
+    Result += "\tvoid *_imp;\n";
+    Result += "};\n";
+    
+    objc_impl_method = true;
+  }
+  
+  // Build _objc_method_list for class's methods if needed
+  
+  /* struct  {
+   struct _objc_method_list *next_method;
+   int method_count;
+   struct _objc_method method_list[];
+   }
+   */
+  unsigned NumMethods = std::distance(MethodBegin, MethodEnd);
+  Result += "\nstatic struct {\n";
+  Result += "\tstruct _objc_method_list *next_method;\n";
+  Result += "\tint method_count;\n";
+  Result += "\tstruct _objc_method method_list[";
+  Result += utostr(NumMethods);
+  Result += "];\n} _OBJC_";
+  Result += prefix;
+  Result += IsInstanceMethod ? "INSTANCE" : "CLASS";
+  Result += "_METHODS_";
+  Result += ClassName;
+  Result += " __attribute__ ((used, section (\"__OBJC, __";
+  Result += IsInstanceMethod ? "inst" : "cls";
+  Result += "_meth\")))= ";
+  Result += "{\n\t0, " + utostr(NumMethods) + "\n";
+  
+  Result += "\t,{{(SEL)\"";
+  Result += (*MethodBegin)->getSelector().getAsString().c_str();
+  std::string MethodTypeString;
+  Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+  Result += "\", \"";
+  Result += MethodTypeString;
+  Result += "\", (void *)";
+  Result += MethodInternalNames[*MethodBegin];
+  Result += "}\n";
+  for (++MethodBegin; MethodBegin != MethodEnd; ++MethodBegin) {
+    Result += "\t  ,{(SEL)\"";
+    Result += (*MethodBegin)->getSelector().getAsString().c_str();
+    std::string MethodTypeString;
+    Context->getObjCEncodingForMethodDecl(*MethodBegin, MethodTypeString);
+    Result += "\", \"";
+    Result += MethodTypeString;
+    Result += "\", (void *)";
+    Result += MethodInternalNames[*MethodBegin];
+    Result += "}\n";
+  }
+  Result += "\t }\n};\n";
+}
+
+Stmt *RewriteObjCFragileABI::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) {
+  SourceRange OldRange = IV->getSourceRange();
+  Expr *BaseExpr = IV->getBase();
+  
+  // Rewrite the base, but without actually doing replaces.
+  {
+    DisableReplaceStmtScope S(*this);
+    BaseExpr = cast<Expr>(RewriteFunctionBodyOrGlobalInitializer(BaseExpr));
+    IV->setBase(BaseExpr);
+  }
+  
+  ObjCIvarDecl *D = IV->getDecl();
+  
+  Expr *Replacement = IV;
+  if (CurMethodDef) {
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      const ObjCInterfaceType *iFaceDecl =
+      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      assert(iFaceDecl && "RewriteObjCIvarRefExpr - iFaceDecl is null");
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = nullptr;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName);
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    CK_BitCast,
+                                                    IV->getBase());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(OldRange.getBegin(),
+                                              OldRange.getEnd(),
+                                              castExpr);
+      if (IV->isFreeIvar() &&
+          declaresSameEntity(CurMethodDef->getClassInterface(), iFaceDecl->getDecl())) {
+        MemberExpr *ME = new (Context) MemberExpr(PE, true, D,
+                                                  IV->getLocation(),
+                                                  D->getType(),
+                                                  VK_LValue, OK_Ordinary);
+        Replacement = ME;
+      } else {
+        IV->setBase(PE);
+      }
+    }
+  } else { // we are outside a method.
+    assert(!IV->isFreeIvar() && "Cannot have a free standing ivar outside a method");
+    
+    // Explicit ivar refs need to have a cast inserted.
+    // FIXME: consider sharing some of this code with the code above.
+    if (BaseExpr->getType()->isObjCObjectPointerType()) {
+      const ObjCInterfaceType *iFaceDecl =
+      dyn_cast<ObjCInterfaceType>(BaseExpr->getType()->getPointeeType());
+      // lookup which class implements the instance variable.
+      ObjCInterfaceDecl *clsDeclared = nullptr;
+      iFaceDecl->getDecl()->lookupInstanceVariable(D->getIdentifier(),
+                                                   clsDeclared);
+      assert(clsDeclared && "RewriteObjCIvarRefExpr(): Can't find class");
+      
+      // Synthesize an explicit cast to gain access to the ivar.
+      std::string RecName = clsDeclared->getIdentifier()->getName();
+      RecName += "_IMPL";
+      IdentifierInfo *II = &Context->Idents.get(RecName);
+      RecordDecl *RD = RecordDecl::Create(*Context, TTK_Struct, TUDecl,
+                                          SourceLocation(), SourceLocation(),
+                                          II);
+      assert(RD && "RewriteObjCIvarRefExpr(): Can't find RecordDecl");
+      QualType castT = Context->getPointerType(Context->getTagDeclType(RD));
+      CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, castT,
+                                                    CK_BitCast,
+                                                    IV->getBase());
+      // Don't forget the parens to enforce the proper binding.
+      ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(),
+                                              IV->getBase()->getLocEnd(), castExpr);
+      // Cannot delete IV->getBase(), since PE points to it.
+      // Replace the old base with the cast. This is important when doing
+      // embedded rewrites. For example, [newInv->_container addObject:0].
+      IV->setBase(PE);
+    }
+  }
+  
+  ReplaceStmtWithRange(IV, Replacement, OldRange);
+  return Replacement;  
+}
+
+#endif
diff --git a/lib/Frontend/Rewrite/RewriteTest.cpp b/lib/Frontend/Rewrite/RewriteTest.cpp
new file mode 100644
index 0000000..722c5e8
--- /dev/null
+++ b/lib/Frontend/Rewrite/RewriteTest.cpp
@@ -0,0 +1,39 @@
+//===--- RewriteTest.cpp - Rewriter playground ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is a testbed.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Rewrite/Frontend/Rewriters.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/TokenRewriter.h"
+#include "llvm/Support/raw_ostream.h"
+
+void clang::DoRewriteTest(Preprocessor &PP, raw_ostream* OS) {
+  SourceManager &SM = PP.getSourceManager();
+  const LangOptions &LangOpts = PP.getLangOpts();
+
+  TokenRewriter Rewriter(SM.getMainFileID(), SM, LangOpts);
+
+  // Throw <i> </i> tags around comments.
+  for (TokenRewriter::token_iterator I = Rewriter.token_begin(),
+       E = Rewriter.token_end(); I != E; ++I) {
+    if (I->isNot(tok::comment)) continue;
+
+    Rewriter.AddTokenBefore(I, "<i>");
+    Rewriter.AddTokenAfter(I, "</i>");
+  }
+
+
+  // Print out the output.
+  for (TokenRewriter::token_iterator I = Rewriter.token_begin(),
+       E = Rewriter.token_end(); I != E; ++I)
+    *OS << PP.getSpelling(*I);
+}
diff --git a/lib/Frontend/SerializedDiagnosticPrinter.cpp b/lib/Frontend/SerializedDiagnosticPrinter.cpp
index db89f25..2ab8fbf 100644
--- a/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ b/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -8,12 +8,16 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/SerializedDiagnosticPrinter.h"
+#include "clang/Frontend/SerializedDiagnosticReader.h"
+#include "clang/Frontend/SerializedDiagnostics.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Frontend/DiagnosticRenderer.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Lex/Lexer.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallString.h"
@@ -86,20 +90,70 @@
   void endDiagnostic(DiagOrStoredDiag D,
                      DiagnosticsEngine::Level Level) override;
 };
-  
+
+typedef llvm::DenseMap<unsigned, unsigned> AbbrevLookup;
+
+class SDiagsMerger : SerializedDiagnosticReader {
+  SDiagsWriter &Writer;
+  AbbrevLookup FileLookup;
+  AbbrevLookup CategoryLookup;
+  AbbrevLookup DiagFlagLookup;
+
+public:
+  SDiagsMerger(SDiagsWriter &Writer)
+      : SerializedDiagnosticReader(), Writer(Writer) {}
+
+  std::error_code mergeRecordsFromFile(const char *File) {
+    return readDiagnostics(File);
+  }
+
+protected:
+  std::error_code visitStartOfDiagnostic() override;
+  std::error_code visitEndOfDiagnostic() override;
+  std::error_code visitCategoryRecord(unsigned ID, StringRef Name) override;
+  std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) override;
+  std::error_code visitDiagnosticRecord(
+      unsigned Severity, const serialized_diags::Location &Location,
+      unsigned Category, unsigned Flag, StringRef Message) override;
+  std::error_code visitFilenameRecord(unsigned ID, unsigned Size,
+                                      unsigned Timestamp,
+                                      StringRef Name) override;
+  std::error_code visitFixitRecord(const serialized_diags::Location &Start,
+                                   const serialized_diags::Location &End,
+                                   StringRef CodeToInsert) override;
+  std::error_code
+  visitSourceRangeRecord(const serialized_diags::Location &Start,
+                         const serialized_diags::Location &End) override;
+
+private:
+  std::error_code adjustSourceLocFilename(RecordData &Record,
+                                          unsigned int offset);
+
+  void adjustAbbrevID(RecordData &Record, AbbrevLookup &Lookup,
+                      unsigned NewAbbrev);
+
+  void writeRecordWithAbbrev(unsigned ID, RecordData &Record);
+
+  void writeRecordWithBlob(unsigned ID, RecordData &Record, StringRef Blob);
+};
+
 class SDiagsWriter : public DiagnosticConsumer {
   friend class SDiagsRenderer;
+  friend class SDiagsMerger;
 
   struct SharedState;
 
   explicit SDiagsWriter(IntrusiveRefCntPtr<SharedState> State)
-    : LangOpts(nullptr), OriginalInstance(false), State(State) {}
+      : LangOpts(nullptr), OriginalInstance(false), MergeChildRecords(false),
+        State(State) {}
 
 public:
-  SDiagsWriter(raw_ostream *os, DiagnosticOptions *diags)
-    : LangOpts(nullptr), OriginalInstance(true),
-      State(new SharedState(os, diags))
-  {
+  SDiagsWriter(StringRef File, DiagnosticOptions *Diags, bool MergeChildRecords)
+      : LangOpts(nullptr), OriginalInstance(true),
+        MergeChildRecords(MergeChildRecords),
+        State(new SharedState(File, Diags)) {
+    if (MergeChildRecords)
+      RemoveOldDiagnostics();
     EmitPreamble();
   }
 
@@ -115,6 +169,14 @@
   void finish() override;
 
 private:
+  /// \brief Build a DiagnosticsEngine to emit diagnostics about the diagnostics
+  DiagnosticsEngine *getMetaDiags();
+
+  /// \brief Remove old copies of the serialized diagnostics. This is necessary
+  /// so that we can detect when subprocesses write diagnostics that we should
+  /// merge into our own.
+  void RemoveOldDiagnostics();
+
   /// \brief Emit the preamble for the serialized diagnostics.
   void EmitPreamble();
   
@@ -152,7 +214,9 @@
   /// \brief Emit the string information for diagnostic flags.
   unsigned getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel,
                                  unsigned DiagID = 0);
-  
+
+  unsigned getEmitDiagnosticFlag(StringRef DiagName);
+
   /// \brief Emit (lazily) the file string and retrieved the file identifier.
   unsigned getEmitFile(const char *Filename);
 
@@ -173,9 +237,6 @@
   void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record,
                                   const SourceManager &SM);
 
-  /// \brief The version of the diagnostics file.
-  enum { Version = 2 };
-
   /// \brief Language options, which can differ from one clone of this client
   /// to another.
   const LangOptions *LangOpts;
@@ -184,11 +245,16 @@
   /// clones), responsible for writing the file at the end.
   bool OriginalInstance;
 
+  /// \brief Whether this instance should aggregate diagnostics that are
+  /// generated from child processes.
+  bool MergeChildRecords;
+
   /// \brief State that is shared among the various clones of this diagnostic
   /// consumer.
   struct SharedState : RefCountedBase<SharedState> {
-    SharedState(raw_ostream *os, DiagnosticOptions *diags)
-      : DiagOpts(diags), Stream(Buffer), OS(os), EmittedAnyDiagBlocks(false) { }
+    SharedState(StringRef File, DiagnosticOptions *Diags)
+        : DiagOpts(Diags), Stream(Buffer), OutputFile(File.str()),
+          EmittedAnyDiagBlocks(false) {}
 
     /// \brief Diagnostic options.
     IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
@@ -200,7 +266,7 @@
     llvm::BitstreamWriter Stream;
 
     /// \brief The name of the diagnostics file.
-    std::unique_ptr<raw_ostream> OS;
+    std::string OutputFile;
 
     /// \brief The set of constructed record abbreviations.
     AbbreviationMap Abbrevs;
@@ -227,6 +293,9 @@
     /// this becomes \c true, we never close a DIAG block until we know that we're
     /// starting another one or we're done.
     bool EmittedAnyDiagBlocks;
+
+    /// \brief Engine for emitting diagnostics about the diagnostics.
+    std::unique_ptr<DiagnosticsEngine> MetaDiagnostics;
   };
 
   /// \brief State shared among the various clones of this diagnostic consumer.
@@ -236,9 +305,11 @@
 
 namespace clang {
 namespace serialized_diags {
-DiagnosticConsumer *create(raw_ostream *OS, DiagnosticOptions *diags) {
-  return new SDiagsWriter(OS, diags);
+std::unique_ptr<DiagnosticConsumer>
+create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords) {
+  return llvm::make_unique<SDiagsWriter>(OutputFile, Diags, MergeChildRecords);
 }
+
 } // end namespace serialized_diags
 } // end namespace clang
 
@@ -465,17 +536,15 @@
   Stream.EnterSubblock(BLOCK_META, 3);
   Record.clear();
   Record.push_back(RECORD_VERSION);
-  Record.push_back(Version);
+  Record.push_back(VersionNumber);
   Stream.EmitRecordWithAbbrev(Abbrevs.get(RECORD_VERSION), Record);  
   Stream.ExitBlock();
 }
 
 unsigned SDiagsWriter::getEmitCategory(unsigned int category) {
-  if (State->Categories.count(category))
+  if (!State->Categories.insert(category).second)
     return category;
-  
-  State->Categories.insert(category);
-  
+
   // We use a local version of 'Record' so that we can be generating
   // another record when we lazily generate one for the category entry.
   RecordData Record;
@@ -495,6 +564,10 @@
     return 0; // No flag for notes.
   
   StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(DiagID);
+  return getEmitDiagnosticFlag(FlagName);
+}
+
+unsigned SDiagsWriter::getEmitDiagnosticFlag(StringRef FlagName) {
   if (FlagName.empty())
     return 0;
 
@@ -689,6 +762,40 @@
   Writer.ExitDiagBlock();
 }
 
+DiagnosticsEngine *SDiagsWriter::getMetaDiags() {
+  // FIXME: It's slightly absurd to create a new diagnostics engine here, but
+  // the other options that are available today are worse:
+  //
+  // 1. Teach DiagnosticsConsumers to emit diagnostics to the engine they are a
+  //    part of. The DiagnosticsEngine would need to know not to send
+  //    diagnostics back to the consumer that failed. This would require us to
+  //    rework ChainedDiagnosticsConsumer and teach the engine about multiple
+  //    consumers, which is difficult today because most APIs interface with
+  //    consumers rather than the engine itself.
+  //
+  // 2. Pass a DiagnosticsEngine to SDiagsWriter on creation - this would need
+  //    to be distinct from the engine the writer was being added to and would
+  //    normally not be used.
+  if (!State->MetaDiagnostics) {
+    IntrusiveRefCntPtr<DiagnosticIDs> IDs(new DiagnosticIDs());
+    auto Client =
+        new TextDiagnosticPrinter(llvm::errs(), State->DiagOpts.get());
+    State->MetaDiagnostics = llvm::make_unique<DiagnosticsEngine>(
+        IDs, State->DiagOpts.get(), Client);
+  }
+  return State->MetaDiagnostics.get();
+}
+
+void SDiagsWriter::RemoveOldDiagnostics() {
+  if (!llvm::sys::fs::remove(State->OutputFile))
+    return;
+
+  getMetaDiags()->Report(diag::warn_fe_serialized_diag_merge_failure);
+  // Disable merging child records, as whatever is in this file may be
+  // misleading.
+  MergeChildRecords = false;
+}
+
 void SDiagsWriter::finish() {
   // The original instance is responsible for writing the file.
   if (!OriginalInstance)
@@ -698,9 +805,113 @@
   if (State->EmittedAnyDiagBlocks)
     ExitDiagBlock();
 
-  // Write the generated bitstream to "Out".
-  State->OS->write((char *)&State->Buffer.front(), State->Buffer.size());
-  State->OS->flush();
+  if (MergeChildRecords) {
+    if (!State->EmittedAnyDiagBlocks)
+      // We have no diagnostics of our own, so we can just leave the child
+      // process' output alone
+      return;
 
-  State->OS.reset(nullptr);
+    if (llvm::sys::fs::exists(State->OutputFile))
+      if (SDiagsMerger(*this).mergeRecordsFromFile(State->OutputFile.c_str()))
+        getMetaDiags()->Report(diag::warn_fe_serialized_diag_merge_failure);
+  }
+
+  std::error_code EC;
+  auto OS = llvm::make_unique<llvm::raw_fd_ostream>(State->OutputFile.c_str(),
+                                                    EC, llvm::sys::fs::F_None);
+  if (EC) {
+    getMetaDiags()->Report(diag::warn_fe_serialized_diag_failure)
+        << State->OutputFile << EC.message();
+    return;
+  }
+
+  // Write the generated bitstream to "Out".
+  OS->write((char *)&State->Buffer.front(), State->Buffer.size());
+  OS->flush();
+}
+
+std::error_code SDiagsMerger::visitStartOfDiagnostic() {
+  Writer.EnterDiagBlock();
+  return std::error_code();
+}
+
+std::error_code SDiagsMerger::visitEndOfDiagnostic() {
+  Writer.ExitDiagBlock();
+  return std::error_code();
+}
+
+std::error_code
+SDiagsMerger::visitSourceRangeRecord(const serialized_diags::Location &Start,
+                                     const serialized_diags::Location &End) {
+  RecordData Record;
+  Record.push_back(RECORD_SOURCE_RANGE);
+  Record.push_back(FileLookup[Start.FileID]);
+  Record.push_back(Start.Line);
+  Record.push_back(Start.Col);
+  Record.push_back(Start.Offset);
+  Record.push_back(FileLookup[End.FileID]);
+  Record.push_back(End.Line);
+  Record.push_back(End.Col);
+  Record.push_back(End.Offset);
+
+  Writer.State->Stream.EmitRecordWithAbbrev(
+      Writer.State->Abbrevs.get(RECORD_SOURCE_RANGE), Record);
+  return std::error_code();
+}
+
+std::error_code SDiagsMerger::visitDiagnosticRecord(
+    unsigned Severity, const serialized_diags::Location &Location,
+    unsigned Category, unsigned Flag, StringRef Message) {
+  RecordData MergedRecord;
+  MergedRecord.push_back(RECORD_DIAG);
+  MergedRecord.push_back(Severity);
+  MergedRecord.push_back(FileLookup[Location.FileID]);
+  MergedRecord.push_back(Location.Line);
+  MergedRecord.push_back(Location.Col);
+  MergedRecord.push_back(Location.Offset);
+  MergedRecord.push_back(CategoryLookup[Category]);
+  MergedRecord.push_back(Flag ? DiagFlagLookup[Flag] : 0);
+  MergedRecord.push_back(Message.size());
+
+  Writer.State->Stream.EmitRecordWithBlob(
+      Writer.State->Abbrevs.get(RECORD_DIAG), MergedRecord, Message);
+  return std::error_code();
+}
+
+std::error_code
+SDiagsMerger::visitFixitRecord(const serialized_diags::Location &Start,
+                               const serialized_diags::Location &End,
+                               StringRef Text) {
+  RecordData Record;
+  Record.push_back(RECORD_FIXIT);
+  Record.push_back(FileLookup[Start.FileID]);
+  Record.push_back(Start.Line);
+  Record.push_back(Start.Col);
+  Record.push_back(Start.Offset);
+  Record.push_back(FileLookup[End.FileID]);
+  Record.push_back(End.Line);
+  Record.push_back(End.Col);
+  Record.push_back(End.Offset);
+  Record.push_back(Text.size());
+
+  Writer.State->Stream.EmitRecordWithBlob(
+      Writer.State->Abbrevs.get(RECORD_FIXIT), Record, Text);
+  return std::error_code();
+}
+
+std::error_code SDiagsMerger::visitFilenameRecord(unsigned ID, unsigned Size,
+                                                  unsigned Timestamp,
+                                                  StringRef Name) {
+  FileLookup[ID] = Writer.getEmitFile(Name.str().c_str());
+  return std::error_code();
+}
+
+std::error_code SDiagsMerger::visitCategoryRecord(unsigned ID, StringRef Name) {
+  CategoryLookup[ID] = Writer.getEmitCategory(ID);
+  return std::error_code();
+}
+
+std::error_code SDiagsMerger::visitDiagFlagRecord(unsigned ID, StringRef Name) {
+  DiagFlagLookup[ID] = Writer.getEmitDiagnosticFlag(Name);
+  return std::error_code();
 }
diff --git a/lib/Frontend/SerializedDiagnosticReader.cpp b/lib/Frontend/SerializedDiagnosticReader.cpp
new file mode 100644
index 0000000..c8faef3
--- /dev/null
+++ b/lib/Frontend/SerializedDiagnosticReader.cpp
@@ -0,0 +1,295 @@
+//===--- SerializedDiagnosticReader.cpp - Reads diagnostics ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/SerializedDiagnosticReader.h"
+#include "clang/Frontend/SerializedDiagnostics.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace clang;
+using namespace clang::serialized_diags;
+
+std::error_code SerializedDiagnosticReader::readDiagnostics(StringRef File) {
+  // Open the diagnostics file.
+  FileSystemOptions FO;
+  FileManager FileMgr(FO);
+
+  auto Buffer = FileMgr.getBufferForFile(File);
+  if (!Buffer)
+    return SDError::CouldNotLoad;
+
+  llvm::BitstreamReader StreamFile;
+  StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
+                  (const unsigned char *)(*Buffer)->getBufferEnd());
+
+  llvm::BitstreamCursor Stream(StreamFile);
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'D' ||
+      Stream.Read(8) != 'I' ||
+      Stream.Read(8) != 'A' ||
+      Stream.Read(8) != 'G')
+    return SDError::InvalidSignature;
+
+  // Read the top level blocks.
+  while (!Stream.AtEndOfStream()) {
+    if (Stream.ReadCode() != llvm::bitc::ENTER_SUBBLOCK)
+      return SDError::InvalidDiagnostics;
+
+    std::error_code EC;
+    switch (Stream.ReadSubBlockID()) {
+    case llvm::bitc::BLOCKINFO_BLOCK_ID:
+      if (Stream.ReadBlockInfoBlock())
+        return SDError::MalformedBlockInfoBlock;
+      continue;
+    case BLOCK_META:
+      if ((EC = readMetaBlock(Stream)))
+        return EC;
+      continue;
+    case BLOCK_DIAG:
+      if ((EC = readDiagnosticBlock(Stream)))
+        return EC;
+      continue;
+    default:
+      if (!Stream.SkipBlock())
+        return SDError::MalformedTopLevelBlock;
+      continue;
+    }
+  }
+  return std::error_code();
+}
+
+enum class SerializedDiagnosticReader::Cursor {
+  Record = 1,
+  BlockEnd,
+  BlockBegin
+};
+
+llvm::ErrorOr<SerializedDiagnosticReader::Cursor>
+SerializedDiagnosticReader::skipUntilRecordOrBlock(
+    llvm::BitstreamCursor &Stream, unsigned &BlockOrRecordID) {
+  BlockOrRecordID = 0;
+
+  while (!Stream.AtEndOfStream()) {
+    unsigned Code = Stream.ReadCode();
+
+    switch ((llvm::bitc::FixedAbbrevIDs)Code) {
+    case llvm::bitc::ENTER_SUBBLOCK:
+      BlockOrRecordID = Stream.ReadSubBlockID();
+      return Cursor::BlockBegin;
+
+    case llvm::bitc::END_BLOCK:
+      if (Stream.ReadBlockEnd())
+        return SDError::InvalidDiagnostics;
+      return Cursor::BlockEnd;
+
+    case llvm::bitc::DEFINE_ABBREV:
+      Stream.ReadAbbrevRecord();
+      continue;
+
+    case llvm::bitc::UNABBREV_RECORD:
+      return SDError::UnsupportedConstruct;
+
+    default:
+      // We found a record.
+      BlockOrRecordID = Code;
+      return Cursor::Record;
+    }
+  }
+
+  return SDError::InvalidDiagnostics;
+}
+
+std::error_code
+SerializedDiagnosticReader::readMetaBlock(llvm::BitstreamCursor &Stream) {
+  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META))
+    return SDError::MalformedMetadataBlock;
+
+  bool VersionChecked = false;
+
+  while (true) {
+    unsigned BlockOrCode = 0;
+    llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
+    if (!Res)
+      Res.getError();
+
+    switch (Res.get()) {
+    case Cursor::Record:
+      break;
+    case Cursor::BlockBegin:
+      if (Stream.SkipBlock())
+        return SDError::MalformedMetadataBlock;
+    case Cursor::BlockEnd:
+      if (!VersionChecked)
+        return SDError::MissingVersion;
+      return std::error_code();
+    }
+
+    SmallVector<uint64_t, 1> Record;
+    unsigned RecordID = Stream.readRecord(BlockOrCode, Record);
+
+    if (RecordID == RECORD_VERSION) {
+      if (Record.size() < 1)
+        return SDError::MissingVersion;
+      if (Record[0] > VersionNumber)
+        return SDError::VersionMismatch;
+      VersionChecked = true;
+    }
+  }
+}
+
+std::error_code
+SerializedDiagnosticReader::readDiagnosticBlock(llvm::BitstreamCursor &Stream) {
+  if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG))
+    return SDError::MalformedDiagnosticBlock;
+
+  std::error_code EC;
+  if ((EC = visitStartOfDiagnostic()))
+    return EC;
+
+  SmallVector<uint64_t, 16> Record;
+  while (true) {
+    unsigned BlockOrCode = 0;
+    llvm::ErrorOr<Cursor> Res = skipUntilRecordOrBlock(Stream, BlockOrCode);
+    if (!Res)
+      Res.getError();
+
+    switch (Res.get()) {
+    case Cursor::BlockBegin:
+      // The only blocks we care about are subdiagnostics.
+      if (BlockOrCode == serialized_diags::BLOCK_DIAG) {
+        if ((EC = readDiagnosticBlock(Stream)))
+          return EC;
+      } else if (!Stream.SkipBlock())
+        return SDError::MalformedSubBlock;
+      continue;
+    case Cursor::BlockEnd:
+      if ((EC = visitEndOfDiagnostic()))
+        return EC;
+      return std::error_code();
+    case Cursor::Record:
+      break;
+    }
+
+    // Read the record.
+    Record.clear();
+    StringRef Blob;
+    unsigned RecID = Stream.readRecord(BlockOrCode, Record, &Blob);
+
+    if (RecID < serialized_diags::RECORD_FIRST ||
+        RecID > serialized_diags::RECORD_LAST)
+      continue;
+
+    switch ((RecordIDs)RecID) {
+    case RECORD_CATEGORY:
+      // A category has ID and name size.
+      if (Record.size() != 2)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitCategoryRecord(Record[0], Blob)))
+        return EC;
+      continue;
+    case RECORD_DIAG:
+      // A diagnostic has severity, location (4), category, flag, and message
+      // size.
+      if (Record.size() != 8)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitDiagnosticRecord(
+               Record[0], Location(Record[1], Record[2], Record[3], Record[4]),
+               Record[5], Record[6], Blob)))
+        return EC;
+      continue;
+    case RECORD_DIAG_FLAG:
+      // A diagnostic flag has ID and name size.
+      if (Record.size() != 2)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitDiagFlagRecord(Record[0], Blob)))
+        return EC;
+      continue;
+    case RECORD_FILENAME:
+      // A filename has ID, size, timestamp, and name size. The size and
+      // timestamp are legacy fields that are always zero these days.
+      if (Record.size() != 4)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitFilenameRecord(Record[0], Record[1], Record[2], Blob)))
+        return EC;
+      continue;
+    case RECORD_FIXIT:
+      // A fixit has two locations (4 each) and message size.
+      if (Record.size() != 9)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitFixitRecord(
+               Location(Record[0], Record[1], Record[2], Record[3]),
+               Location(Record[4], Record[5], Record[6], Record[7]), Blob)))
+        return EC;
+      continue;
+    case RECORD_SOURCE_RANGE:
+      // A source range is two locations (4 each).
+      if (Record.size() != 8)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitSourceRangeRecord(
+               Location(Record[0], Record[1], Record[2], Record[3]),
+               Location(Record[4], Record[5], Record[6], Record[7]))))
+        return EC;
+      continue;
+    case RECORD_VERSION:
+      // A version is just a number.
+      if (Record.size() != 1)
+        return SDError::MalformedDiagnosticRecord;
+      if ((EC = visitVersionRecord(Record[0])))
+        return EC;
+      continue;
+    }
+  }
+}
+
+namespace {
+class SDErrorCategoryType final : public std::error_category {
+  const char *name() const LLVM_NOEXCEPT override {
+    return "clang.serialized_diags";
+  }
+  std::string message(int IE) const override {
+    SDError E = static_cast<SDError>(IE);
+    switch (E) {
+    case SDError::CouldNotLoad:
+      return "Failed to open diagnostics file";
+    case SDError::InvalidSignature:
+      return "Invalid diagnostics signature";
+    case SDError::InvalidDiagnostics:
+      return "Parse error reading diagnostics";
+    case SDError::MalformedTopLevelBlock:
+      return "Malformed block at top-level of diagnostics";
+    case SDError::MalformedSubBlock:
+      return "Malformed sub-block in a diagnostic";
+    case SDError::MalformedBlockInfoBlock:
+      return "Malformed BlockInfo block";
+    case SDError::MalformedMetadataBlock:
+      return "Malformed Metadata block";
+    case SDError::MalformedDiagnosticBlock:
+      return "Malformed Diagnostic block";
+    case SDError::MalformedDiagnosticRecord:
+      return "Malformed Diagnostic record";
+    case SDError::MissingVersion:
+      return "No version provided in diagnostics";
+    case SDError::VersionMismatch:
+      return "Unsupported diagnostics version";
+    case SDError::UnsupportedConstruct:
+      return "Bitcode constructs that are not supported in diagnostics appear";
+    case SDError::HandlerFailed:
+      return "Generic error occurred while handling a record";
+    }
+    llvm_unreachable("Unknown error type!");
+  }
+};
+}
+
+static llvm::ManagedStatic<SDErrorCategoryType> ErrorCategory;
+const std::error_category &clang::serialized_diags::SDErrorCategory() {
+  return *ErrorCategory;
+}
diff --git a/lib/Frontend/TextDiagnostic.cpp b/lib/Frontend/TextDiagnostic.cpp
index dc67d68..6e6f3dd 100644
--- a/lib/Frontend/TextDiagnostic.cpp
+++ b/lib/Frontend/TextDiagnostic.cpp
@@ -808,7 +808,8 @@
       if (DiagOpts->getFormat() == DiagnosticOptions::Msvc) {
         OS << ',';
         // Visual Studio 2010 or earlier expects column number to be off by one
-        if (LangOpts.MSCVersion && LangOpts.MSCVersion < 170000000)
+        if (LangOpts.MSCompatibilityVersion &&
+            LangOpts.MSCompatibilityVersion < 170000000)
           ColNo--;
       } else
         OS << ':';
diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp
index 6271509..66b46b7 100644
--- a/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -43,7 +43,7 @@
 }
 
 void TextDiagnosticPrinter::EndSourceFile() {
-  TextDiag.reset(nullptr);
+  TextDiag.reset();
 }
 
 /// \brief Print any diagnostic option information to a raw_ostream.
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index b50950e..3ff6b18 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -27,14 +27,13 @@
 typedef VerifyDiagnosticConsumer::DirectiveList DirectiveList;
 typedef VerifyDiagnosticConsumer::ExpectedData ExpectedData;
 
-VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &_Diags)
-  : Diags(_Diags),
-    PrimaryClient(Diags.getClient()), OwnsPrimaryClient(Diags.ownsClient()),
+VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &Diags_)
+  : Diags(Diags_),
+    PrimaryClient(Diags.getClient()), PrimaryClientOwner(Diags.takeClient()),
     Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(nullptr),
     LangOpts(nullptr), SrcManager(nullptr), ActiveSourceFiles(0),
     Status(HasNoDirectives)
 {
-  Diags.takeClient();
   if (Diags.hasSourceManager())
     setSourceManager(Diags.getSourceManager());
 }
@@ -43,10 +42,8 @@
   assert(!ActiveSourceFiles && "Incomplete parsing of source files!");
   assert(!CurrentPreprocessor && "CurrentPreprocessor should be invalid!");
   SrcManager = nullptr;
-  CheckDiagnostics();  
-  Diags.takeClient();
-  if (OwnsPrimaryClient)
-    delete PrimaryClient;
+  CheckDiagnostics();
+  Diags.takeClient().release();
 }
 
 #ifndef NDEBUG
@@ -84,8 +81,8 @@
       const_cast<Preprocessor*>(PP)->addCommentHandler(this);
 #ifndef NDEBUG
       // Debug build tracks parsed files.
-      VerifyFileTracker *V = new VerifyFileTracker(*this, *SrcManager);
-      const_cast<Preprocessor*>(PP)->addPPCallbacks(V);
+      const_cast<Preprocessor*>(PP)->addPPCallbacks(
+                      llvm::make_unique<VerifyFileTracker>(*this, *SrcManager));
 #endif
     }
   }
@@ -402,8 +399,9 @@
 
         // Lookup file via Preprocessor, like a #include.
         const DirectoryLookup *CurDir;
-        const FileEntry *FE = PP->LookupFile(Pos, Filename, false, nullptr,
-                                             CurDir, nullptr, nullptr, nullptr);
+        const FileEntry *FE =
+            PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
+                           nullptr, nullptr, nullptr);
         if (!FE) {
           Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
                        diag::err_verify_missing_file) << Filename << KindStr;
@@ -502,13 +500,12 @@
     }
 
     // Construct new directive.
-    std::unique_ptr<Directive> D(
-        Directive::create(RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text,
-                          Min, Max));
+    std::unique_ptr<Directive> D = Directive::create(
+        RegexKind, Pos, ExpectedLoc, MatchAnyLine, Text, Min, Max);
 
     std::string Error;
     if (D->isValid(Error)) {
-      DL->push_back(D.release());
+      DL->push_back(std::move(D));
       FoundDirective = true;
     } else {
       Diags.Report(Pos.getLocWithOffset(ContentBegin-PH.Begin),
@@ -644,15 +641,16 @@
 
 /// \brief Takes a list of diagnostics that were expected to have been generated
 /// but were not and produces a diagnostic to the user from this.
-static unsigned PrintExpected(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
-                              DirectiveList &DL, const char *Kind) {
+static unsigned PrintExpected(DiagnosticsEngine &Diags,
+                              SourceManager &SourceMgr,
+                              std::vector<Directive *> &DL, const char *Kind) {
   if (DL.empty())
     return 0;
 
   SmallString<256> Fmt;
   llvm::raw_svector_ostream OS(Fmt);
-  for (DirectiveList::iterator I = DL.begin(), E = DL.end(); I != E; ++I) {
-    Directive &D = **I;
+  for (auto *DirPtr : DL) {
+    Directive &D = *DirPtr;
     OS << "\n  File " << SourceMgr.getFilename(D.DiagnosticLoc);
     if (D.MatchAnyLine)
       OS << " Line *";
@@ -694,11 +692,11 @@
                            DirectiveList &Left,
                            const_diag_iterator d2_begin,
                            const_diag_iterator d2_end) {
-  DirectiveList LeftOnly;
+  std::vector<Directive *> LeftOnly;
   DiagList Right(d2_begin, d2_end);
 
-  for (DirectiveList::iterator I = Left.begin(), E = Left.end(); I != E; ++I) {
-    Directive& D = **I;
+  for (auto &Owner : Left) {
+    Directive &D = *Owner;
     unsigned LineNo1 = SourceMgr.getPresumedLineNumber(D.DiagnosticLoc);
 
     for (unsigned i = 0; i < D.Max; ++i) {
@@ -720,7 +718,7 @@
       if (II == IE) {
         // Not found.
         if (i >= D.Min) break;
-        LeftOnly.push_back(*I);
+        LeftOnly.push_back(&D);
       } else {
         // Found. The same cannot be found twice.
         Right.erase(II);
@@ -801,8 +799,8 @@
 
 void VerifyDiagnosticConsumer::CheckDiagnostics() {
   // Ensure any diagnostics go to the primary client.
-  bool OwnsCurClient = Diags.ownsClient();
-  DiagnosticConsumer *CurClient = Diags.takeClient();
+  DiagnosticConsumer *CurClient = Diags.getClient();
+  std::unique_ptr<DiagnosticConsumer> Owner = Diags.takeClient();
   Diags.setClient(PrimaryClient, false);
 
 #ifndef NDEBUG
@@ -864,20 +862,21 @@
                                   Buffer->note_end(), "note"));
   }
 
-  Diags.takeClient();
-  Diags.setClient(CurClient, OwnsCurClient);
+  Diags.setClient(CurClient, Owner.release() != nullptr);
 
   // Reset the buffer, we have processed all the diagnostics in it.
   Buffer.reset(new TextDiagnosticBuffer());
   ED.Reset();
 }
 
-Directive *Directive::create(bool RegexKind, SourceLocation DirectiveLoc,
-                             SourceLocation DiagnosticLoc, bool MatchAnyLine,
-                             StringRef Text, unsigned Min, unsigned Max) {
+std::unique_ptr<Directive> Directive::create(bool RegexKind,
+                                             SourceLocation DirectiveLoc,
+                                             SourceLocation DiagnosticLoc,
+                                             bool MatchAnyLine, StringRef Text,
+                                             unsigned Min, unsigned Max) {
   if (!RegexKind)
-    return new StandardDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine,
-                                 Text, Min, Max);
+    return llvm::make_unique<StandardDirective>(DirectiveLoc, DiagnosticLoc,
+                                                MatchAnyLine, Text, Min, Max);
 
   // Parse the directive into a regular expression.
   std::string RegexStr;
@@ -902,6 +901,6 @@
     }
   }
 
-  return new RegexDirective(DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text,
-                            Min, Max, RegexStr);
+  return llvm::make_unique<RegexDirective>(
+      DirectiveLoc, DiagnosticLoc, MatchAnyLine, Text, Min, Max, RegexStr);
 }
