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