Index: tools/clang/include/clang/Basic/Diagnostic.h
==================================================================
--- tools/clang/include/clang/Basic/Diagnostic.h
+++ tools/clang/include/clang/Basic/Diagnostic.h
@@ -32,10 +32,11 @@
   class DeclContext;
   class LangOptions;
   class Preprocessor;
   class DiagnosticErrorTrap;
   class StoredDiagnostic;
+  class CommentHandler;
 
 /// \brief Annotates a diagnostic with some code that should be
 /// inserted, removed, or replaced to fix the problem.
 ///
 /// This kind of hint should be used when we are certain that the
@@ -1231,10 +1232,15 @@
   /// Default implementation just keeps track of the total number of warnings
   /// and errors.
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                 const Diagnostic &Info);
   
+  /// \brief Return the CommentHandler for this instance.
+  virtual CommentHandler *getCommentHandler() {
+    return 0;
+  }
+
   /// \brief Clone the diagnostic consumer, producing an equivalent consumer
   /// that can be used in a different context.
   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0;
 };
 

Index: tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
==================================================================
--- tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -178,11 +178,15 @@
   virtual bool HandleComment(Preprocessor &PP, SourceRange Comment);
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                 const Diagnostic &Info);
   
+  virtual CommentHandler *getCommentHandler() {
+    return this;
+  }
+
   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
 };
 
 } // end namspace clang
 
 #endif

Index: tools/clang/lib/ARCMigrate/ARCMT.cpp
==================================================================
--- tools/clang/lib/ARCMigrate/ARCMT.cpp
+++ tools/clang/lib/ARCMigrate/ARCMT.cpp
@@ -87,17 +87,51 @@
   return false;
 }
 
 namespace {
 
-class CaptureDiagnosticConsumer : public DiagnosticConsumer {
+class CaptureDiagnosticConsumer : public DiagnosticConsumer,
+                                  public CommentHandler {
+  typedef std::vector<SourceRange> CommentList;
   DiagnosticsEngine &Diags;
   CapturedDiagList &CapturedDiags;
+  CommentList Comments;
+  Preprocessor *PP;
 public:
   CaptureDiagnosticConsumer(DiagnosticsEngine &diags,
                            CapturedDiagList &capturedDiags)
-    : Diags(diags), CapturedDiags(capturedDiags) { }
+    : Diags(diags), CapturedDiags(capturedDiags), PP(0) { }
+
+  void BeginSourceFile(const LangOptions &, const Preprocessor *PP) {
+    // FIXME: Better would be if we could make a copy of Preprocessor, rather
+    // than use const_cast; see also VerifyDiagnosticConsumer::BeginSourceFile.
+    if (PP) {
+      this->PP = const_cast<Preprocessor*>(PP);
+      this->PP->addCommentHandler(this);
+    }
+  }
+
+  void EndSourceFile() {
+    if (PP) PP->removeCommentHandler(this);
+  }
+
+  bool HandleComment(Preprocessor& PP, SourceRange Comment) {
+    assert(&PP == this->PP && "Preprocessor changed!");
+    Comments.push_back(Comment);
+    return false;
+  }
+
+  void ForwardComments(CommentHandler *Target) {
+    bool ret;
+    if (Target && PP) {
+      for (CommentList::iterator I = Comments.begin(), End = Comments.end();
+            I != End; ++I) {
+        ret = Target->HandleComment(*PP, *I);
+        assert(!ret && "CommentCapture cannot handle CommentHandlers that push tokens");
+      }
+    }
+  }
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
                                 const Diagnostic &Info) {
     if (DiagnosticIDs::isARCDiagnostic(Info.getID()) ||
         level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) {
@@ -274,10 +308,11 @@
   ASTContext &Ctx = Unit->getASTContext();
 
   if (Diags->hasFatalErrorOccurred()) {
     Diags->Reset();
     DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
+    errRec.ForwardComments(DiagClient->getCommentHandler());
     capturedDiags.reportDiagnostics(*Diags);
     DiagClient->EndSourceFile();
     return true;
   }
 
@@ -297,10 +332,11 @@
   // diagnostics objects to emit further diagnostics.
   // We call BeginSourceFile because DiagnosticConsumer requires that 
   // diagnostics with source range information are emitted only in between
   // BeginSourceFile() and EndSourceFile().
   DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
+  errRec.ForwardComments(DiagClient->getCommentHandler());
 
   // No macros will be added since we are just checking and we won't modify
   // source code.
   std::vector<SourceLocation> ARCMTMacroLocs;
 
@@ -582,10 +618,11 @@
   ASTContext &Ctx = Unit->getASTContext();
 
   if (Diags->hasFatalErrorOccurred()) {
     Diags->Reset();
     DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
+    errRec.ForwardComments(DiagClient->getCommentHandler());
     capturedDiags.reportDiagnostics(*Diags);
     DiagClient->EndSourceFile();
     return true;
   }
 
@@ -593,10 +630,11 @@
   // diagnostics objects to emit further diagnostics.
   // We call BeginSourceFile because DiagnosticConsumer requires that 
   // diagnostics with source range information are emitted only in between
   // BeginSourceFile() and EndSourceFile().
   DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
+  errRec.ForwardComments(DiagClient->getCommentHandler());
 
   Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
   TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
   MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(),
                      Unit->getSema(), TA, ARCMTMacroLocs);

