[PCH] Fix a regression that r139441 introduced (decls were getting passed
to the consumer without being fully deserialized).

The regression was on compiling boost.python and it was too difficult to get a reduced
test case unfortunately.

Also modify the logic of how objc methods are getting passed to the consumer;
codegen depended on receiving objc methods before the implementation decl.
Since the interesting objc methods are ones with a body and such methods only
exist inside an ObjCImplDecl, deserialize and pass to consumer all the methods
of ObCImplDecl when we see one.

Fixes http://llvm.org/PR10922 & rdar://10117105.

llvm-svn: 139644
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 429edf9..77f4fb8 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -4142,12 +4142,31 @@
   return const_cast<DeclContext*>(DC)->lookup(Name);
 }
 
+/// \brief Under non-PCH compilation the consumer receives the objc methods
+/// before receiving the implementation, and codegen depends on this.
+/// We simulate this by deserializing and passing to consumer the methods of the
+/// implementation before passing the deserialized implementation decl.
+static void PassObjCImplDeclToConsumer(ObjCImplDecl *ImplD,
+                                       ASTConsumer *Consumer) {
+  assert(ImplD && Consumer);
+
+  for (ObjCImplDecl::method_iterator
+         I = ImplD->meth_begin(), E = ImplD->meth_end(); I != E; ++I)
+    Consumer->HandleInterestingDecl(DeclGroupRef(*I));
+
+  Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
+}
+
 void ASTReader::PassInterestingDeclsToConsumer() {
   assert(Consumer);
   while (!InterestingDecls.empty()) {
-    DeclGroupRef DG(InterestingDecls.front());
+    Decl *D = InterestingDecls.front();
     InterestingDecls.pop_front();
-    Consumer->HandleInterestingDecl(DG);
+
+    if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
+      PassObjCImplDeclToConsumer(ImplD, Consumer);
+    else
+      Consumer->HandleInterestingDecl(DeclGroupRef(D));
   }
 }