@@ -129,11 +129,71 @@ findFirstParentInfo(
129
129
}
130
130
}
131
131
132
+ bool
133
+ qualifiedNameCompare (
134
+ Polymorphic<NameInfo> const & lhs0,
135
+ Polymorphic<NameInfo> const & rhs0,
136
+ Info const & context,
137
+ CorpusImpl const & corpus)
138
+ {
139
+ MRDOCS_CHECK_OR (lhs0 && rhs0, false );
140
+ // Compare each component of the qualified name
141
+ NameInfo const * lhs = &*lhs0;
142
+ NameInfo const * rhs = &*rhs0;
143
+ while (lhs && rhs)
144
+ {
145
+ if (lhs->Name != rhs->Name )
146
+ {
147
+ return false ;
148
+ }
149
+ lhs = lhs->Prefix ? &*lhs->Prefix : nullptr ;
150
+ rhs = rhs->Prefix ? &*rhs->Prefix : nullptr ;
151
+ }
152
+ // We consumed all components of both names
153
+ if (!lhs && !rhs)
154
+ {
155
+ return true ;
156
+ }
157
+ // One name has more components than the other:
158
+ // these component should match the names from
159
+ // the context. When we doesn't match the context
160
+ // we try again with the parent context.
161
+ NameInfo const * curName0 = lhs ? lhs : rhs;
162
+ Info const * curContext0 = &context;
163
+ NameInfo const * curName = curName0;
164
+ Info const * curContext = curContext0;
165
+ while (curName && curContext)
166
+ {
167
+ if (curName->Name != curContext->Name )
168
+ {
169
+ // The name doesn't match the context name
170
+ // Try again, starting from the parent
171
+ // context.
172
+ curName = curName0;
173
+ curContext0 = curContext0->Parent ? corpus.find (curContext->Parent ) : nullptr ;
174
+ // No parent context to try: return false
175
+ if (!curContext0)
176
+ {
177
+ return false ;
178
+ }
179
+ curContext = curContext0;
180
+ continue ;
181
+ }
182
+ // Names matches, match next component
183
+ curName = curName->Prefix ? &*curName->Prefix : nullptr ;
184
+ curContext = curContext->Parent ? corpus.find (curContext->Parent ) : nullptr ;
185
+ }
186
+ // We should have consumed all components of the name with the context
187
+ return !curName;
188
+ }
189
+
132
190
template <bool isInner>
133
191
bool
134
192
isDecayedEqualImpl (
135
193
Polymorphic<TypeInfo> const & lhs,
136
- Polymorphic<TypeInfo> const & rhs)
194
+ Polymorphic<TypeInfo> const & rhs,
195
+ Info const & context,
196
+ CorpusImpl const & corpus)
137
197
{
138
198
// Polymorphic
139
199
MRDOCS_CHECK_OR (static_cast <bool >(lhs) == static_cast <bool >(rhs), false );
@@ -161,13 +221,16 @@ isDecayedEqualImpl(
161
221
MRDOCS_CHECK_OR (lhs->Constraints == rhs->Constraints , false );
162
222
switch (lhs->Kind )
163
223
{
164
- // Types that never decay are compared directly
224
+ // Types that never decay are compared directly, but we
225
+ // only compare the fields of the type, without reevaluating
226
+ // the fields of TypeInfo.
165
227
case TypeKind::Named:
166
228
{
167
- // Compare only the fields of NameInfo, without
168
- // TypeInfo, to avoid evaluating TypeInfo::IsConst
169
- return dynamic_cast <NamedTypeInfo const &>(*lhs).Name ==
170
- dynamic_cast <NamedTypeInfo const &>(*rhs).Name ;
229
+ return
230
+ qualifiedNameCompare (
231
+ dynamic_cast <NamedTypeInfo const &>(*lhs).Name ,
232
+ dynamic_cast <NamedTypeInfo const &>(*rhs).Name ,
233
+ context, corpus);
171
234
}
172
235
case TypeKind::Decltype:
173
236
{
@@ -186,22 +249,24 @@ isDecayedEqualImpl(
186
249
return
187
250
isDecayedEqualImpl<true >(
188
251
dynamic_cast <LValueReferenceTypeInfo const &>(*lhs).PointeeType ,
189
- dynamic_cast <LValueReferenceTypeInfo const &>(*rhs).PointeeType );
252
+ dynamic_cast <LValueReferenceTypeInfo const &>(*rhs).PointeeType ,
253
+ context, corpus);
190
254
}
191
255
case TypeKind::RValueReference:
192
256
{
193
257
return
194
258
isDecayedEqualImpl<true >(
195
259
dynamic_cast <RValueReferenceTypeInfo const &>(*lhs).PointeeType ,
196
- dynamic_cast <RValueReferenceTypeInfo const &>(*rhs).PointeeType );
260
+ dynamic_cast <RValueReferenceTypeInfo const &>(*rhs).PointeeType ,
261
+ context, corpus);
197
262
}
198
263
case TypeKind::MemberPointer:
199
264
{
200
265
auto const & lhsMP = dynamic_cast <MemberPointerTypeInfo const &>(*lhs);
201
266
auto const & rhsMP = dynamic_cast <MemberPointerTypeInfo const &>(*rhs);
202
267
return
203
- isDecayedEqualImpl<true >(lhsMP.PointeeType , rhsMP.PointeeType ) &&
204
- isDecayedEqualImpl<true >(lhsMP.ParentType , rhsMP.ParentType );
268
+ isDecayedEqualImpl<true >(lhsMP.PointeeType , rhsMP.PointeeType , context, corpus ) &&
269
+ isDecayedEqualImpl<true >(lhsMP.ParentType , rhsMP.ParentType , context, corpus );
205
270
}
206
271
case TypeKind::Function:
207
272
{
@@ -210,11 +275,11 @@ isDecayedEqualImpl(
210
275
MRDOCS_CHECK_OR (lhsF.RefQualifier == rhsF.RefQualifier , false );
211
276
MRDOCS_CHECK_OR (lhsF.ExceptionSpec == rhsF.ExceptionSpec , false );
212
277
MRDOCS_CHECK_OR (lhsF.IsVariadic == rhsF.IsVariadic , false );
213
- MRDOCS_CHECK_OR (isDecayedEqualImpl<true >(lhsF.ReturnType , rhsF.ReturnType ), false );
278
+ MRDOCS_CHECK_OR (isDecayedEqualImpl<true >(lhsF.ReturnType , rhsF.ReturnType , context, corpus ), false );
214
279
MRDOCS_CHECK_OR (lhsF.ParamTypes .size () == rhsF.ParamTypes .size (), false );
215
280
for (std::size_t i = 0 ; i < lhsF.ParamTypes .size (); ++i)
216
281
{
217
- MRDOCS_CHECK_OR (isDecayedEqualImpl<false >(lhsF.ParamTypes [i], rhsF.ParamTypes [i]), false );
282
+ MRDOCS_CHECK_OR (isDecayedEqualImpl<false >(lhsF.ParamTypes [i], rhsF.ParamTypes [i], context, corpus ), false );
218
283
}
219
284
return true ;
220
285
}
@@ -226,7 +291,7 @@ isDecayedEqualImpl(
226
291
auto const I2 = innerType (*rhs);
227
292
MRDOCS_CHECK_OR (static_cast <bool >(I1) == static_cast <bool >(I2), false );
228
293
MRDOCS_CHECK_OR (static_cast <bool >(I1) && static_cast <bool >(I2), true );
229
- return isDecayedEqualImpl<true >(I1->get (), I2->get ());
294
+ return isDecayedEqualImpl<true >(I1->get (), I2->get (), context, corpus );
230
295
}
231
296
default :
232
297
MRDOCS_UNREACHABLE ();
@@ -240,9 +305,11 @@ isDecayedEqualImpl(
240
305
bool
241
306
isDecayedEqual (
242
307
Polymorphic<TypeInfo> const & lhs,
243
- Polymorphic<TypeInfo> const & rhs)
308
+ Polymorphic<TypeInfo> const & rhs,
309
+ Info const & context,
310
+ CorpusImpl const & corpus)
244
311
{
245
- return isDecayedEqualImpl<false >(lhs, rhs);
312
+ return isDecayedEqualImpl<false >(lhs, rhs, context, corpus );
246
313
}
247
314
}
248
315
@@ -513,7 +580,7 @@ lookupImpl(
513
580
{
514
581
auto & lhsType = F.Params [i].Type ;
515
582
auto & rhsType = ref.FunctionParameters [i];
516
- MRDOCS_CHECK_OR (isDecayedEqual (lhsType, rhsType), matchRes);
583
+ MRDOCS_CHECK_OR (isDecayedEqual (lhsType, rhsType, context, * this ), matchRes);
517
584
}
518
585
MRDOCS_CHECK_OR (F.IsVariadic == ref.IsVariadic , matchRes);
519
586
matchRes = MatchLevel::FunctionParameters;
0 commit comments