@@ -70,6 +70,9 @@ class FriendDecl final
70
70
// Location of the 'friend' specifier.
71
71
SourceLocation FriendLoc;
72
72
73
+ // Location of the '...', if present.
74
+ SourceLocation EllipsisLoc;
75
+
73
76
// / True if this 'friend' declaration is unsupported. Eventually we
74
77
// / will support every possible friend declaration, but for now we
75
78
// / silently ignore some and set this flag to authorize all access.
@@ -82,10 +85,11 @@ class FriendDecl final
82
85
unsigned NumTPLists : 31 ;
83
86
84
87
FriendDecl (DeclContext *DC, SourceLocation L, FriendUnion Friend,
85
- SourceLocation FriendL,
88
+ SourceLocation FriendL, SourceLocation EllipsisLoc,
86
89
ArrayRef<TemplateParameterList *> FriendTypeTPLists)
87
90
: Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
88
- UnsupportedFriend (false ), NumTPLists(FriendTypeTPLists.size()) {
91
+ EllipsisLoc (EllipsisLoc), UnsupportedFriend(false ),
92
+ NumTPLists(FriendTypeTPLists.size()) {
89
93
for (unsigned i = 0 ; i < NumTPLists; ++i)
90
94
getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i];
91
95
}
@@ -110,7 +114,7 @@ class FriendDecl final
110
114
111
115
static FriendDecl *
112
116
Create (ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
113
- SourceLocation FriendL,
117
+ SourceLocation FriendL, SourceLocation EllipsisLoc = {},
114
118
ArrayRef<TemplateParameterList *> FriendTypeTPLists = std::nullopt );
115
119
static FriendDecl *CreateDeserialized (ASTContext &C, GlobalDeclID ID,
116
120
unsigned FriendTypeNumTPLists);
@@ -143,8 +147,24 @@ class FriendDecl final
143
147
return FriendLoc;
144
148
}
145
149
150
+ // / Retrieves the location of the '...', if present.
151
+ SourceLocation getEllipsisLoc () const { return EllipsisLoc; }
152
+
146
153
// / Retrieves the source range for the friend declaration.
147
154
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
+
148
168
if (NamedDecl *ND = getFriendDecl ()) {
149
169
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
150
170
return FD->getSourceRange ();
@@ -158,15 +178,8 @@ class FriendDecl final
158
178
}
159
179
return SourceRange (getFriendLoc (), ND->getEndLoc ());
160
180
}
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 ());
170
183
}
171
184
172
185
// / Determines if this friend kind is unsupported.
@@ -177,6 +190,8 @@ class FriendDecl final
177
190
UnsupportedFriend = Unsupported;
178
191
}
179
192
193
+ bool isPackExpansion () const { return EllipsisLoc.isValid (); }
194
+
180
195
// Implement isa/cast/dyncast/etc.
181
196
static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
182
197
static bool classofKind (Kind K) { return K == Decl::Friend; }
0 commit comments