Index: tools/clang/include/clang/Basic/Diagnostic.h
==================================================================
--- tools/clang/include/clang/Basic/Diagnostic.h
+++ tools/clang/include/clang/Basic/Diagnostic.h
@@ -1222,17 +1222,29 @@
 };
 
 /// \brief Abstract interface, implemented by clients of the front-end, which
 /// formats and prints fully processed diagnostics.
 class DiagnosticConsumer {
+public:
+  enum ClassId { DC_Ignoring, DC_Chained, DC_Verify,
+                 DC_LogPrinter, DC_TextPrinter,
+                 DC_TextBuffer, DC_FixItRewriter,
+
+                 /// \brief Use DC_Unknown as the class identifier where
+                 /// use of isa/cast/dyn_cast is not required.
+                 DC_Unknown };
+private:
+  const ClassId Id;
 protected:
   unsigned NumWarnings;       ///< Number of warnings reported
   unsigned NumErrors;         ///< Number of errors reported
   
 public:
-  DiagnosticConsumer() : NumWarnings(0), NumErrors(0) { }
+  DiagnosticConsumer(ClassId ClassId) : Id(ClassId),
+    NumWarnings(0), NumErrors(0) { }
 
+  ClassId getClassId() const { return Id; }
   unsigned getNumErrors() const { return NumErrors; }
   unsigned getNumWarnings() const { return NumWarnings; }
   virtual void clear() { NumWarnings = NumErrors = 0; }
 
   virtual ~DiagnosticConsumer();
@@ -1278,22 +1290,35 @@
                                 const Diagnostic &Info);
   
   /// \brief Clone the diagnostic consumer, producing an equivalent consumer
   /// that can be used in a different context.
   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const = 0;
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *) { return true; }
 };
 
 /// \brief A diagnostic client that ignores all diagnostics.
 class IgnoringDiagConsumer : public DiagnosticConsumer {
+public:
+  IgnoringDiagConsumer() : DiagnosticConsumer(DC_Ignoring) { }
   virtual void anchor();
   void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                         const Diagnostic &Info) {
     // Just ignore it.
   }
   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
     return new IgnoringDiagConsumer();
   }
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_Ignoring;
+  }
+  static bool classof(const IgnoringDiagConsumer *) {
+    return true;
+  }
 };
 
 // Struct used for sending info about how a type should be printed.
 struct TemplateDiffTypes {
   intptr_t FromType;

Index: tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
==================================================================
--- tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
+++ tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h
@@ -25,11 +25,12 @@
   OwningPtr<DiagnosticConsumer> Primary;
   OwningPtr<DiagnosticConsumer> Secondary;
 
 public:
   ChainedDiagnosticConsumer(DiagnosticConsumer *_Primary,
-                          DiagnosticConsumer *_Secondary) {
+                          DiagnosticConsumer *_Secondary)
+      : DiagnosticConsumer(DC_Chained) {
     Primary.reset(_Primary);
     Secondary.reset(_Secondary);
   }
 
   virtual void BeginSourceFile(const LangOptions &LO,
@@ -64,10 +65,17 @@
   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {
     return new ChainedDiagnosticConsumer(Primary->clone(Diags), 
                                          Secondary->clone(Diags));
   }
 
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_Chained;
+  }
+  static bool classof(const ChainedDiagnosticConsumer *) {
+    return true;
+  }
 };
 
 } // end namspace clang
 
 #endif

Index: tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h
==================================================================
--- tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h
+++ tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h
@@ -70,10 +70,18 @@
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                 const Diagnostic &Info);
   
   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_LogPrinter;
+  }
+  static bool classof(const LogDiagnosticPrinter *) {
+    return true;
+  }
 };
 
 } // end namespace clang
 
 #endif

Index: tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h
==================================================================
--- tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h
+++ tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h
@@ -28,10 +28,12 @@
   typedef DiagList::iterator iterator;
   typedef DiagList::const_iterator const_iterator;
 private:
   DiagList Errors, Warnings, Notes;
 public:
