aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/DeclFriend.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclFriend.h')
-rw-r--r--include/clang/AST/DeclFriend.h50
1 files changed, 41 insertions, 9 deletions
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 37e45868b57c..253c23c199af 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());
}