summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-10-14 20:14:34 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2010-10-14 20:14:34 +0000
commit0e88a565c0978bb6fd835a33e8069135661a1400 (patch)
tree6dfc7d7a5d72ed59d2c1a71df07dba8d313be476 /clang/lib/AST/Decl.cpp
parent55d1fc2d3cd17aa7fdb1a6309613a7b8d91137cf (diff)
downloadbcm5719-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.cpp33
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
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud