DeclFriend.h revision 6764334dfa73d67cbbb1b1fc8fe00440aad00f2a
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" 1992b7f70c924cbf4514e9e434cea7def51ab49860John McCall 2092b7f70c924cbf4514e9e434cea7def51ab49860John McCallnamespace clang { 2192b7f70c924cbf4514e9e434cea7def51ab49860John McCall 2292b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// FriendDecl - Represents the declaration of a friend entity, 2392b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// which can be a function, a type, or a templated function or type. 2492b7f70c924cbf4514e9e434cea7def51ab49860John McCall// For example: 2592b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// 2692b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// @code 2792b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// template <typename T> class A { 2892b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// friend int foo(T); 2992b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// friend class B; 3092b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// friend T; // only in C++0x 3192b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// template <typename U> friend class C; 3292b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// template <typename U> friend A& operator+=(A&, const U&) { ... } 3392b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// }; 3492b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// @endcode 3592b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// 3692b7f70c924cbf4514e9e434cea7def51ab49860John McCall/// The semantic context of a friend decl is its declaring class. 3792b7f70c924cbf4514e9e434cea7def51ab49860John McCallclass FriendDecl : public Decl { 3892b7f70c924cbf4514e9e434cea7def51ab49860John McCallpublic: 3932f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; 4092b7f70c924cbf4514e9e434cea7def51ab49860John McCall 4192b7f70c924cbf4514e9e434cea7def51ab49860John McCallprivate: 4292b7f70c924cbf4514e9e434cea7def51ab49860John McCall // The declaration that's a friend of this class. 4392b7f70c924cbf4514e9e434cea7def51ab49860John McCall FriendUnion Friend; 4492b7f70c924cbf4514e9e434cea7def51ab49860John McCall 45d60e22e601852ae1345f01514318a0951dc09f89John McCall // A pointer to the next friend in the sequence. 46d60e22e601852ae1345f01514318a0951dc09f89John McCall FriendDecl *NextFriend; 47d60e22e601852ae1345f01514318a0951dc09f89John McCall 4892b7f70c924cbf4514e9e434cea7def51ab49860John McCall // Location of the 'friend' specifier. 4992b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation FriendLoc; 5092b7f70c924cbf4514e9e434cea7def51ab49860John McCall 51d60e22e601852ae1345f01514318a0951dc09f89John McCall friend class CXXRecordDecl::friend_iterator; 52d60e22e601852ae1345f01514318a0951dc09f89John McCall friend class CXXRecordDecl; 53d60e22e601852ae1345f01514318a0951dc09f89John McCall 5492b7f70c924cbf4514e9e434cea7def51ab49860John McCall FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, 5592b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation FriendL) 5692b7f70c924cbf4514e9e434cea7def51ab49860John McCall : Decl(Decl::Friend, DC, L), 5792b7f70c924cbf4514e9e434cea7def51ab49860John McCall Friend(Friend), 58d60e22e601852ae1345f01514318a0951dc09f89John McCall NextFriend(0), 59af2094e7cecadf36667deb61a83587ffdd979bd3John McCall FriendLoc(FriendL) { 6092b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 6192b7f70c924cbf4514e9e434cea7def51ab49860John McCall 626764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis FriendDecl(EmptyShell Empty) : Decl(Decl::Friend, Empty), NextFriend(0) { } 636764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis 6492b7f70c924cbf4514e9e434cea7def51ab49860John McCallpublic: 6592b7f70c924cbf4514e9e434cea7def51ab49860John McCall static FriendDecl *Create(ASTContext &C, DeclContext *DC, 6692b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation L, FriendUnion Friend_, 6792b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation FriendL); 686764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis static FriendDecl *Create(ASTContext &C, EmptyShell Empty); 6992b7f70c924cbf4514e9e434cea7def51ab49860John McCall 7092b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// If this friend declaration names an (untemplated but 7192b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// possibly dependent) type, return the type; otherwise 7292b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// return null. This is used only for C++0x's unelaborated 7392b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// friend type declarations. 7432f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall TypeSourceInfo *getFriendType() const { 7532f2fb53d9d7c28c94d8569fd0fcf06cccee0c3dJohn McCall return Friend.dyn_cast<TypeSourceInfo*>(); 7692b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 7792b7f70c924cbf4514e9e434cea7def51ab49860John McCall 7892b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// If this friend declaration doesn't name an unelaborated 7992b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// type, return the inner declaration. 8092b7f70c924cbf4514e9e434cea7def51ab49860John McCall NamedDecl *getFriendDecl() const { 8192b7f70c924cbf4514e9e434cea7def51ab49860John McCall return Friend.dyn_cast<NamedDecl*>(); 8292b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 8392b7f70c924cbf4514e9e434cea7def51ab49860John McCall 8492b7f70c924cbf4514e9e434cea7def51ab49860John McCall /// Retrieves the location of the 'friend' keyword. 8592b7f70c924cbf4514e9e434cea7def51ab49860John McCall SourceLocation getFriendLoc() const { 8692b7f70c924cbf4514e9e434cea7def51ab49860John McCall return FriendLoc; 8792b7f70c924cbf4514e9e434cea7def51ab49860John McCall } 8892b7f70c924cbf4514e9e434cea7def51ab49860John McCall 8992b7f70c924cbf4514e9e434cea7def51ab49860John McCall // Implement isa/cast/dyncast/etc. 9092b7f70c924cbf4514e9e434cea7def51ab49860John McCall static bool classof(const Decl *D) { return classofKind(D->getKind()); } 9192b7f70c924cbf4514e9e434cea7def51ab49860John McCall static bool classof(const FriendDecl *D) { return true; } 9292b7f70c924cbf4514e9e434cea7def51ab49860John McCall static bool classofKind(Kind K) { return K == Decl::Friend; } 936764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis 946764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis friend class PCHDeclReader; 956764334dfa73d67cbbb1b1fc8fe00440aad00f2aArgyrios Kyrtzidis friend class PCHDeclWriter; 9692b7f70c924cbf4514e9e434cea7def51ab49860John McCall}; 97d60e22e601852ae1345f01514318a0951dc09f89John McCall 98d60e22e601852ae1345f01514318a0951dc09f89John McCall/// An iterator over the friend declarations of a class. 99d60e22e601852ae1345f01514318a0951dc09f89John McCallclass CXXRecordDecl::friend_iterator { 100d60e22e601852ae1345f01514318a0951dc09f89John McCall FriendDecl *Ptr; 101d60e22e601852ae1345f01514318a0951dc09f89John McCall 102d60e22e601852ae1345f01514318a0951dc09f89John McCall friend class CXXRecordDecl; 103d60e22e601852ae1345f01514318a0951dc09f89John McCall explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {} 104d60e22e601852ae1345f01514318a0951dc09f89John McCallpublic: 105d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator() {} 106d60e22e601852ae1345f01514318a0951dc09f89John McCall 107d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef FriendDecl *value_type; 108d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef FriendDecl *reference; 109d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef FriendDecl *pointer; 110d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef int difference_type; 111d60e22e601852ae1345f01514318a0951dc09f89John McCall typedef std::forward_iterator_tag iterator_category; 112d60e22e601852ae1345f01514318a0951dc09f89John McCall 113d60e22e601852ae1345f01514318a0951dc09f89John McCall reference operator*() const { return Ptr; } 114d60e22e601852ae1345f01514318a0951dc09f89John McCall 115d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator &operator++() { 116d60e22e601852ae1345f01514318a0951dc09f89John McCall assert(Ptr && "attempt to increment past end of friend list"); 117d60e22e601852ae1345f01514318a0951dc09f89John McCall Ptr = Ptr->NextFriend; 118d60e22e601852ae1345f01514318a0951dc09f89John McCall return *this; 119d60e22e601852ae1345f01514318a0951dc09f89John McCall } 120d60e22e601852ae1345f01514318a0951dc09f89John McCall 121d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator operator++(int) { 122d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator tmp = *this; 123d60e22e601852ae1345f01514318a0951dc09f89John McCall ++*this; 124d60e22e601852ae1345f01514318a0951dc09f89John McCall return tmp; 125d60e22e601852ae1345f01514318a0951dc09f89John McCall } 126d60e22e601852ae1345f01514318a0951dc09f89John McCall 127d60e22e601852ae1345f01514318a0951dc09f89John McCall bool operator==(const friend_iterator &Other) const { 128d60e22e601852ae1345f01514318a0951dc09f89John McCall return Ptr == Other.Ptr; 129d60e22e601852ae1345f01514318a0951dc09f89John McCall } 130d60e22e601852ae1345f01514318a0951dc09f89John McCall 131d60e22e601852ae1345f01514318a0951dc09f89John McCall bool operator!=(const friend_iterator &Other) const { 132d60e22e601852ae1345f01514318a0951dc09f89John McCall return Ptr != Other.Ptr; 133d60e22e601852ae1345f01514318a0951dc09f89John McCall } 134d60e22e601852ae1345f01514318a0951dc09f89John McCall 135d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator &operator+=(difference_type N) { 136d60e22e601852ae1345f01514318a0951dc09f89John McCall assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator"); 137d60e22e601852ae1345f01514318a0951dc09f89John McCall while (N--) 138d60e22e601852ae1345f01514318a0951dc09f89John McCall ++*this; 139d60e22e601852ae1345f01514318a0951dc09f89John McCall return *this; 140d60e22e601852ae1345f01514318a0951dc09f89John McCall } 141d60e22e601852ae1345f01514318a0951dc09f89John McCall 142d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator operator+(difference_type N) const { 143d60e22e601852ae1345f01514318a0951dc09f89John McCall friend_iterator tmp = *this; 144d60e22e601852ae1345f01514318a0951dc09f89John McCall tmp += N; 145d60e22e601852ae1345f01514318a0951dc09f89John McCall return tmp; 146d60e22e601852ae1345f01514318a0951dc09f89John McCall } 147d60e22e601852ae1345f01514318a0951dc09f89John McCall}; 148d60e22e601852ae1345f01514318a0951dc09f89John McCall 149d60e22e601852ae1345f01514318a0951dc09f89John McCallinline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const { 150d60e22e601852ae1345f01514318a0951dc09f89John McCall return friend_iterator(data().FirstFriend); 151d60e22e601852ae1345f01514318a0951dc09f89John McCall} 152d60e22e601852ae1345f01514318a0951dc09f89John McCall 153d60e22e601852ae1345f01514318a0951dc09f89John McCallinline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const { 154d60e22e601852ae1345f01514318a0951dc09f89John McCall return friend_iterator(0); 155d60e22e601852ae1345f01514318a0951dc09f89John McCall} 156d60e22e601852ae1345f01514318a0951dc09f89John McCall 157d60e22e601852ae1345f01514318a0951dc09f89John McCallinline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { 158d60e22e601852ae1345f01514318a0951dc09f89John McCall assert(FD->NextFriend == 0 && "friend already has next friend?"); 159d60e22e601852ae1345f01514318a0951dc09f89John McCall FD->NextFriend = data().FirstFriend; 160d60e22e601852ae1345f01514318a0951dc09f89John McCall data().FirstFriend = FD; 161d60e22e601852ae1345f01514318a0951dc09f89John McCall} 16292b7f70c924cbf4514e9e434cea7def51ab49860John McCall 16392b7f70c924cbf4514e9e434cea7def51ab49860John McCall} 16492b7f70c924cbf4514e9e434cea7def51ab49860John McCall 16592b7f70c924cbf4514e9e434cea7def51ab49860John McCall#endif 166