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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116507 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 9ee8183..23f2eaa 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -903,8 +903,8 @@
return true;
}
- Info.LexicalDecls = reinterpret_cast<const DeclID*>(Blob);
- Info.NumLexicalDecls = BlobLen / sizeof(DeclID);
+ Info.LexicalDecls = reinterpret_cast<const KindDeclIDPair*>(Blob);
+ Info.NumLexicalDecls = BlobLen / sizeof(KindDeclIDPair);
} else {
Info.LexicalDecls = 0;
Info.NumLexicalDecls = 0;
@@ -1778,8 +1778,8 @@
case TU_UPDATE_LEXICAL: {
DeclContextInfo Info = {
/* No visible information */ 0,
- reinterpret_cast<const DeclID *>(BlobStart),
- BlobLen / sizeof(DeclID)
+ reinterpret_cast<const KindDeclIDPair *>(BlobStart),
+ BlobLen / sizeof(KindDeclIDPair)
};
DeclContextOffsets[Context ? Context->getTranslationUnitDecl() : 0]
.push_back(Info);
@@ -3242,6 +3242,7 @@
}
bool ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
+ bool (*isKindWeWant)(Decl::Kind),
llvm::SmallVectorImpl<Decl*> &Decls) {
assert(DC->hasExternalLexicalStorage() &&
"DeclContext has no lexical decls in storage");
@@ -3258,9 +3259,12 @@
continue;
// Load all of the declaration IDs
- for (const DeclID *ID = I->LexicalDecls, *IDE = ID + I->NumLexicalDecls;
- ID != IDE; ++ID) {
- Decl *D = GetDecl(*ID);
+ for (const KindDeclIDPair *ID = I->LexicalDecls,
+ *IDE = ID + I->NumLexicalDecls; ID != IDE; ++ID) {
+ if (isKindWeWant && !isKindWeWant((Decl::Kind)ID->first))
+ continue;
+
+ Decl *D = GetDecl(ID->second);
assert(D && "Null decl in lexical decls");
Decls.push_back(D);
}