Skip to content

Commit 036c6fc

Browse files
committed
Merge pull request #69138 from Azoy/generics-are-hard
[Runtime] Refactor _gatherWrittenGenericParameters
1 parent 26f4272 commit 036c6fc

File tree

5 files changed

+326
-214
lines changed

5 files changed

+326
-214
lines changed

stdlib/public/runtime/Demangle.cpp

Lines changed: 53 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -266,25 +266,6 @@ _buildDemanglingForMetadataPack(MetadataPackPointer pack, size_t count,
266266
return node;
267267
}
268268

269-
/// Demangle the given type name to a generic parameter reference, which
270-
/// will be returned as (depth, index).
271-
static llvm::Optional<std::pair<unsigned, unsigned>>
272-
demangleToGenericParamRef(StringRef typeName) {
273-
StackAllocatedDemangler<1024> demangler;
274-
NodePointer node = demangler.demangleType(typeName);
275-
if (!node)
276-
return llvm::None;
277-
278-
// Find the flat index that the right-hand side refers to.
279-
if (node->getKind() == Demangle::Node::Kind::Type)
280-
node = node->getChild(0);
281-
if (node->getKind() != Demangle::Node::Kind::DependentGenericParamType)
282-
return llvm::None;
283-
284-
return std::pair<unsigned, unsigned>(node->getChild(0)->getIndex(),
285-
node->getChild(1)->getIndex());
286-
}
287-
288269
/// Build an array of demangling trees for each generic argument of the given
289270
/// type metadata.
290271
///
@@ -314,144 +295,77 @@ static bool _buildDemanglingForGenericArgs(
314295
return true;
315296

316297
auto genericArgs = description->getGenericArguments(type);
317-
318298
auto packHeader = generics->getGenericPackShapeHeader();
319299
auto packDescriptors = generics->getGenericPackShapeDescriptors();
320300

321-
unsigned packIndex = 0;
322-
unsigned argIndex = packHeader.NumShapeClasses;
323-
324-
bool missingWrittenArguments = false;
301+
llvm::SmallVector<MetadataOrPack> allGenericArgs;
325302

303+
auto numKeyArgs = 0;
326304
for (auto param : generics->getGenericParams()) {
327-
switch (param.getKind()) {
328-
case GenericParamKind::Type:
329-
// The type should have a key argument unless it's been same-typed to
330-
// another type.
331-
if (param.hasKeyArgument()) {
332-
auto genericArg = reinterpret_cast<const Metadata *>(genericArgs[argIndex]);
333-
334-
auto genericArgDemangling =
335-
_swift_buildDemanglingForMetadata(genericArg, Dem);
336-
if (!genericArgDemangling)
337-
return false;
338-
demangledGenerics.push_back(genericArgDemangling);
339-
340-
++argIndex;
341-
} else {
342-
// Leave a gap for us to fill in by looking at same-type requirements.
343-
demangledGenerics.push_back(nullptr);
344-
missingWrittenArguments = true;
345-
}
305+
if (param.hasKeyArgument()) {
306+
numKeyArgs += 1;
307+
}
308+
}
346309

347-
break;
310+
// _gatherWrittenGenericParameters expects to immediately read key generic
311+
// arguments, so skip past the shape classes if we have any.
312+
auto nonShapeClassGenericArgs = genericArgs + packHeader.NumShapeClasses;
348313

349-
case GenericParamKind::TypePack:
350-
if (param.hasKeyArgument()) {
351-
auto packDescriptor = packDescriptors[packIndex];
352-
assert(packDescriptor.Kind == GenericPackKind::Metadata);
353-
assert(packDescriptor.ShapeClass < packHeader.NumShapeClasses);
354-
assert(packDescriptor.Index == argIndex);
314+
llvm::ArrayRef<const void *> genericArgsRef(
315+
reinterpret_cast<const void * const *>(nonShapeClassGenericArgs), numKeyArgs);
355316

356-
MetadataPackPointer pack(genericArgs[argIndex]);
357-
size_t count = reinterpret_cast<size_t>(genericArgs[packDescriptor.ShapeClass]);
317+
if (!_gatherWrittenGenericParameters(description, genericArgsRef,
318+
allGenericArgs, Dem)) {
319+
return false;
320+
}
358321

359-
auto genericArgDemangling = _buildDemanglingForMetadataPack(pack, count, Dem);
360-
if (genericArgDemangling == nullptr)
361-
return false;
322+
auto argIndex = 0;
323+
auto packIndex = 0;
362324

363-
demangledGenerics.push_back(genericArgDemangling);
325+
for (auto param : generics->getGenericParams()) {
326+
auto genericArg = allGenericArgs[argIndex];
364327

365-
++packIndex;
366-
++argIndex;
367-
} else {
368-
// Leave a gap for us to fill in by looking at same-type requirements.
369-
demangledGenerics.push_back(nullptr);
370-
missingWrittenArguments = true;
328+
switch (param.getKind()) {
329+
case GenericParamKind::Type: {
330+
auto metadata = genericArg.getMetadata();
331+
auto genericArgDemangling =
332+
_swift_buildDemanglingForMetadata(metadata, Dem);
333+
334+
if (!genericArgDemangling) {
335+
return false;
371336
}
372337

338+
demangledGenerics.push_back(genericArgDemangling);
373339
break;
374-
375-
default:
376-
// We don't know about this kind of parameter.
377-
return false;
378340
}
379-
}
380341

381-
// If there is no follow-up work to do, we're done.
382-
if (!missingWrittenArguments)
383-
return true;
342+
case GenericParamKind::TypePack: {
343+
auto packDescriptor = packDescriptors[packIndex];
344+
assert(packDescriptor.Kind == GenericPackKind::Metadata);
345+
assert(packDescriptor.ShapeClass < packHeader.NumShapeClasses);
384346

385-
// We have generic arguments that would be written, but have been
386-
// canonicalized away. Use same-type requirements to reconstitute them.
387-
SubstGenericParametersFromMetadata substitutions(
388-
description, reinterpret_cast<const void * const *>(genericArgs));
389-
390-
// Retrieve the mapping information needed for depth/index -> flat index.
391-
llvm::SmallVector<unsigned, 8> genericParamCounts;
392-
(void)_gatherGenericParameterCounts(description, genericParamCounts, Dem);
393-
394-
// Walk through the generic requirements to evaluate same-type
395-
// constraints that are needed to fill in missing generic arguments.
396-
for (const auto &req : generics->getGenericRequirements()) {
397-
// We only care about same-type constraints.
398-
if (req.Flags.getKind() != GenericRequirementKind::SameType)
399-
continue;
400-
401-
auto lhsParam = demangleToGenericParamRef(req.getParam());
402-
if (!lhsParam)
403-
continue;
404-
405-
assert(!req.Flags.isPackRequirement() &&
406-
"Pack requirements not supported here yet");
407-
408-
// If we don't yet have an argument for this parameter, it's a
409-
// same-type-to-concrete constraint.
410-
auto lhsFlatIndex =
411-
_depthIndexToFlatIndex(lhsParam->first, lhsParam->second,
412-
genericParamCounts);
413-
if (!lhsFlatIndex || *lhsFlatIndex >= demangledGenerics.size())
414-
return false;
347+
// Arg index is not interested in the shape classes, but the pack
348+
// descriptor's index is in terms of the shape classes.
349+
assert(packDescriptor.Index == argIndex + packHeader.NumShapeClasses);
415350

416-
if (!demangledGenerics[*lhsFlatIndex]) {
417-
// Substitute into the right-hand side.
418-
auto *genericArg =
419-
swift_getTypeByMangledName(MetadataState::Abstract,
420-
req.getMangledTypeName(),
421-
reinterpret_cast<const void * const *>(genericArgs),
422-
[&substitutions](unsigned depth, unsigned index) {
423-
// FIXME: Variadic generics
424-
return substitutions.getMetadata(depth, index).getMetadata();
425-
},
426-
[&substitutions](const Metadata *type, unsigned index) {
427-
return substitutions.getWitnessTable(type, index);
428-
}).getType().getMetadata();
429-
if (!genericArg)
430-
return false;
351+
MetadataPackPointer pack(genericArg.getMetadataPack());
352+
size_t count = reinterpret_cast<size_t>(genericArgs[packDescriptor.ShapeClass]);
431353

432-
demangledGenerics[*lhsFlatIndex] =
433-
_swift_buildDemanglingForMetadata(genericArg, Dem);
354+
auto genericArgDemangling = _buildDemanglingForMetadataPack(pack, count, Dem);
355+
if (genericArgDemangling == nullptr)
356+
return false;
434357

435-
continue;
358+
demangledGenerics.push_back(genericArgDemangling);
359+
packIndex += 1;
360+
break;
436361
}
437362

438-
// If we do have an argument for this parameter, it might be that
439-
// the right-hand side is itself a generic parameter, which means
440-
// we have a same-type constraint A == B where A is already filled in.
441-
auto rhsParam = demangleToGenericParamRef(req.getMangledTypeName());
442-
if (!rhsParam)
443-
return false;
444-
445-
auto rhsFlatIndex =
446-
_depthIndexToFlatIndex(rhsParam->first, rhsParam->second,
447-
genericParamCounts);
448-
if (!rhsFlatIndex || *rhsFlatIndex >= demangledGenerics.size())
449-
return false;
450-
451-
if (demangledGenerics[*rhsFlatIndex] || !demangledGenerics[*lhsFlatIndex])
363+
default:
364+
// We don't know about this kind of parameter.
452365
return false;
366+
}
453367

454-
demangledGenerics[*rhsFlatIndex] = demangledGenerics[*lhsFlatIndex];
368+
argIndex += 1;
455369
}
456370

457371
return true;
@@ -468,9 +382,14 @@ _buildDemanglingForNominalType(const Metadata *type, Demangle::Demangler &Dem) {
468382
switch (type->getKind()) {
469383
case MetadataKind::Class: {
470384
auto classType = static_cast<const ClassMetadata *>(type);
385+
386+
if (!classType->isTypeMetadata()) {
387+
return nullptr;
388+
}
389+
471390
#if SWIFT_OBJC_INTEROP
472391
// Peek through artificial subclasses.
473-
while (classType->isTypeMetadata() && classType->isArtificialSubclass())
392+
while (classType->isArtificialSubclass())
474393
classType = classType->Superclass;
475394
#endif
476395
description = classType->getDescription();

0 commit comments

Comments
 (0)