diff options
author | Enea Zaffanella <zaffanella@cs.unipr.it> | 2013-01-31 09:54:08 +0000 |
---|---|---|
committer | Enea Zaffanella <zaffanella@cs.unipr.it> | 2013-01-31 09:54:08 +0000 |
commit | 8c84028ed9aa0dfd54ab729dee78f29c961d7f37 (patch) | |
tree | 03c0bbdc540d71e409b0308b448510e17ab935e8 /lib | |
parent | a8d3904ffa613406ffacec5662c782c9269e5241 (diff) |
Added outer template parameter lists to friend type AST nodes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174050 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/DeclFriend.cpp | 21 | ||||
-rw-r--r-- | lib/AST/DeclPrinter.cpp | 9 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 15 |
5 files changed, 43 insertions, 19 deletions
diff --git a/lib/AST/DeclFriend.cpp b/lib/AST/DeclFriend.cpp index 553d170fc3..37a812e71a 100644 --- a/lib/AST/DeclFriend.cpp +++ b/lib/AST/DeclFriend.cpp @@ -27,7 +27,8 @@ FriendDecl *FriendDecl::getNextFriendSlowCase() { FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend, - SourceLocation FriendL) { + SourceLocation FriendL, + ArrayRef<TemplateParameterList*> FriendTypeTPLists) { #ifndef NDEBUG if (Friend.is<NamedDecl*>()) { NamedDecl *D = Friend.get<NamedDecl*>(); @@ -40,15 +41,25 @@ FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, // to the original declaration when instantiating members. assert(D->getFriendObjectKind() || (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind())); + // These template parameters are for friend types only. + assert(FriendTypeTPLists.size() == 0); } #endif - FriendDecl *FD = new (C) FriendDecl(DC, L, Friend, FriendL); + std::size_t Size = sizeof(FriendDecl) + + FriendTypeTPLists.size() * sizeof(TemplateParameterList*); + void *Mem = C.Allocate(Size); + FriendDecl *FD = new (Mem) FriendDecl(DC, L, Friend, FriendL, + FriendTypeTPLists); cast<CXXRecordDecl>(DC)->pushFriendDecl(FD); return FD; } -FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID) { - void *Mem = AllocateDeserializedDecl(C, ID, sizeof(FriendDecl)); - return new (Mem) FriendDecl(EmptyShell()); +FriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID, + unsigned FriendTypeNumTPLists) { + std::size_t Size = sizeof(FriendDecl) + + FriendTypeNumTPLists * sizeof(TemplateParameterList*); + void *Mem = AllocateDeserializedDecl(C, ID, Size); + return new (Mem) FriendDecl(EmptyShell(), FriendTypeNumTPLists); } + diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp index 6057f60136..f863bb49d5 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -83,7 +83,7 @@ namespace { void VisitUsingShadowDecl(UsingShadowDecl *D); void PrintTemplateParameters(const TemplateParameterList *Params, - const TemplateArgumentList *Args); + const TemplateArgumentList *Args = 0); void prettyPrintAttributes(Decl *D); }; } @@ -580,6 +580,9 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { void DeclPrinter::VisitFriendDecl(FriendDecl *D) { if (TypeSourceInfo *TSI = D->getFriendType()) { + unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists(); + for (unsigned i = 0; i < NumTPLists; ++i) + PrintTemplateParameters(D->getFriendTypeTemplateParameterList(i)); Out << "friend "; Out << " " << TSI->getType().getAsString(Policy); } @@ -771,8 +774,8 @@ void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { Visit(*D->decls_begin()); } -void DeclPrinter::PrintTemplateParameters( - const TemplateParameterList *Params, const TemplateArgumentList *Args = 0) { +void DeclPrinter::PrintTemplateParameters(const TemplateParameterList *Params, + const TemplateArgumentList *Args) { assert(Params); assert(!Args || Params->size() == Args->size()); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index c0697f117c..9ef91467da 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -10347,7 +10347,8 @@ FriendDecl *Sema::CheckFriendTypeDecl(SourceLocation LocStart, Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, - IdentifierInfo *Name, SourceLocation NameLoc, + IdentifierInfo *Name, + SourceLocation NameLoc, AttributeList *Attr, MultiTemplateParamsArg TempParamLists) { TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); @@ -10431,7 +10432,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, } FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc, - TSI, FriendLoc); + TSI, FriendLoc, TempParamLists); Friend->setAccess(AS_public); CurContext->addDecl(Friend); return Friend; @@ -10453,7 +10454,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, TL.setNameLoc(NameLoc); FriendDecl *Friend = FriendDecl::Create(Context, CurContext, NameLoc, - TSI, FriendLoc); + TSI, FriendLoc, TempParamLists); Friend->setAccess(AS_public); Friend->setUnsupportedFriend(true); CurContext->addDecl(Friend); diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 5fe1011579..469b3938ee 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1262,10 +1262,12 @@ void ASTDeclReader::VisitAccessSpecDecl(AccessSpecDecl *D) { void ASTDeclReader::VisitFriendDecl(FriendDecl *D) { VisitDecl(D); - if (Record[Idx++]) - D->Friend = GetTypeSourceInfo(Record, Idx); - else + if (Record[Idx++]) // hasFriendDecl D->Friend = ReadDeclAs<NamedDecl>(Record, Idx); + else + D->Friend = GetTypeSourceInfo(Record, Idx); + for (unsigned i = 0; i != D->NumTPLists; ++i) + D->getTPLists()[i] = Reader.ReadTemplateParameterList(F, Record, Idx); D->NextFriend = Record[Idx++]; D->UnsupportedFriend = (Record[Idx++] != 0); D->FriendLoc = ReadSourceLocation(Record, Idx); @@ -2003,7 +2005,7 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { D = AccessSpecDecl::CreateDeserialized(Context, ID); break; case DECL_FRIEND: - D = FriendDecl::CreateDeserialized(Context, ID); + D = FriendDecl::CreateDeserialized(Context, ID, Record[Idx++]); break; case DECL_FRIEND_TEMPLATE: D = FriendTemplateDecl::CreateDeserialized(Context, ID); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 7be49a283f..c2e1513586 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -1017,12 +1017,19 @@ void ASTDeclWriter::VisitAccessSpecDecl(AccessSpecDecl *D) { } void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) { + // Record the number of friend type template parameter lists here + // so as to simplify memory allocation during deserialization. + Record.push_back(D->NumTPLists); VisitDecl(D); - Record.push_back(D->Friend.is<TypeSourceInfo*>()); - if (D->Friend.is<TypeSourceInfo*>()) - Writer.AddTypeSourceInfo(D->Friend.get<TypeSourceInfo*>(), Record); + bool hasFriendDecl = D->Friend.is<NamedDecl*>(); + Record.push_back(hasFriendDecl); + if (hasFriendDecl) + Writer.AddDeclRef(D->getFriendDecl(), Record); else - Writer.AddDeclRef(D->Friend.get<NamedDecl*>(), Record); + Writer.AddTypeSourceInfo(D->getFriendType(), Record); + for (unsigned i = 0; i < D->NumTPLists; ++i) + Writer.AddTemplateParameterList(D->getFriendTypeTemplateParameterList(i), + Record); Writer.AddDeclRef(D->getNextFriend(), Record); Record.push_back(D->UnsupportedFriend); Writer.AddSourceLocation(D->FriendLoc, Record); |