Lazily load the next friend in the chain of FriendDecls, to eliminate

some excessive recursion and deserialization.

llvm-svn: 117480
This commit is contained in:
Douglas Gregor 2010-10-27 20:23:41 +00:00
parent 5701585780
commit e0fb32c261
3 changed files with 11 additions and 6 deletions

View File

@ -43,7 +43,7 @@ private:
FriendUnion Friend;
// A pointer to the next friend in the sequence.
FriendDecl *NextFriend;
LazyDeclPtr NextFriend;
// Location of the 'friend' specifier.
SourceLocation FriendLoc;
@ -60,14 +60,19 @@ private:
SourceLocation FriendL)
: Decl(Decl::Friend, DC, L),
Friend(Friend),
NextFriend(0),
NextFriend(),
FriendLoc(FriendL),
UnsupportedFriend(false) {
}
explicit FriendDecl(EmptyShell Empty)
: Decl(Decl::Friend, Empty), NextFriend(0) { }
: Decl(Decl::Friend, Empty), NextFriend() { }
FriendDecl *getNextFriend() {
return cast_or_null<FriendDecl>(
NextFriend.get(getASTContext().getExternalSource()));
}
public:
static FriendDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, FriendUnion Friend_,
@ -129,7 +134,7 @@ public:
friend_iterator &operator++() {
assert(Ptr && "attempt to increment past end of friend list");
Ptr = Ptr->NextFriend;
Ptr = Ptr->getNextFriend();
return *this;
}

View File

@ -933,7 +933,7 @@ void ASTDeclReader::VisitFriendDecl(FriendDecl *D) {
D->Friend = GetTypeSourceInfo(Record, Idx);
else
D->Friend = cast<NamedDecl>(Reader.GetDecl(Record[Idx++]));
D->NextFriend = cast_or_null<FriendDecl>(Reader.GetDecl(Record[Idx++]));
D->NextFriend = Record[Idx++];
D->UnsupportedFriend = (Record[Idx++] != 0);
D->FriendLoc = ReadSourceLocation(Record, Idx);
}

View File

@ -803,7 +803,7 @@ void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) {
Writer.AddTypeSourceInfo(D->Friend.get<TypeSourceInfo*>(), Record);
else
Writer.AddDeclRef(D->Friend.get<NamedDecl*>(), Record);
Writer.AddDeclRef(D->NextFriend, Record);
Writer.AddDeclRef(D->getNextFriend(), Record);
Record.push_back(D->UnsupportedFriend);
Writer.AddSourceLocation(D->FriendLoc, Record);
Code = serialization::DECL_FRIEND;