+  TextDiagnosticBuffer() : DiagnosticConsumer(DC_TextBuffer) { }
+
   const_iterator err_begin() const  { return Errors.begin(); }
   const_iterator err_end() const    { return Errors.end(); }
 
   const_iterator warn_begin() const { return Warnings.begin(); }
   const_iterator warn_end() const   { return Warnings.end(); }
@@ -45,10 +47,18 @@
   /// FlushDiagnostics - Flush the buffered diagnostics to an given
   /// diagnostic engine.
   void FlushDiagnostics(DiagnosticsEngine &Diags) const;
   
   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_TextBuffer;
+  }
+  static bool classof(const TextDiagnosticBuffer *) {
+    return true;
+  }
 };
 
 } // end namspace clang
 
 #endif

Index: tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h
==================================================================
--- tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h
+++ tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h
@@ -48,10 +48,18 @@
 
   void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP);
   void EndSourceFile();
   void HandleDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info);
   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_TextPrinter;
+  }
+  static bool classof(const TextDiagnosticPrinter *) {
+    return true;
+  }
 };
 
 } // end namespace clang
 
 #endif

Index: tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
==================================================================
--- tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -196,10 +196,18 @@
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                 const Diagnostic &Info);
   
   virtual DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_Verify;
+  }
+  static bool classof(const VerifyDiagnosticConsumer *) {
+    return true;
+  }
 };
 
 } // end namspace clang
 
 #endif

Index: tools/clang/include/clang/Rewrite/FixItRewriter.h
==================================================================
--- tools/clang/include/clang/Rewrite/FixItRewriter.h
+++ tools/clang/include/clang/Rewrite/FixItRewriter.h
@@ -121,10 +121,18 @@
 
   /// \brief Emit a diagnostic via the adapted diagnostic client.
   void Diag(SourceLocation Loc, unsigned DiagID);
   
   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const;
+
+  /// \brief Implement isa/cast/dyn_cast/etc.
+  static bool classof(const DiagnosticConsumer *DC) {
+    return DC->getClassId() == DC_FixItRewriter;
+  }
+  static bool classof(const FixItRewriter *) {
+    return true;
+  }
 };
 
 }
 
 #endif // LLVM_CLANG_REWRITE_FIX_IT_REWRITER_H

Index: tools/clang/lib/ARCMigrate/ARCMT.cpp
==================================================================
--- tools/clang/lib/ARCMigrate/ARCMT.cpp
+++ tools/clang/lib/ARCMigrate/ARCMT.cpp
@@ -10,10 +10,11 @@
 #include "Internals.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Frontend/VerifyDiagnosticConsumer.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/Rewrite/Rewriter.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "clang/Basic/DiagnosticCategories.h"
