@@ -129,11 +129,71 @@ findFirstParentInfo(
129129 }
130130}
131131
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+
132190template <bool isInner>
133191bool
134192isDecayedEqualImpl (
135193 Polymorphic<TypeInfo> const & lhs,
136- Polymorphic<TypeInfo> const & rhs)
194+ Polymorphic<TypeInfo> const & rhs,
195+ Info const & context,
196+ CorpusImpl const & corpus)
137197{
138198 // Polymorphic
139199 MRDOCS_CHECK_OR (static_cast <bool >(lhs) == static_cast <bool >(rhs), false );
@@ -161,13 +221,16 @@ isDecayedEqualImpl(
161221 MRDOCS_CHECK_OR (lhs->Constraints == rhs->Constraints , false );
162222 switch (lhs->Kind )
163223 {
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.
165227 case TypeKind::Named:
166228 {
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);
171234 }
172235 case TypeKind::Decltype:
173236 {
@@ -186,22 +249,24 @@ isDecayedEqualImpl(
186249 return
187250 isDecayedEqualImpl<true >(
188251 dynamic_cast <LValueReferenceTypeInfo const &>(*lhs).PointeeType ,
189- dynamic_cast <LValueReferenceTypeInfo const &>(*rhs).PointeeType );
252+ dynamic_cast <LValueReferenceTypeInfo const &>(*rhs).PointeeType ,
253+ context, corpus);
190254 }
191255 case TypeKind::RValueReference:
192256 {
193257 return
194258 isDecayedEqualImpl<true >(
195259 dynamic_cast <RValueReferenceTypeInfo const &>(*lhs).PointeeType ,
196- dynamic_cast <RValueReferenceTypeInfo const &>(*rhs).PointeeType );
260+ dynamic_cast <RValueReferenceTypeInfo const &>(*rhs).PointeeType ,
261+ context, corpus);
197262 }
198263 case TypeKind::MemberPointer:
199264 {
200265 auto const & lhsMP = dynamic_cast <MemberPointerTypeInfo const &>(*lhs);
201266 auto const & rhsMP = dynamic_cast <MemberPointerTypeInfo const &>(*rhs);
202267 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 );
205270 }
206271 case TypeKind::Function:
207272 {
@@ -210,11 +275,11 @@ isDecayedEqualImpl(
210275 MRDOCS_CHECK_OR (lhsF.RefQualifier == rhsF.RefQualifier , false );
211276 MRDOCS_CHECK_OR (lhsF.ExceptionSpec == rhsF.ExceptionSpec , false );
212277 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 );
214279 MRDOCS_CHECK_OR (lhsF.ParamTypes .size () == rhsF.ParamTypes .size (), false );
215280 for (std::size_t i = 0 ; i < lhsF.ParamTypes .size (); ++i)
216281 {
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 );
218283 }
219284 return true ;
220285 }
@@ -226,7 +291,7 @@ isDecayedEqualImpl(
226291 auto const I2 = innerType (*rhs);
227292 MRDOCS_CHECK_OR (static_cast <bool >(I1) == static_cast <bool >(I2), false );
228293 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 );
230295 }
231296 default :
232297 MRDOCS_UNREACHABLE ();
@@ -240,9 +305,11 @@ isDecayedEqualImpl(
240305bool
241306isDecayedEqual (
242307 Polymorphic<TypeInfo> const & lhs,
243- Polymorphic<TypeInfo> const & rhs)
308+ Polymorphic<TypeInfo> const & rhs,
309+ Info const & context,
310+ CorpusImpl const & corpus)
244311{
245- return isDecayedEqualImpl<false >(lhs, rhs);
312+ return isDecayedEqualImpl<false >(lhs, rhs, context, corpus );
246313}
247314}
248315
@@ -513,7 +580,7 @@ lookupImpl(
513580 {
514581 auto & lhsType = F.Params [i].Type ;
515582 auto & rhsType = ref.FunctionParameters [i];
516- MRDOCS_CHECK_OR (isDecayedEqual (lhsType, rhsType), matchRes);
583+ MRDOCS_CHECK_OR (isDecayedEqual (lhsType, rhsType, context, * this ), matchRes);
517584 }
518585 MRDOCS_CHECK_OR (F.IsVariadic == ref.IsVariadic , matchRes);
519586 matchRes = MatchLevel::FunctionParameters;
0 commit comments