Skip to content

Commit 1bbc169

Browse files
committed
--wip-- [skip ci]
1 parent 6d2d2e0 commit 1bbc169

File tree

4 files changed

+185
-22
lines changed

4 files changed

+185
-22
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ class ASTBuilder {
6464
using BuiltRequirement = swift::Requirement;
6565
using BuiltSubstitutionMap = swift::SubstitutionMap;
6666

67+
static constexpr bool needsToPrecomputeParentGenericContextShapes = false;
68+
6769
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}
6870

6971
ASTContext &getASTContext() { return Ctx; }

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 110 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,24 @@ struct FieldTypeCollectionResult {
354354
std::vector<std::string> Errors;
355355
};
356356

357+
struct TypeRefDecl {
358+
std::string mangledName;
359+
360+
// Only used when building a bound generic typeref, and when the
361+
// generic params for all the levels are stored as a flat array.
362+
llvm::Optional<std::vector<size_t>> genericParamsPerLevel;
363+
364+
TypeRefDecl(std::string mangledName,
365+
std::vector<size_t> genericParamsPerLevel)
366+
: mangledName(mangledName),
367+
genericParamsPerLevel(genericParamsPerLevel) {}
368+
369+
TypeRefDecl(std::string mangledName)
370+
: mangledName(mangledName),
371+
genericParamsPerLevel(llvm::None) {}
372+
373+
};
374+
357375
/// An implementation of MetadataReader's BuilderType concept for
358376
/// building TypeRefs, and parsing field metadata from any images
359377
/// it has been made aware of.
@@ -366,7 +384,7 @@ class TypeRefBuilder {
366384

367385
public:
368386
using BuiltType = const TypeRef *;
369-
using BuiltTypeDecl = llvm::Optional<std::string>;
387+
using BuiltTypeDecl = llvm::Optional<TypeRefDecl>;
370388
using BuiltProtocolDecl =
371389
llvm::Optional<std::pair<std::string, bool /*isObjC*/>>;
372390
using BuiltSubstitution = std::pair<const TypeRef *, const TypeRef *>;
@@ -376,6 +394,8 @@ class TypeRefBuilder {
376394
using BuiltGenericSignature = const GenericSignatureRef *;
377395
using BuiltSubstitutionMap = llvm::DenseMap<DepthAndIndex, const TypeRef *>;
378396

397+
static constexpr bool needsToPrecomputeParentGenericContextShapes = true;
398+
379399
TypeRefBuilder(const TypeRefBuilder &other) = delete;
380400
TypeRefBuilder &operator=(const TypeRefBuilder &other) = delete;
381401

@@ -433,12 +453,30 @@ class TypeRefBuilder {
433453
return BuiltinTypeRef::create(*this, mangledName);
434454
}
435455

436-
llvm::Optional<std::string> createTypeDecl(Node *node, bool &typeAlias) {
456+
BuiltTypeDecl createTypeDecl(Node *node, std::vector<size_t> paramsPerLevel) {
457+
auto mangling = Demangle::mangleNode(node);
458+
if (!mangling.isSuccess()) {
459+
return llvm::None;
460+
}
461+
return {{mangling.result(), paramsPerLevel}};
462+
}
463+
464+
BuiltTypeDecl createTypeDecl(std::string &&mangledName,
465+
std::vector<size_t> paramsPerLevel) {
466+
return {{std::move(mangledName), {paramsPerLevel}}};
467+
}
468+
469+
BuiltTypeDecl createTypeDecl(Node *node, bool &typeAlias) {
437470
auto mangling = Demangle::mangleNode(node);
438471
if (!mangling.isSuccess()) {
439472
return llvm::None;
440473
}
441-
return mangling.result();
474+
return {{mangling.result()}};
475+
}
476+
477+
BuiltTypeDecl createTypeDecl(std::string &&mangledName,
478+
bool &typeAlias) {
479+
return {{(mangledName)}};;
442480
}
443481

444482
BuiltProtocolDecl
@@ -455,24 +493,20 @@ class TypeRefBuilder {
455493
return std::make_pair(name, true);
456494
}
457495

458-
llvm::Optional<std::string> createTypeDecl(std::string &&mangledName,
459-
bool &typeAlias) {
460-
return std::move(mangledName);
461-
}
462496

463497
const NominalTypeRef *
464-
createNominalType(const llvm::Optional<std::string> &mangledName) {
465-
return NominalTypeRef::create(*this, *mangledName, nullptr);
498+
createNominalType(const BuiltTypeDecl &typeRefDecl) {
499+
return NominalTypeRef::create(*this, typeRefDecl->mangledName, nullptr);
466500
}
467501

468502
const NominalTypeRef *
469-
createNominalType(const llvm::Optional<std::string> &mangledName,
503+
createNominalType(const BuiltTypeDecl &typeRefDecl,
470504
const TypeRef *parent) {
471-
return NominalTypeRef::create(*this, *mangledName, parent);
505+
return NominalTypeRef::create(*this, typeRefDecl->mangledName, parent);
472506
}
473507

474508
const TypeRef *
475-
createTypeAliasType(const llvm::Optional<std::string> &mangledName,
509+
createTypeAliasType(const BuiltTypeDecl &typeRefDecl,
476510
const TypeRef *parent) {
477511
// TypeRefs don't contain sugared types
478512
return nullptr;
@@ -498,17 +532,75 @@ class TypeRefBuilder {
498532
return nullptr;
499533
}
500534

535+
const BoundGenericTypeRef *createBoundGenericTypeReconstructingParent(
536+
const NodePointer node, const TypeRefDecl &decl, size_t shapeIndex,
537+
const llvm::ArrayRef<const TypeRef *> &args, size_t argsIndex) {
538+
if (!node || !node->hasChildren())
539+
return nullptr;
540+
541+
auto maybeGenericParamsPerLevel = decl.genericParamsPerLevel;
542+
if (!maybeGenericParamsPerLevel)
543+
return nullptr;
544+
545+
auto genericParamsPerLevel = *maybeGenericParamsPerLevel;
546+
547+
auto kind = node->getKind();
548+
// Kinds who have a "BoundGeneric..." variant.
549+
if (kind != Node::Kind::Class && kind != Node::Kind::Structure &&
550+
kind != Node::Kind::Enum && kind != Node::Kind::Protocol &&
551+
kind != Node::Kind::OtherNominalType && kind != Node::Kind::TypeAlias &&
552+
kind != Node::Kind::Function)
553+
return nullptr;
554+
auto mangling = Demangle::mangleNode(node);
555+
if (!mangling.isSuccess())
556+
return nullptr;
557+
558+
auto numGenericArgs = genericParamsPerLevel[shapeIndex];
559+
560+
std::vector<const TypeRef *> genericParams(
561+
args.end() - argsIndex - numGenericArgs, args.end() - argsIndex);
562+
563+
const BoundGenericTypeRef *parent = nullptr;
564+
if (node->hasChildren())
565+
parent = createBoundGenericTypeReconstructingParent(
566+
node->getFirstChild(), decl, --shapeIndex, args, argsIndex + numGenericArgs);
567+
568+
return BoundGenericTypeRef::create(*this, mangling.result(), genericParams,
569+
parent);
570+
}
571+
501572
const BoundGenericTypeRef *
502-
createBoundGenericType(const llvm::Optional<std::string> &mangledName,
503-
const std::vector<const TypeRef *> &args) {
504-
return BoundGenericTypeRef::create(*this, *mangledName, args, nullptr);
573+
createBoundGenericType(const BuiltTypeDecl &builtTypeDecl,
574+
const llvm::ArrayRef<const TypeRef *> &args) {
575+
if (!builtTypeDecl)
576+
return nullptr;
577+
578+
if (!builtTypeDecl->genericParamsPerLevel)
579+
return BoundGenericTypeRef::create(*this, builtTypeDecl->mangledName, args, nullptr);
580+
581+
582+
auto node = Dem.demangleType(builtTypeDecl->mangledName);
583+
if (!node || !node->hasChildren() || node->getKind() != Node::Kind::Type)
584+
return nullptr;
585+
586+
auto type = node->getFirstChild();
587+
return createBoundGenericTypeReconstructingParent(
588+
type, *builtTypeDecl, builtTypeDecl->genericParamsPerLevel->size() - 1, args, 0);
505589
}
506590

507591
const BoundGenericTypeRef *
508-
createBoundGenericType(const llvm::Optional<std::string> &mangledName,
592+
createBoundGenericType(const BuiltTypeDecl &builtTypeDecl,
509593
llvm::ArrayRef<const TypeRef *> args,
510594
const TypeRef *parent) {
511-
return BoundGenericTypeRef::create(*this, *mangledName, args, parent);
595+
if (!builtTypeDecl)
596+
return nullptr;
597+
598+
if (!builtTypeDecl->genericParamsPerLevel)
599+
return BoundGenericTypeRef::create(*this, builtTypeDecl->mangledName, args,
600+
parent);
601+
assert(parent == nullptr &&
602+
"Parent is not null but we're reconstructing the parent!");
603+
return createBoundGenericType(builtTypeDecl, args);
512604
}
513605

514606
const TypeRef *
@@ -627,7 +719,7 @@ class TypeRefBuilder {
627719
if (protocol->second) {
628720
return llvm::cast<TypeRef>(createObjCProtocolType(protocol->first));
629721
} else {
630-
return llvm::cast<TypeRef>(createNominalType(protocol->first));
722+
return llvm::cast<TypeRef>(createNominalType(TypeRefDecl(protocol->first)));
631723
}
632724
}
633725

include/swift/Remote/MetadataReader.h

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/Runtime/HeapObject.h"
3131
#include "swift/Basic/Unreachable.h"
3232

33+
#include <type_traits>
3334
#include <vector>
3435
#include <unordered_map>
3536

@@ -2808,8 +2809,14 @@ class MetadataReader {
28082809

28092810
/// Given a read nominal type descriptor, attempt to build a
28102811
/// nominal type decl from it.
2811-
BuiltTypeDecl
2812-
buildNominalTypeDecl(ContextDescriptorRef descriptor) {
2812+
template <
2813+
typename T = BuilderType,
2814+
typename std::enable_if_t<
2815+
!std::is_same<
2816+
bool,
2817+
decltype(T::needsToPrecomputeParentGenericContextShapes)>::value,
2818+
bool> = true>
2819+
BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) {
28132820
// Build the demangling tree from the context tree.
28142821
Demangler dem;
28152822
auto node = buildContextMangling(descriptor, dem);
@@ -2820,6 +2827,41 @@ class MetadataReader {
28202827
return decl;
28212828
}
28222829

2830+
template <
2831+
typename T = BuilderType,
2832+
typename std::enable_if_t<
2833+
std::is_same<
2834+
bool,
2835+
decltype(T::needsToPrecomputeParentGenericContextShapes)>::value,
2836+
bool> = true>
2837+
BuiltTypeDecl buildNominalTypeDecl(ContextDescriptorRef descriptor) {
2838+
// Build the demangling tree from the context tree.
2839+
Demangler dem;
2840+
auto node = buildContextMangling(descriptor, dem);
2841+
if (!node || node->getKind() != Node::Kind::Type)
2842+
return BuiltTypeDecl();
2843+
std::vector<size_t> paramsPerLevel;
2844+
size_t runningCount = 0;
2845+
std::function<void(ContextDescriptorRef current, size_t &)> countLevels =
2846+
[&](ContextDescriptorRef current, size_t &runningCount) {
2847+
if (auto parentContextRef = readParentContextDescriptor(current))
2848+
if (parentContextRef->isResolved())
2849+
if (auto parentContext = parentContextRef->getResolved())
2850+
countLevels(parentContext, runningCount);
2851+
2852+
auto genericContext = current->getGenericContext();
2853+
if (!genericContext)
2854+
return;
2855+
auto contextHeader = genericContext->getGenericContextHeader();
2856+
2857+
paramsPerLevel.emplace_back(contextHeader.NumParams - runningCount);
2858+
runningCount += paramsPerLevel.back();
2859+
};
2860+
countLevels(descriptor, runningCount);
2861+
BuiltTypeDecl decl = Builder.createTypeDecl(node, paramsPerLevel);
2862+
return decl;
2863+
}
2864+
28232865
#if SWIFT_OBJC_INTEROP
28242866
std::string readObjCProtocolName(StoredPointer Address) {
28252867
auto Size = sizeof(TargetObjCProtocolPrefix<Runtime>);

stdlib/public/Reflection/TypeRef.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,35 @@ class DemanglingForTypeRef
579579
genericNode->addChild(unspecializedType, Dem);
580580
genericNode->addChild(genericArgsList, Dem);
581581

582-
if (auto parent = BG->getParent())
583-
assert(false && "not implemented");
582+
auto parent = BG->getParent();
583+
if (!parent)
584+
return genericNode;
585+
586+
auto parentNode = visit(parent);
587+
if (!parentNode || !parentNode->hasChildren() ||
588+
parentNode->getKind() != Node::Kind::Type ||
589+
!unspecializedType->hasChildren())
590+
return genericNode;
591+
592+
// Peel off the "Type" node.
593+
parentNode = parentNode->getFirstChild();
594+
595+
auto nominalNode = unspecializedType->getFirstChild();
596+
597+
if (nominalNode->getNumChildren() != 2)
598+
return genericNode;
599+
600+
// Save identifier for reinsertion later, we have to remove it
601+
// so we can insert the parent node as the first child.
602+
auto identifierNode = nominalNode->getLastChild();
603+
604+
// Remove all children.
605+
nominalNode->removeChildAt(1);
606+
nominalNode->removeChildAt(0);
607+
608+
// Add the parent we just visited back in, followed by the identifier.
609+
nominalNode->addChild(parentNode, Dem);
610+
nominalNode->addChild(identifierNode, Dem);
584611

585612
return genericNode;
586613
}

0 commit comments

Comments
 (0)