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/Decl.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/Decl.cpp')
| -rw-r--r-- | clang/lib/AST/Decl.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index f4554730595..e822009c580 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -1651,6 +1651,7 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, HasFlexibleArrayMember = false; AnonymousStructOrUnion = false; HasObjectMember = false; + LoadedFieldsFromExternalStorage = false; assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!"); } @@ -1673,6 +1674,13 @@ bool RecordDecl::isInjectedClassName() const { cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName(); } +RecordDecl::field_iterator RecordDecl::field_begin() const { + if (hasExternalLexicalStorage() && !LoadedFieldsFromExternalStorage) + LoadFieldsFromExternalStorage(); + + return field_iterator(decl_iterator(FirstDecl)); +} + /// completeDefinition - Notes that the definition of this type is now /// complete. void RecordDecl::completeDefinition() { @@ -1691,6 +1699,31 @@ ValueDecl *RecordDecl::getAnonymousStructOrUnionObject() { return D; } +void RecordDecl::LoadFieldsFromExternalStorage() const { + ExternalASTSource *Source = getASTContext().getExternalSource(); + assert(hasExternalLexicalStorage() && Source && "No external storage?"); + + // Notify that we have a RecordDecl doing some initialization. + ExternalASTSource::Deserializing TheFields(Source); + + llvm::SmallVector<Decl*, 64> Decls; + if (Source->FindExternalLexicalDeclsBy<FieldDecl>(this, Decls)) + return; + +#ifndef NDEBUG + // Check that all decls we got were FieldDecls. + for (unsigned i=0, e=Decls.size(); i != e; ++i) + assert(isa<FieldDecl>(Decls[i])); +#endif + + LoadedFieldsFromExternalStorage = true; + + if (Decls.empty()) + return; + + llvm::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls); +} + //===----------------------------------------------------------------------===// // BlockDecl Implementation //===----------------------------------------------------------------------===// |

