diff options
Diffstat (limited to 'include/clang/AST/DeclFriend.h')
-rw-r--r-- | include/clang/AST/DeclFriend.h | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 37e4586..253c23c 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -54,22 +54,40 @@ private: /// True if this 'friend' declaration is unsupported. Eventually we /// will support every possible friend declaration, but for now we /// silently ignore some and set this flag to authorize all access. - bool UnsupportedFriend; + bool UnsupportedFriend : 1; + + // The number of "outer" template parameter lists in non-templatic + // (currently unsupported) friend type declarations, such as + // template <class T> friend class A<T>::B; + unsigned NumTPLists : 31; + + // The tail-allocated friend type template parameter lists (if any). + TemplateParameterList* const *getTPLists() const { + return reinterpret_cast<TemplateParameterList* const *>(this + 1); + } + TemplateParameterList **getTPLists() { + return reinterpret_cast<TemplateParameterList**>(this + 1); + } friend class CXXRecordDecl::friend_iterator; friend class CXXRecordDecl; FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend, - SourceLocation FriendL) + SourceLocation FriendL, + ArrayRef<TemplateParameterList*> FriendTypeTPLists) : Decl(Decl::Friend, DC, L), Friend(Friend), NextFriend(), FriendLoc(FriendL), - UnsupportedFriend(false) { + UnsupportedFriend(false), + NumTPLists(FriendTypeTPLists.size()) { + for (unsigned i = 0; i < NumTPLists; ++i) + getTPLists()[i] = FriendTypeTPLists[i]; } - explicit FriendDecl(EmptyShell Empty) - : Decl(Decl::Friend, Empty), NextFriend() { } + FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists) + : Decl(Decl::Friend, Empty), NextFriend(), + NumTPLists(NumFriendTypeTPLists) { } FriendDecl *getNextFriend() { if (!NextFriend.isOffset()) @@ -81,8 +99,11 @@ private: public: static FriendDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, - SourceLocation FriendL); - static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID); + SourceLocation FriendL, + ArrayRef<TemplateParameterList*> FriendTypeTPLists + = ArrayRef<TemplateParameterList*>()); + static FriendDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned FriendTypeNumTPLists); /// If this friend declaration names an (untemplated but possibly /// dependent) type, return the type; otherwise return null. This @@ -91,6 +112,13 @@ public: TypeSourceInfo *getFriendType() const { return Friend.dyn_cast<TypeSourceInfo*>(); } + unsigned getFriendTypeNumTemplateParameterLists() const { + return NumTPLists; + } + TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const { + assert(N < NumTPLists); + return getTPLists()[N]; + } /// If this friend declaration doesn't name a type, return the inner /// declaration. @@ -114,8 +142,12 @@ public: } return SourceRange(getFriendLoc(), ND->getLocEnd()); } - else if (TypeSourceInfo *TInfo = getFriendType()) - return SourceRange(getFriendLoc(), TInfo->getTypeLoc().getEndLoc()); + else if (TypeSourceInfo *TInfo = getFriendType()) { + SourceLocation StartL = (NumTPLists == 0) + ? getFriendLoc() + : getTPLists()[0]->getTemplateLoc(); + return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc()); + } else return SourceRange(getFriendLoc(), getLocation()); } |