diff options
Diffstat (limited to 'lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 762ad01b51..41d8ff98a1 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -47,6 +47,8 @@ namespace clang { DeclID DeclContextIDForTemplateParmDecl; DeclID LexicalDeclContextIDForTemplateParmDecl; + bool HasPendingBody; + uint64_t GetCurrentCursorOffset(); SourceLocation ReadSourceLocation(const RecordData &R, unsigned &I) { @@ -198,11 +200,14 @@ namespace clang { const RecordData &Record, unsigned &Idx) : Reader(Reader), F(F), ThisDeclID(thisDeclID), RawLocation(RawLocation), Record(Record), Idx(Idx), - TypeIDForTypeDecl(0) { } + TypeIDForTypeDecl(0), HasPendingBody(false) { } static void attachPreviousDecl(Decl *D, Decl *previous); static void attachLatestDecl(Decl *D, Decl *latest); + /// \brief Determine whether this declaration has a pending body. + bool hasPendingBody() const { return HasPendingBody; } + void Visit(Decl *D); void UpdateDecl(Decl *D, ModuleFile &ModuleFile, @@ -324,9 +329,10 @@ void ASTDeclReader::Visit(Decl *D) { // module). // FIXME: Also consider = default and = delete. // FIXME: Can we diagnose ODR violations somehow? - if (Record[Idx++] && - (!Reader.getContext().getLangOpts().Modules || !FD->hasBody())) - FD->setLazyBody(GetCurrentCursorOffset()); + if (Record[Idx++]) { + Reader.PendingBodies[FD] = GetCurrentCursorOffset(); + HasPendingBody = true; + } } else if (D->isTemplateParameter()) { // If we have a fully initialized template parameter, we can now // set its DeclContext. @@ -634,13 +640,10 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { void ASTDeclReader::VisitObjCMethodDecl(ObjCMethodDecl *MD) { VisitNamedDecl(MD); if (Record[Idx++]) { - // In practice, this won't be executed (since method definitions - // don't occur in header files). - // Switch case IDs for this method body. - ASTReader::SwitchCaseMapTy SwitchCaseStmtsForObjCMethod; - SaveAndRestore<ASTReader::SwitchCaseMapTy *> - SCFOM(Reader.CurrSwitchCaseStmts, &SwitchCaseStmtsForObjCMethod); - MD->setBody(Reader.ReadStmt(F)); + // Load the body on-demand. Most clients won't care, because method + // definitions rarely show up in headers. + Reader.PendingBodies[MD] = GetCurrentCursorOffset(); + HasPendingBody = true; MD->setSelfDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx)); MD->setCmdDecl(ReadDeclAs<ImplicitParamDecl>(Record, Idx)); } @@ -1662,7 +1665,7 @@ inline void ASTReader::LoadedDecl(unsigned Index, Decl *D) { /// This routine should return true for anything that might affect /// code generation, e.g., inline function definitions, Objective-C /// declarations with metadata, etc. -static bool isConsumerInterestedIn(Decl *D) { +static bool isConsumerInterestedIn(Decl *D, bool HasBody) { // An ObjCMethodDecl is never considered as "interesting" because its // implementation container always is. @@ -1674,7 +1677,7 @@ static bool isConsumerInterestedIn(Decl *D) { return Var->isFileVarDecl() && Var->isThisDeclarationADefinition() == VarDecl::Definition; if (FunctionDecl *Func = dyn_cast<FunctionDecl>(D)) - return Func->doesThisDeclarationHaveABody(); + return Func->doesThisDeclarationHaveABody() || HasBody; return false; } @@ -2162,7 +2165,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { // 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 (isConsumerInterestedIn(D, Reader.hasPendingBody())) InterestingDecls.push_back(D); return D; |