@@ -70,6 +70,9 @@ class FriendDecl final
7070 // Location of the 'friend' specifier.
7171 SourceLocation FriendLoc;
7272
73+ // Location of the '...', if present.
74+ SourceLocation EllipsisLoc;
75+
7376 // / True if this 'friend' declaration is unsupported. Eventually we
7477 // / will support every possible friend declaration, but for now we
7578 // / silently ignore some and set this flag to authorize all access.
@@ -82,10 +85,11 @@ class FriendDecl final
8285 unsigned NumTPLists : 31 ;
8386
8487 FriendDecl (DeclContext *DC, SourceLocation L, FriendUnion Friend,
85- SourceLocation FriendL,
88+ SourceLocation FriendL, SourceLocation EllipsisLoc,
8689 ArrayRef<TemplateParameterList *> FriendTypeTPLists)
8790 : Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
88- UnsupportedFriend (false ), NumTPLists(FriendTypeTPLists.size()) {
91+ EllipsisLoc (EllipsisLoc), UnsupportedFriend(false ),
92+ NumTPLists(FriendTypeTPLists.size()) {
8993 for (unsigned i = 0 ; i < NumTPLists; ++i)
9094 getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
9195 }
@@ -110,7 +114,7 @@ class FriendDecl final
110114
111115 static FriendDecl *
112116 Create (ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
113- SourceLocation FriendL,
117+ SourceLocation FriendL, SourceLocation EllipsisLoc = {},
114118 ArrayRef<TemplateParameterList *> FriendTypeTPLists = std::nullopt );
115119 static FriendDecl *CreateDeserialized (ASTContext &C, GlobalDeclID ID,
116120 unsigned FriendTypeNumTPLists);
@@ -143,8 +147,24 @@ class FriendDecl final
143147 return FriendLoc;
144148 }
145149
150+ // / Retrieves the location of the '...', if present.
151+ SourceLocation getEllipsisLoc () const { return EllipsisLoc; }
152+
146153 // / Retrieves the source range for the friend declaration.
147154 SourceRange getSourceRange () const override LLVM_READONLY {
155+ if (TypeSourceInfo *TInfo = getFriendType ()) {
156+ SourceLocation StartL =
157+ (NumTPLists == 0 ) ? getFriendLoc ()
158+ : getTrailingObjects<TemplateParameterList *>()[0 ]
159+ ->getTemplateLoc ();
160+ SourceLocation EndL = isPackExpansion () ? getEllipsisLoc ()
161+ : TInfo->getTypeLoc ().getEndLoc ();
162+ return SourceRange (StartL, EndL);
163+ }
164+
165+ if (isPackExpansion ())
166+ return SourceRange (getFriendLoc (), getEllipsisLoc ());
167+
148168 if (NamedDecl *ND = getFriendDecl ()) {
149169 if (const auto *FD = dyn_cast<FunctionDecl>(ND))
150170 return FD->getSourceRange ();
@@ -158,15 +178,8 @@ class FriendDecl final
158178 }
159179 return SourceRange (getFriendLoc (), ND->getEndLoc ());
160180 }
161- else if (TypeSourceInfo *TInfo = getFriendType ()) {
162- SourceLocation StartL =
163- (NumTPLists == 0 ) ? getFriendLoc ()
164- : getTrailingObjects<TemplateParameterList *>()[0 ]
165- ->getTemplateLoc ();
166- return SourceRange (StartL, TInfo->getTypeLoc ().getEndLoc ());
167- }
168- else
169- return SourceRange (getFriendLoc (), getLocation ());
181+
182+ return SourceRange (getFriendLoc (), getLocation ());
170183 }
171184
172185 // / Determines if this friend kind is unsupported.
@@ -177,6 +190,8 @@ class FriendDecl final
177190 UnsupportedFriend = Unsupported;
178191 }
179192
193+ bool isPackExpansion () const { return EllipsisLoc.isValid (); }
194+
180195 // Implement isa/cast/dyncast/etc.
181196 static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
182197 static bool classofKind (Kind K) { return K == Decl::Friend; }
0 commit comments