@@ -87,17 +88,54 @@
   return false;
 }
 
 namespace {
 
-class CaptureDiagnosticConsumer : public DiagnosticConsumer {
+class CaptureDiagnosticConsumer : public DiagnosticConsumer,
+                                  public CommentHandler {
+  typedef SmallVector<SourceRange, 10> CommentList;
   DiagnosticsEngine &Diags;
   CapturedDiagList &CapturedDiags;
+  CommentList Comments;
+  Preprocessor *PP;
 public:
   CaptureDiagnosticConsumer(DiagnosticsEngine &diags,
                            CapturedDiagList &capturedDiags)
-    : Diags(diags), CapturedDiags(capturedDiags) { }
+    : DiagnosticConsumer(DC_Unknown), Diags(diags),
+      CapturedDiags(capturedDiags), PP(0) { }
+
+  void BeginSourceFile(const LangOptions &, const Preprocessor *PP) {
+    assert(!this->PP && "CaptureDiagnosticConsumer already used!");
+    if (PP) {
+      this->PP = const_cast<Preprocessor*>(PP);
+      this->PP->addCommentHandler(this);
+    }
+  }
+
+  void EndSourceFile() {
+    if (PP) PP->removeCommentHandler(this);
+    // PP is not cleared since it is required in ForwardComments which
+    // is called after file parsing has completed.
+  }
+
+  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 && "Cannot handle CommentHandlers that push tokens");
+      }
+    }
+    (void)ret; // Silence compiler warning on unused variable.
+  }
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
                                 const Diagnostic &Info) {
     if (DiagnosticIDs::isARCDiagnostic(Info.getID()) ||
         level >= DiagnosticsEngine::Error || level == DiagnosticsEngine::Note) {
@@ -274,10 +312,11 @@
   ASTContext &Ctx = Unit->getASTContext();
 
   if (Diags->hasFatalErrorOccurred()) {
     Diags->Reset();
     DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
+    errRec.ForwardComments(dyn_cast<VerifyDiagnosticConsumer>(DiagClient));
     capturedDiags.reportDiagnostics(*Diags);
     DiagClient->EndSourceFile();
     return true;
   }
 
@@ -297,10 +336,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(dyn_cast<VerifyDiagnosticConsumer>(DiagClient));
 
   // No macros will be added since we are just checking and we won't modify
   // source code.
   std::vector<SourceLocation> ARCMTMacroLocs;
 
@@ -582,10 +622,11 @@
   ASTContext &Ctx = Unit->getASTContext();
 
   if (Diags->hasFatalErrorOccurred()) {
     Diags->Reset();
     DiagClient->BeginSourceFile(Ctx.getLangOpts(), &Unit->getPreprocessor());
+    errRec.ForwardComments(dyn_cast<VerifyDiagnosticConsumer>(DiagClient));
     capturedDiags.reportDiagnostics(*Diags);
     DiagClient->EndSourceFile();
     return true;
   }
 
@@ -593,10 +634,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(dyn_cast<VerifyDiagnosticConsumer>(DiagClient));
 
   Rewriter rewriter(Ctx.getSourceManager(), Ctx.getLangOpts());
   TransformActions TA(*Diags, capturedDiags, Ctx, Unit->getPreprocessor());
   MigrationPass pass(Ctx, OrigCI.getLangOpts()->getGC(),
                      Unit->getSema(), TA, ARCMTMacroLocs);

Index: tools/clang/lib/Frontend/ASTUnit.cpp
==================================================================
--- tools/clang/lib/Frontend/ASTUnit.cpp
+++ tools/clang/lib/Frontend/ASTUnit.cpp
@@ -568,11 +568,11 @@
   SmallVectorImpl<StoredDiagnostic> &StoredDiags;
   
 public:
   explicit StoredDiagnosticConsumer(
                           SmallVectorImpl<StoredDiagnostic> &StoredDiags)
-    : StoredDiags(StoredDiags) { }
+    : DiagnosticConsumer(DC_Unknown), StoredDiags(StoredDiags) { }
   
   virtual void HandleDiagnostic(DiagnosticsEngine::Level Level,
                                 const Diagnostic &Info);
   
   DiagnosticConsumer *clone(DiagnosticsEngine &Diags) const {

Index: tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp
==================================================================
--- tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp
+++ tools/clang/lib/Frontend/LogDiagnosticPrinter.cpp
@@ -16,11 +16,11 @@
 using namespace clang;
 
 LogDiagnosticPrinter::LogDiagnosticPrinter(raw_ostream &os,
                                            const DiagnosticOptions &diags,
                                            bool _OwnsOutputStream)
-  : OS(os), LangOpts(0), DiagOpts(&diags),
+  : DiagnosticConsumer(DC_LogPrinter), OS(os), LangOpts(0), DiagOpts(&diags),
     OwnsOutputStream(_OwnsOutputStream) {
 }
 
 LogDiagnosticPrinter::~LogDiagnosticPrinter() {
   if (OwnsOutputStream)

Index: tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
==================================================================
--- tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
+++ tools/clang/lib/Frontend/SerializedDiagnosticPrinter.cpp
@@ -90,11 +90,11 @@
   
 class SDiagsWriter : public DiagnosticConsumer {
   friend class SDiagsRenderer;
 public:  
   explicit SDiagsWriter(llvm::raw_ostream *os, const DiagnosticOptions &diags) 
-    : LangOpts(0), DiagOpts(diags),
+    : DiagnosticConsumer(DC_Unknown), LangOpts(0), DiagOpts(diags),
       Stream(Buffer), OS(os), inNonNoteDiagnostic(false)
   { 
     EmitPreamble();
   }
   

Index: tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp
==================================================================
--- tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ tools/clang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -25,11 +25,11 @@
 using namespace clang;
 
 TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &os,
                                              const DiagnosticOptions &diags,
                                              bool _OwnsOutputStream)
-  : OS(os), DiagOpts(&diags),
+  : DiagnosticConsumer(DC_TextPrinter), OS(os), DiagOpts(&diags),
     OwnsOutputStream(_OwnsOutputStream) {
 }
 
 TextDiagnosticPrinter::~TextDiagnosticPrinter() {
   if (OwnsOutputStream)

Index: tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
==================================================================
--- tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ tools/clang/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -24,12 +24,12 @@
 typedef VerifyDiagnosticConsumer::Directive Directive;
 typedef VerifyDiagnosticConsumer::DirectiveList DirectiveList;
 typedef VerifyDiagnosticConsumer::ExpectedData ExpectedData;
 
 VerifyDiagnosticConsumer::VerifyDiagnosticConsumer(DiagnosticsEngine &_Diags)
-  : Diags(_Diags),
+  : DiagnosticConsumer(DC_Verify), Diags(_Diags),
     PrimaryClient(Diags.getClient()), OwnsPrimaryClient(Diags.ownsClient()),
     Buffer(new TextDiagnosticBuffer()), CurrentPreprocessor(0),
     ActiveSourceFiles(0)
 {
   Diags.takeClient();

Index: tools/clang/lib/Rewrite/FixItRewriter.cpp
==================================================================
--- tools/clang/lib/Rewrite/FixItRewriter.cpp
+++ tools/clang/lib/Rewrite/FixItRewriter.cpp
@@ -28,11 +28,12 @@
 using namespace clang;
 
 FixItRewriter::FixItRewriter(DiagnosticsEngine &Diags, SourceManager &SourceMgr,
                              const LangOptions &LangOpts,
                              FixItOptions *FixItOpts)
-  : Diags(Diags),
+  : DiagnosticConsumer(DC_FixItRewriter),
+    Diags(Diags),
     Editor(SourceMgr, LangOpts),
     Rewrite(SourceMgr, LangOpts),
     FixItOpts(FixItOpts),
     NumFailures(0),
     PrevDiagSilenced(false) {

ADDED   tools/clang/test/ARCMT/verify.m
Index: tools/clang/test/ARCMT/verify.m
==================================================================
--- tools/clang/test/ARCMT/verify.m
+++ tools/clang/test/ARCMT/verify.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -arcmt-check -verify %s
+
+#if 0
+// expected-error {{should be ignored}}
+#endif
+
+#error should not be ignored
+// expected-error@-1 {{should not be ignored}}

Index: tools/clang/tools/libclang/Indexing.cpp
==================================================================
--- tools/clang/tools/libclang/Indexing.cpp
+++ tools/clang/tools/libclang/Indexing.cpp
@@ -157,10 +157,11 @@
 //===----------------------------------------------------------------------===//
 
 class CaptureDiagnosticConsumer : public DiagnosticConsumer {
   SmallVector<StoredDiagnostic, 4> Errors;
 public:
+  CaptureDiagnosticConsumer() : DiagnosticConsumer(DC_Unknown) { }
 
   virtual void HandleDiagnostic(DiagnosticsEngine::Level level,
                                 const Diagnostic &Info) {
     if (level >= DiagnosticsEngine::Error)
       Errors.push_back(StoredDiagnostic(level, Info));
