192b7f70c924cbf4514e9e434cea7def51ab49860John McCall//===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===// 292b7f70c924cbf4514e9e434cea7def51ab49860John McCall// 392b7f70c924cbf4514e9e434cea7def51ab49860John McCall// The LLVM Compiler Infrastructure 492b7f70c924cbf4514e9e434cea7def51ab49860John McCall// 592b7f70c924cbf4514e9e434cea7def51ab49860John McCall// This file is distributed under the University of Illinois Open Source 692b7f70c924cbf4514e9e434cea7def51ab49860John McCall// License. See LICENSE.TXT for details. 792b7f70c924cbf4514e9e434cea7def51ab49860John McCall// 892b7f70c924cbf4514e9e434cea7def51ab49860John McCall//===----------------------------------------------------------------------===// 992b7f70c924cbf4514e9e434cea7def51ab49860John McCall// 1092b7f70c924cbf4514e9e434cea7def51ab49860John McCall// This file defines the section of the AST representing C++ friend 1192b7f70c924cbf4514e9e434cea7def51ab49860John McCall// declarations. 1292b7f70c924cbf4514e9e434cea7def51ab49860John McCall// 1392b7f70c924cbf4514e9e434cea7def51ab49860John McCall//===----------------------------------------------------------------------===// 1492b7f70c924cbf4514e9e434cea7def51ab49860John McCall 1592b7f70c924cbf4514e9e434cea7def51ab49860John McCall#ifndef LLVM_CLANG_AST_DECLFRIEND_H 1692b7f70c924cbf4514e9e434cea7def51ab49860John McCall#define LLVM_CLANG_AST_DECLFRIEND_H 1792b7f70c924cbf4514e9e434cea7def51ab49860John McCall 1892b7f70c924cbf4514e9e434cea7def51ab49860John McCall#include "clang/AST/DeclCXX.h" 19aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar#include "llvm/Support/Compiler.h" 2092b7f70c924cbf4514e9e434cea7def51ab49860John McCall 2192b7f70c924cbf4514e9e434cea7def51ab49860John McCallnamespace clang { 2292b7f70c924cbf4514e9e434cea7def51ab49860John McCall 2392b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// FriendDecl - Represents the declaration of a friend entity, 2492b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// which can be a function, a type, or a templated function or type. 2592b7f70c924cbf4514e9e434cea7def51ab49860John McCall// For example: 2692b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// 2792b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// @code 2892b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// template <typename T> class A { 2992b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// friend int foo(T); 3092b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// friend class B; 3192b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// friend T; // only in C++0x 3292b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// template <typename U> friend class C; 3392b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// template <typename U> friend A& operator+=(A&, const U&) { ... } 3492b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// }; 3592b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// @endcode 3692b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// 3792b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// The semantic context of a friend decl is its declaring class. 3892b7f70c924cbf4514e9e434cea7def51ab49860John McCallclass FriendDecl : public Decl { 3999ba9e3bd70671f3441fb974895f226a83ce0e66David Blaikie virtual void anchor(); 4092b7f70c924cbf4514e9e434cea7def51ab49860John McCallpublic: 4132f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; 4292b7f70c924cbf4514e9e434cea7def51ab49860John McCall 4392b7f70c924cbf4514e9e434cea7def51ab49860John McCallprivate: 4492b7f70c924cbf4514e9e434cea7def51ab49860John McCall // The declaration that's a friend of this class. 4592b7f70c924cbf4514e9e434cea7def51ab49860John McCall FriendUnion Friend; 4692b7f70c924cbf4514e9e434cea7def51ab49860John McCall 47d60e22e601852ae1345f01514318a0951dc09f89John McCall // A pointer to the next friend in the sequence. 4869aecc6252bf4a5ee59f9b51c3728ea07b6342bfDouglas Gregor LazyDeclPtr NextFriend; 49d60e22e601852ae1345f01514318a0951dc09f89John McCall 5092b7f70c924cbf4514e9e434cea7def51ab49860John McCall // Location of the 'friend' specifier. 5192b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation FriendLoc; 5292b7f70c924cbf4514e9e434cea7def51ab49860John McCall 536102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall /// True if this 'friend' declaration is unsupported. Eventually we 546102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall /// will support every possible friend declaration, but for now we 556102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall /// silently ignore some and set this flag to authorize all access. 566102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall bool UnsupportedFriend; 576102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall 58d60e22e601852ae1345f01514318a0951dc09f89John McCall friend class CXXRecordDecl::friend_iterator; 59d60e22e601852ae1345f01514318a0951dc09f89John McCall friend class CXXRecordDecl; 60d60e22e601852ae1345f01514318a0951dc09f89John McCall 6192b7f70c924cbf4514e9e434cea7def51ab49860John McCall FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, 6292b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation FriendL) 6392b7f70c924cbf4514e9e434cea7def51ab49860John McCall : Decl(Decl::Friend, DC, L), 6492b7f70c924cbf4514e9e434cea7def51ab49860John McCall Friend(Friend), 6569aecc6252bf4a5ee59f9b51c3728ea07b6342bfDouglas Gregor NextFriend(), 666102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall FriendLoc(FriendL), 676102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall UnsupportedFriend(false) { 6892b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 6992b7f70c924cbf4514e9e434cea7def51ab49860John McCall 700ab5de16a47d64ba7cc8ca2e31b679daeae963feArgyrios Kyrtzidis explicit FriendDecl(EmptyShell Empty) 7169aecc6252bf4a5ee59f9b51c3728ea07b6342bfDouglas Gregor : Decl(Decl::Friend, Empty), NextFriend() { } 726764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis 7369aecc6252bf4a5ee59f9b51c3728ea07b6342bfDouglas Gregor FriendDecl *getNextFriend() { 74471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer if (!NextFriend.isOffset()) 75471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer return cast_or_null<FriendDecl>(NextFriend.get(0)); 76471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer return getNextFriendSlowCase(); 7769aecc6252bf4a5ee59f9b51c3728ea07b6342bfDouglas Gregor } 78471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer FriendDecl *getNextFriendSlowCase(); 79471c8b49982d1132f30b0b0da27fef94fd6e4f67Benjamin Kramer 8092b7f70c924cbf4514e9e434cea7def51ab49860John McCallpublic: 8192b7f70c924cbf4514e9e434cea7def51ab49860John McCall static FriendDecl *Create(ASTContext &C, DeclContext *DC, 8292b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation L, FriendUnion Friend_, 8392b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation FriendL); 841e68ecc4fcce12f683c4fd38acfd1a004001b04fDouglas Gregor static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID); 8592b7f70c924cbf4514e9e434cea7def51ab49860John McCall 86710672485039d3dd355748876299fff88e8ad84cCraig Silverstein /// If this friend declaration names an (untemplated but possibly 87710672485039d3dd355748876299fff88e8ad84cCraig Silverstein /// dependent) type, return the type; otherwise return null. This 88710672485039d3dd355748876299fff88e8ad84cCraig Silverstein /// is used for elaborated-type-specifiers and, in C++0x, for 89710672485039d3dd355748876299fff88e8ad84cCraig Silverstein /// arbitrary friend type declarations. 9032f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall TypeSourceInfo *getFriendType() const { 9132f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall return Friend.dyn_cast<TypeSourceInfo*>(); 9292b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 9392b7f70c924cbf4514e9e434cea7def51ab49860John McCall 94710672485039d3dd355748876299fff88e8ad84cCraig Silverstein /// If this friend declaration doesn't name a type, return the inner 95710672485039d3dd355748876299fff88e8ad84cCraig Silverstein /// declaration. 9692b7f70c924cbf4514e9e434cea7def51ab49860John McCall NamedDecl *getFriendDecl() const { 9792b7f70c924cbf4514e9e434cea7def51ab49860John McCall return Friend.dyn_cast<NamedDecl*>(); 9892b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 9992b7f70c924cbf4514e9e434cea7def51ab49860John McCall 10092b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// Retrieves the location of the 'friend' keyword. 10192b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation getFriendLoc() const { 10292b7f70c924cbf4514e9e434cea7def51ab49860John McCall return FriendLoc; 10392b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 10492b7f70c924cbf4514e9e434cea7def51ab49860John McCall 1058fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara /// Retrieves the source range for the friend declaration. 106aa49a7d70e58dac2aeb40664ba16d2ea571b8c95Daniel Dunbar SourceRange getSourceRange() const LLVM_READONLY { 1078fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara /* FIXME: consider the case of templates wrt start of range. */ 1088fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara if (NamedDecl *ND = getFriendDecl()) 1098fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara return SourceRange(getFriendLoc(), ND->getLocEnd()); 1108fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara else if (TypeSourceInfo *TInfo = getFriendType()) 1118fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc()); 1128fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara else 1138fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara return SourceRange(getFriendLoc(), getLocation()); 1148fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara } 1158fbb7628e9fc364bbfb65bdf2c2468b0d06a7e5bAbramo Bagnara 1166102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall /// Determines if this friend kind is unsupported. 1176102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall bool isUnsupportedFriend() const { 1186102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall return UnsupportedFriend; 1196102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall } 1206102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall void setUnsupportedFriend(bool Unsupported) { 1216102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall UnsupportedFriend = Unsupported; 1226102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall } 1236102ca1d490836096678d7d934f0b2b78f9293ecJohn McCall 12492b7f70c924cbf4514e9e434cea7def51ab49860John McCall // Implement isa/cast/dyncast/etc. 12592b7f70c924cbf4514e9e434cea7def51ab49860John McCall static bool classof(const Decl *D) { return classofKind(D->getKind()); } 12692b7f70c924cbf4514e9e434cea7def51ab49860John McCall static bool classof(const FriendDecl *D) { return true; } 12792b7f70c924cbf4514e9e434cea7def51ab49860John McCall static bool classofKind(Kind K) { return K == Decl::Friend; } 1286764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis 129d527cc06d78fe5afa5f20105b51697637eb02c56Sebastian Redl friend class ASTDeclReader; 1303397c5570369f19b2d6c52e898f708d75ceede1fSebastian Redl friend class ASTDeclWriter; 13192b7f70c924cbf4514e9e434cea7def51ab49860John McCall}; 132d60e22e601852ae1345f01514318a0951dc09f89John McCall 133d60e22e601852ae1345f01514318a0951dc09f89John McCall/// An iterator over the friend declarations of a class. 134d60e22e601852ae1345f01514318a0951dc09f89John McCallclass CXXRecordDecl::friend_iterator { 135d60e22e601852ae1345f01514318a0951dc09f89John McCall FriendDecl *Ptr; 136d60e22e601852ae1345f01514318a0951dc09f89John McCall 137d60e22e601852ae1345f01514318a0951dc09f89John McCall friend class CXXRecordDecl; 138d60e22e601852ae1345f01514318a0951dc09f89John McCall explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {} 139d60e22e601852ae1345f01514318a0951dc09f89John McCallpublic: 140d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator() {} 141d60e22e601852ae1345f01514318a0951dc09f89John McCall 142d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef FriendDecl *value_type; 143d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef FriendDecl *reference; 144d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef FriendDecl *pointer; 145d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef int difference_type; 146d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef std::forward_iterator_tag iterator_category; 147d60e22e601852ae1345f01514318a0951dc09f89John McCall 148d60e22e601852ae1345f01514318a0951dc09f89John McCall reference operator*() const { return Ptr; } 149d60e22e601852ae1345f01514318a0951dc09f89John McCall 150d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator &operator++() { 151d60e22e601852ae1345f01514318a0951dc09f89John McCall assert(Ptr && "attempt to increment past end of friend list"); 15269aecc6252bf4a5ee59f9b51c3728ea07b6342bfDouglas Gregor Ptr = Ptr->getNextFriend(); 153d60e22e601852ae1345f01514318a0951dc09f89John McCall return *this; 154d60e22e601852ae1345f01514318a0951dc09f89John McCall } 155d60e22e601852ae1345f01514318a0951dc09f89John McCall 156d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator operator++(int) { 157d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator tmp = *this; 158d60e22e601852ae1345f01514318a0951dc09f89John McCall ++*this; 159d60e22e601852ae1345f01514318a0951dc09f89John McCall return tmp; 160d60e22e601852ae1345f01514318a0951dc09f89John McCall } 161d60e22e601852ae1345f01514318a0951dc09f89John McCall 162d60e22e601852ae1345f01514318a0951dc09f89John McCall bool operator==(const friend_iterator &Other) const { 163d60e22e601852ae1345f01514318a0951dc09f89John McCall return Ptr == Other.Ptr; 164d60e22e601852ae1345f01514318a0951dc09f89John McCall } 165d60e22e601852ae1345f01514318a0951dc09f89John McCall 166d60e22e601852ae1345f01514318a0951dc09f89John McCall bool operator!=(const friend_iterator &Other) const { 167d60e22e601852ae1345f01514318a0951dc09f89John McCall return Ptr != Other.Ptr; 168d60e22e601852ae1345f01514318a0951dc09f89John McCall } 169d60e22e601852ae1345f01514318a0951dc09f89John McCall 170d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator &operator+=(difference_type N) { 171d60e22e601852ae1345f01514318a0951dc09f89John McCall assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator"); 172d60e22e601852ae1345f01514318a0951dc09f89John McCall while (N--) 173d60e22e601852ae1345f01514318a0951dc09f89John McCall ++*this; 174d60e22e601852ae1345f01514318a0951dc09f89John McCall return *this; 175d60e22e601852ae1345f01514318a0951dc09f89John McCall } 176d60e22e601852ae1345f01514318a0951dc09f89John McCall 177d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator operator+(difference_type N) const { 178d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator tmp = *this; 179d60e22e601852ae1345f01514318a0951dc09f89John McCall tmp += N; 180d60e22e601852ae1345f01514318a0951dc09f89John McCall return tmp; 181d60e22e601852ae1345f01514318a0951dc09f89John McCall } 182d60e22e601852ae1345f01514318a0951dc09f89John McCall}; 183d60e22e601852ae1345f01514318a0951dc09f89John McCall 184d60e22e601852ae1345f01514318a0951dc09f89John McCallinline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const { 185d60e22e601852ae1345f01514318a0951dc09f89John McCall return friend_iterator(data().FirstFriend); 186d60e22e601852ae1345f01514318a0951dc09f89John McCall} 187d60e22e601852ae1345f01514318a0951dc09f89John McCall 188d60e22e601852ae1345f01514318a0951dc09f89John McCallinline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { 189d60e22e601852ae1345f01514318a0951dc09f89John McCall return friend_iterator(0); 190d60e22e601852ae1345f01514318a0951dc09f89John McCall} 191d60e22e601852ae1345f01514318a0951dc09f89John McCall 192d60e22e601852ae1345f01514318a0951dc09f89John McCallinline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { 193d60e22e601852ae1345f01514318a0951dc09f89John McCall assert(FD->NextFriend == 0 && "friend already has next friend?"); 194d60e22e601852ae1345f01514318a0951dc09f89John McCall FD->NextFriend = data().FirstFriend; 195d60e22e601852ae1345f01514318a0951dc09f89John McCall data().FirstFriend = FD; 196d60e22e601852ae1345f01514318a0951dc09f89John McCall} 19792b7f70c924cbf4514e9e434cea7def51ab49860John McCall 19892b7f70c924cbf4514e9e434cea7def51ab49860John McCall} 19992b7f70c924cbf4514e9e434cea7def51ab49860John McCall 20092b7f70c924cbf4514e9e434cea7def51ab49860John McCall#endif 201