Skip to content

Commit 4a40e18

Browse files
committed
ref parameter match supports arbitrarily qualified names
#feat
1 parent da3305b commit 4a40e18

File tree

5 files changed

+2076
-16
lines changed

5 files changed

+2076
-16
lines changed

src/lib/Lib/CorpusImpl.cpp

Lines changed: 83 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
132190
template <bool isInner>
133191
bool
134192
isDecayedEqualImpl(
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(
240305
bool
241306
isDecayedEqual(
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

Comments
 (0)