diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index ba2d63b026d57d114e4b48d3b85b2fdcaefd732d..b5284d8022f0e1781113fb27484b461208643604 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -30,37 +30,70 @@ using namespace clang;
 
 namespace {
 
-/// \brief Dumps deserialized declarations.
-class DeserializedDeclsDumper : public ASTDeserializationListener {
+class DelegatingDeserializationListener : public ASTDeserializationListener {
   ASTDeserializationListener *Previous;
 
 public:
-  DeserializedDeclsDumper(ASTDeserializationListener *Previous)
+  explicit DelegatingDeserializationListener(
+                                           ASTDeserializationListener *Previous)
     : Previous(Previous) { }
 
+  virtual void ReaderInitialized(ASTReader *Reader) {
+    if (Previous)
+      Previous->ReaderInitialized(Reader);
+  }
+  virtual void IdentifierRead(serialization::IdentID ID,
+                              IdentifierInfo *II) {
+    if (Previous)
+      Previous->IdentifierRead(ID, II);
+  }
+  virtual void TypeRead(serialization::TypeIdx Idx, QualType T) {
+    if (Previous)
+      Previous->TypeRead(Idx, T);
+  }
+  virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
+    if (Previous)
+      Previous->DeclRead(ID, D);
+  }
+  virtual void SelectorRead(serialization::SelectorID ID, Selector Sel) {
+    if (Previous)
+      Previous->SelectorRead(ID, Sel);
+  }
+  virtual void MacroDefinitionRead(serialization::PreprocessedEntityID PPID, 
+                                   MacroDefinition *MD) {
+    if (Previous)
+      Previous->MacroDefinitionRead(PPID, MD);
+  }
+};
+
+/// \brief Dumps deserialized declarations.
+class DeserializedDeclsDumper : public DelegatingDeserializationListener {
+public:
+  explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous)
+    : DelegatingDeserializationListener(Previous) { }
+
   virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
     llvm::outs() << "PCH DECL: " << D->getDeclKindName();
     if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
       llvm::outs() << " - " << ND->getNameAsString();
     llvm::outs() << "\n";
 
-    if (Previous)
-      Previous->DeclRead(ID, D);
+    DelegatingDeserializationListener::DeclRead(ID, D);
   }
 };
 
   /// \brief Checks deserialized declarations and emits error if a name
   /// matches one given in command-line using -error-on-deserialized-decl.
-  class DeserializedDeclsChecker : public ASTDeserializationListener {
+  class DeserializedDeclsChecker : public DelegatingDeserializationListener {
     ASTContext &Ctx;
     std::set<std::string> NamesToCheck;
-    ASTDeserializationListener *Previous;
 
   public:
     DeserializedDeclsChecker(ASTContext &Ctx,
                              const std::set<std::string> &NamesToCheck, 
                              ASTDeserializationListener *Previous)
-      : Ctx(Ctx), NamesToCheck(NamesToCheck), Previous(Previous) { }
+      : DelegatingDeserializationListener(Previous),
+        Ctx(Ctx), NamesToCheck(NamesToCheck) { }
 
     virtual void DeclRead(serialization::DeclID ID, const Decl *D) {
       if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
@@ -72,8 +105,7 @@ public:
               << ND->getNameAsString();
         }
 
-      if (Previous)
-        Previous->DeclRead(ID, D);
+      DelegatingDeserializationListener::DeclRead(ID, D);
     }
 };