Author: akirtzidis Date: Tue Sep 13 16:35:00 2011 New Revision: 139644 URL: http://llvm.org/viewvc/llvm-project?rev=139644&view=rev Log: [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. Modified: cfe/trunk/lib/AST/ASTContext.cpp cfe/trunk/lib/Serialization/ASTReader.cpp cfe/trunk/lib/Serialization/ASTReaderDecl.cpp cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Modified: cfe/trunk/lib/AST/ASTContext.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=139644&r1=139643&r2=139644&view=diff ============================================================================== --- cfe/trunk/lib/AST/ASTContext.cpp (original) +++ cfe/trunk/lib/AST/ASTContext.cpp Tue Sep 13 16:35:00 2011 @@ -6387,7 +6387,7 @@ if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { if (!VD->isFileVarDecl()) return false; - } else if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) + } else if (!isa<FunctionDecl>(D)) return false; // Weak references don't produce any output by themselves. @@ -6427,9 +6427,6 @@ return false; return true; } - - if (const ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) - return Method->hasBody(); const VarDecl *VD = cast<VarDecl>(D); assert(VD->isFileVarDecl() && "Expected file scoped var"); Modified: cfe/trunk/lib/Serialization/ASTReader.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=139644&r1=139643&r2=139644&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReader.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Sep 13 16:35:00 2011 @@ -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)); } } Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=139644&r1=139643&r2=139644&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Sep 13 16:35:00 2011 @@ -1393,6 +1393,9 @@ /// code generation, e.g., inline function definitions, Objective-C /// declarations with metadata, etc. static bool isConsumerInterestedIn(Decl *D) { + // An ObjCMethodDecl is never considered as "interesting" because its + // implementation container always is. + if (isa<FileScopeAsmDecl>(D) || isa<ObjCProtocolDecl>(D) || isa<ObjCImplDecl>(D)) @@ -1402,8 +1405,6 @@ Var->isThisDeclarationADefinition() == VarDecl::Definition; if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) return Func->doesThisDeclarationHaveABody(); - if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D)) - return Method->hasBody(); return false; } @@ -1737,14 +1738,8 @@ // AST consumer might need to know about, queue it. // We don't pass it to the consumer immediately because we may be in recursive // loading, and some declarations may still be initializing. - if (isConsumerInterestedIn(D)) { - if (Consumer) { - DeclGroupRef DG(D); - Consumer->HandleInterestingDecl(DG); - } else { + if (isConsumerInterestedIn(D)) InterestingDecls.push_back(D); - } - } return D; } Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=139644&r1=139643&r2=139644&view=diff ============================================================================== --- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original) +++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Tue Sep 13 16:35:00 2011 @@ -1594,6 +1594,9 @@ /// relatively painless since they would presumably only do it for top-level /// decls. static bool isRequiredDecl(const Decl *D, ASTContext &Context) { + // An ObjCMethodDecl is never considered as "required" because its + // implementation container always is. + // File scoped assembly or obj-c implementation must be seen. if (isa<FileScopeAsmDecl>(D) || isa<ObjCImplDecl>(D)) return true; _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
