diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-14 20:14:34 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-14 20:14:34 +0000 |
commit | 0e88a565c0978bb6fd835a33e8069135661a1400 (patch) | |
tree | 6dfc7d7a5d72ed59d2c1a71df07dba8d313be476 /clang/lib/AST/DeclBase.cpp | |
parent | 55d1fc2d3cd17aa7fdb1a6309613a7b8d91137cf (diff) | |
download | bcm5719-llvm-0e88a565c0978bb6fd835a33e8069135661a1400.tar.gz bcm5719-llvm-0e88a565c0978bb6fd835a33e8069135661a1400.zip |
Allow deserialization of just the fields of a record, when we want to iterate over them,
instead of deserializing the complete declaration context of the record.
Iterating over the fields of a record is very common (e.g to determine the layout), unfortunately we needlessly deserialize every declaration
that the declaration context of the record contains; this can be bad for large C++ classes that contain a lot of methods.
Fix this by allow deserialization of just the fields when we want to iterate over them.
Progress for rdar://7260160.
llvm-svn: 116507
Diffstat (limited to 'clang/lib/AST/DeclBase.cpp')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index ece9945390a..d60a06749d5 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -599,6 +599,24 @@ DeclContext *DeclContext::getNextContext() { } } +std::pair<Decl *, Decl *> +DeclContext::BuildDeclChain(const llvm::SmallVectorImpl<Decl*> &Decls) { + // Build up a chain of declarations via the Decl::NextDeclInContext field. + Decl *FirstNewDecl = 0; + Decl *PrevDecl = 0; + for (unsigned I = 0, N = Decls.size(); I != N; ++I) { + Decl *D = Decls[I]; + if (PrevDecl) + PrevDecl->NextDeclInContext = D; + else + FirstNewDecl = D; + + PrevDecl = D; + } + + return std::make_pair(FirstNewDecl, PrevDecl); +} + /// \brief Load the declarations within this lexical storage from an /// external source. void @@ -619,26 +637,22 @@ DeclContext::LoadLexicalDeclsFromExternalStorage() const { if (Decls.empty()) return; - // Resolve all of the declaration IDs into declarations, building up - // a chain of declarations via the Decl::NextDeclInContext field. - Decl *FirstNewDecl = 0; - Decl *PrevDecl = 0; - for (unsigned I = 0, N = Decls.size(); I != N; ++I) { - Decl *D = Decls[I]; - if (PrevDecl) - PrevDecl->NextDeclInContext = D; - else - FirstNewDecl = D; - - PrevDecl = D; - } + // We may have already loaded just the fields of this record, in which case + // don't add the decls, just replace the FirstDecl/LastDecl chain. + if (const RecordDecl *RD = dyn_cast<RecordDecl>(this)) + if (RD->LoadedFieldsFromExternalStorage) { + llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls); + return; + } // Splice the newly-read declarations into the beginning of the list // of declarations. - PrevDecl->NextDeclInContext = FirstDecl; - FirstDecl = FirstNewDecl; + Decl *ExternalFirst, *ExternalLast; + llvm::tie(ExternalFirst, ExternalLast) = BuildDeclChain(Decls); + ExternalLast->NextDeclInContext = FirstDecl; + FirstDecl = ExternalFirst; if (!LastDecl) - LastDecl = PrevDecl; + LastDecl = ExternalLast; } DeclContext::lookup_result |