LCOV - code coverage report
Current view: top level - clang/AST - DeclFriend.h (source / functions) Hit Total Coverage
Test: clang.info Lines: 0 2 0.0 %
Date: 2016-01-31 12:01:00 Functions: 0 2 0.0 %

          Line data    Source code
       1             : //===-- DeclFriend.h - Classes for C++ friend declarations -*- C++ -*------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file defines the section of the AST representing C++ friend
      11             : // declarations.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_CLANG_AST_DECLFRIEND_H
      16             : #define LLVM_CLANG_AST_DECLFRIEND_H
      17             : 
      18             : #include "clang/AST/DeclCXX.h"
      19             : #include "clang/AST/DeclTemplate.h"
      20             : #include "clang/AST/TypeLoc.h"
      21             : #include "llvm/Support/Compiler.h"
      22             : 
      23             : namespace clang {
      24             : 
      25             : /// FriendDecl - Represents the declaration of a friend entity,
      26             : /// which can be a function, a type, or a templated function or type.
      27             : //  For example:
      28             : ///
      29             : /// @code
      30             : /// template <typename T> class A {
      31             : ///   friend int foo(T);
      32             : ///   friend class B;
      33             : ///   friend T; // only in C++0x
      34             : ///   template <typename U> friend class C;
      35             : ///   template <typename U> friend A& operator+=(A&, const U&) { ... }
      36             : /// };
      37             : /// @endcode
      38             : ///
      39             : /// The semantic context of a friend decl is its declaring class.
      40             : class FriendDecl : public Decl {
      41             :   virtual void anchor();
      42             : public:
      43             :   typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
      44             : 
      45             : private:
      46             :   // The declaration that's a friend of this class.
      47             :   FriendUnion Friend;
      48             : 
      49             :   // A pointer to the next friend in the sequence.
      50             :   LazyDeclPtr NextFriend;
      51             : 
      52             :   // Location of the 'friend' specifier.
      53             :   SourceLocation FriendLoc;
      54             : 
      55             :   /// True if this 'friend' declaration is unsupported.  Eventually we
      56             :   /// will support every possible friend declaration, but for now we
      57             :   /// silently ignore some and set this flag to authorize all access.
      58             :   bool UnsupportedFriend : 1;
      59             : 
      60             :   // The number of "outer" template parameter lists in non-templatic
      61             :   // (currently unsupported) friend type declarations, such as
      62             :   //     template <class T> friend class A<T>::B;
      63             :   unsigned NumTPLists : 31;
      64             : 
      65             :   // The tail-allocated friend type template parameter lists (if any).
      66             :   TemplateParameterList* const *getTPLists() const {
      67             :     return reinterpret_cast<TemplateParameterList* const *>(this + 1);
      68             :   }
      69             :   TemplateParameterList **getTPLists() {
      70             :     return reinterpret_cast<TemplateParameterList**>(this + 1);
      71             :   }
      72             : 
      73             :   friend class CXXRecordDecl::friend_iterator;
      74             :   friend class CXXRecordDecl;
      75             : 
      76             :   FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
      77             :              SourceLocation FriendL,
      78             :              ArrayRef<TemplateParameterList*> FriendTypeTPLists)
      79             :     : Decl(Decl::Friend, DC, L),
      80             :       Friend(Friend),
      81             :       NextFriend(),
      82             :       FriendLoc(FriendL),
      83             :       UnsupportedFriend(false),
      84             :       NumTPLists(FriendTypeTPLists.size()) {
      85             :     for (unsigned i = 0; i < NumTPLists; ++i)
      86             :       getTPLists()[i] = FriendTypeTPLists[i];
      87             :   }
      88             : 
      89             :   FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
      90             :     : Decl(Decl::Friend, Empty), NextFriend(),
      91             :       NumTPLists(NumFriendTypeTPLists) { }
      92             : 
      93             :   FriendDecl *getNextFriend() {
      94             :     if (!NextFriend.isOffset())
      95             :       return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
      96             :     return getNextFriendSlowCase();
      97             :   }
      98             :   FriendDecl *getNextFriendSlowCase();
      99             : 
     100             : public:
     101             :   static FriendDecl *Create(ASTContext &C, DeclContext *DC,
     102             :                             SourceLocation L, FriendUnion Friend_,
     103             :                             SourceLocation FriendL,
     104             :                             ArrayRef<TemplateParameterList*> FriendTypeTPLists
     105             :                             = None);
     106             :   static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID,
     107             :                                         unsigned FriendTypeNumTPLists);
     108             : 
     109             :   /// If this friend declaration names an (untemplated but possibly
     110             :   /// dependent) type, return the type; otherwise return null.  This
     111             :   /// is used for elaborated-type-specifiers and, in C++0x, for
     112             :   /// arbitrary friend type declarations.
     113             :   TypeSourceInfo *getFriendType() const {
     114           0 :     return Friend.dyn_cast<TypeSourceInfo*>();
     115             :   }
     116             :   unsigned getFriendTypeNumTemplateParameterLists() const {
     117             :     return NumTPLists;
     118             :   }
     119             :   TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
     120             :     assert(N < NumTPLists);
     121             :     return getTPLists()[N];
     122             :   }
     123             : 
     124             :   /// If this friend declaration doesn't name a type, return the inner
     125             :   /// declaration.
     126             :   NamedDecl *getFriendDecl() const {
     127           0 :     return Friend.dyn_cast<NamedDecl*>();
     128             :   }
     129             : 
     130             :   /// Retrieves the location of the 'friend' keyword.
     131             :   SourceLocation getFriendLoc() const {
     132             :     return FriendLoc;
     133             :   }
     134             : 
     135             :   /// Retrieves the source range for the friend declaration.
     136             :   SourceRange getSourceRange() const override LLVM_READONLY {
     137             :     if (NamedDecl *ND = getFriendDecl()) {
     138             :       if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
     139             :         return FD->getSourceRange();
     140             :       if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
     141             :         return FTD->getSourceRange();
     142             :       if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
     143             :         return CTD->getSourceRange();
     144             :       if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
     145             :         if (DD->getOuterLocStart() != DD->getInnerLocStart())
     146             :           return DD->getSourceRange();
     147             :       }
     148             :       return SourceRange(getFriendLoc(), ND->getLocEnd());
     149             :     }
     150             :     else if (TypeSourceInfo *TInfo = getFriendType()) {
     151             :       SourceLocation StartL = (NumTPLists == 0)
     152             :         ? getFriendLoc()
     153             :         : getTPLists()[0]->getTemplateLoc();
     154             :       return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc());
     155             :     }
     156             :     else
     157             :       return SourceRange(getFriendLoc(), getLocation());
     158             :   }
     159             : 
     160             :   /// Determines if this friend kind is unsupported.
     161             :   bool isUnsupportedFriend() const {
     162             :     return UnsupportedFriend;
     163             :   }
     164             :   void setUnsupportedFriend(bool Unsupported) {
     165             :     UnsupportedFriend = Unsupported;
     166             :   }
     167             : 
     168             :   // Implement isa/cast/dyncast/etc.
     169             :   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
     170             :   static bool classofKind(Kind K) { return K == Decl::Friend; }
     171             : 
     172             :   friend class ASTDeclReader;
     173             :   friend class ASTDeclWriter;
     174             : };
     175             : 
     176             : /// An iterator over the friend declarations of a class.
     177             : class CXXRecordDecl::friend_iterator {
     178             :   FriendDecl *Ptr;
     179             : 
     180             :   friend class CXXRecordDecl;
     181             :   explicit friend_iterator(FriendDecl *Ptr) : Ptr(Ptr) {}
     182             : public:
     183             :   friend_iterator() {}
     184             : 
     185             :   typedef FriendDecl *value_type;
     186             :   typedef FriendDecl *reference;
     187             :   typedef FriendDecl *pointer;
     188             :   typedef int difference_type;
     189             :   typedef std::forward_iterator_tag iterator_category;
     190             : 
     191             :   reference operator*() const { return Ptr; }
     192             : 
     193             :   friend_iterator &operator++() {
     194             :     assert(Ptr && "attempt to increment past end of friend list");
     195             :     Ptr = Ptr->getNextFriend();
     196             :     return *this;
     197             :   }
     198             : 
     199             :   friend_iterator operator++(int) {
     200             :     friend_iterator tmp = *this;
     201             :     ++*this;
     202             :     return tmp;
     203             :   }
     204             : 
     205             :   bool operator==(const friend_iterator &Other) const {
     206             :     return Ptr == Other.Ptr;
     207             :   }
     208             : 
     209             :   bool operator!=(const friend_iterator &Other) const {
     210             :     return Ptr != Other.Ptr;
     211             :   }
     212             : 
     213             :   friend_iterator &operator+=(difference_type N) {
     214             :     assert(N >= 0 && "cannot rewind a CXXRecordDecl::friend_iterator");
     215             :     while (N--)
     216             :       ++*this;
     217             :     return *this;
     218             :   }
     219             : 
     220             :   friend_iterator operator+(difference_type N) const {
     221             :     friend_iterator tmp = *this;
     222             :     tmp += N;
     223             :     return tmp;
     224             :   }
     225             : };
     226             : 
     227             : inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_begin() const {
     228             :   return friend_iterator(getFirstFriend());
     229             : }
     230             : 
     231             : inline CXXRecordDecl::friend_iterator CXXRecordDecl::friend_end() const {
     232             :   return friend_iterator(nullptr);
     233             : }
     234             : 
     235             : inline CXXRecordDecl::friend_range CXXRecordDecl::friends() const {
     236             :   return friend_range(friend_begin(), friend_end());
     237             : }
     238             : 
     239             : inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) {
     240             :   assert(!FD->NextFriend && "friend already has next friend?");
     241             :   FD->NextFriend = data().FirstFriend;
     242             :   data().FirstFriend = FD;
     243             : }
     244             :   
     245             : }
     246             : 
     247             : #endif

Generated by: LCOV version 1.11