1205219Srdivacky//===--- DeclFriend.cpp - C++ Friend Declaration AST Node Implementation --===// 2205219Srdivacky// 3205219Srdivacky// The LLVM Compiler Infrastructure 4205219Srdivacky// 5205219Srdivacky// This file is distributed under the University of Illinois Open Source 6205219Srdivacky// License. See LICENSE.TXT for details. 7205219Srdivacky// 8205219Srdivacky//===----------------------------------------------------------------------===// 9205219Srdivacky// 10205219Srdivacky// This file implements the AST classes related to C++ friend 11205219Srdivacky// declarations. 12205219Srdivacky// 13205219Srdivacky//===----------------------------------------------------------------------===// 14205219Srdivacky 15245431Sdim#include "clang/AST/ASTContext.h" 16205219Srdivacky#include "clang/AST/DeclFriend.h" 17205219Srdivacky#include "clang/AST/DeclTemplate.h" 18205219Srdivackyusing namespace clang; 19205219Srdivacky 20235633Sdimvoid FriendDecl::anchor() { } 21235633Sdim 22245431SdimFriendDecl *FriendDecl::getNextFriendSlowCase() { 23245431Sdim return cast_or_null<FriendDecl>( 24245431Sdim NextFriend.get(getASTContext().getExternalSource())); 25245431Sdim} 26245431Sdim 27205219SrdivackyFriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC, 28205219Srdivacky SourceLocation L, 29205219Srdivacky FriendUnion Friend, 30252723Sdim SourceLocation FriendL, 31252723Sdim ArrayRef<TemplateParameterList*> FriendTypeTPLists) { 32205219Srdivacky#ifndef NDEBUG 33205219Srdivacky if (Friend.is<NamedDecl*>()) { 34205219Srdivacky NamedDecl *D = Friend.get<NamedDecl*>(); 35205219Srdivacky assert(isa<FunctionDecl>(D) || 36205219Srdivacky isa<CXXRecordDecl>(D) || 37205219Srdivacky isa<FunctionTemplateDecl>(D) || 38205219Srdivacky isa<ClassTemplateDecl>(D)); 39205219Srdivacky 40205219Srdivacky // As a temporary hack, we permit template instantiation to point 41205219Srdivacky // to the original declaration when instantiating members. 42205219Srdivacky assert(D->getFriendObjectKind() || 43205219Srdivacky (cast<CXXRecordDecl>(DC)->getTemplateSpecializationKind())); 44252723Sdim // These template parameters are for friend types only. 45252723Sdim assert(FriendTypeTPLists.size() == 0); 46205219Srdivacky } 47205219Srdivacky#endif 48205219Srdivacky 49252723Sdim std::size_t Size = sizeof(FriendDecl) 50252723Sdim + FriendTypeTPLists.size() * sizeof(TemplateParameterList*); 51252723Sdim void *Mem = C.Allocate(Size); 52252723Sdim FriendDecl *FD = new (Mem) FriendDecl(DC, L, Friend, FriendL, 53252723Sdim FriendTypeTPLists); 54205219Srdivacky cast<CXXRecordDecl>(DC)->pushFriendDecl(FD); 55205219Srdivacky return FD; 56205219Srdivacky} 57210299Sed 58252723SdimFriendDecl *FriendDecl::CreateDeserialized(ASTContext &C, unsigned ID, 59252723Sdim unsigned FriendTypeNumTPLists) { 60252723Sdim std::size_t Size = sizeof(FriendDecl) 61252723Sdim + FriendTypeNumTPLists * sizeof(TemplateParameterList*); 62252723Sdim void *Mem = AllocateDeserializedDecl(C, ID, Size); 63252723Sdim return new (Mem) FriendDecl(EmptyShell(), FriendTypeNumTPLists); 64210299Sed} 65252723Sdim 66263509SdimFriendDecl *CXXRecordDecl::getFirstFriend() const { 67263509Sdim ExternalASTSource *Source = getParentASTContext().getExternalSource(); 68263509Sdim Decl *First = data().FirstFriend.get(Source); 69263509Sdim return First ? cast<FriendDecl>(First) : 0; 70263509Sdim} 71