Skip to content

Commit 96a1e07

Browse files
committed
[AST] De/mangling for functions with generic sigs.
1 parent f161fa1 commit 96a1e07

File tree

5 files changed

+160
-91
lines changed

5 files changed

+160
-91
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class ASTBuilder {
5959
using BuiltType = swift::Type;
6060
using BuiltTypeDecl = swift::GenericTypeDecl *; // nominal or type alias
6161
using BuiltProtocolDecl = swift::ProtocolDecl *;
62+
using BuiltSubstitution = std::pair<Type, Type>;
63+
using BuiltRequirement = swift::Requirement;
6264
explicit ASTBuilder(ASTContext &ctx) : Ctx(ctx) {}
6365

6466
ASTContext &getASTContext() { return Ctx; }
@@ -99,11 +101,14 @@ class ASTBuilder {
99101
Type output, FunctionTypeFlags flags);
100102

101103
Type createImplFunctionType(
102-
Demangle::ImplParameterConvention calleeConvention,
103-
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
104-
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
105-
Optional<Demangle::ImplFunctionResult<Type>> errorResult,
106-
ImplFunctionTypeFlags flags);
104+
Demangle::ImplParameterConvention calleeConvention,
105+
BuiltRequirement *witnessMethodConformanceRequirement,
106+
ArrayRef<BuiltType> GenericParameters,
107+
ArrayRef<BuiltRequirement> Requirements,
108+
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
109+
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
110+
Optional<Demangle::ImplFunctionResult<Type>> errorResult,
111+
ImplFunctionTypeFlags flags);
107112

108113
Type createProtocolCompositionType(ArrayRef<ProtocolDecl *> protocols,
109114
Type superclass,
@@ -128,8 +133,6 @@ class ASTBuilder {
128133

129134
Type createSILBoxType(Type base);
130135
using BuiltSILBoxField = llvm::PointerIntPair<Type, 1>;
131-
using BuiltSubstitution = std::pair<Type, Type>;
132-
using BuiltRequirement = swift::Requirement;
133136
using BuiltLayoutConstraint = swift::LayoutConstraint;
134137
Type createSILBoxTypeWithLayout(ArrayRef<BuiltSILBoxField> Fields,
135138
ArrayRef<BuiltSubstitution> Substitutions,

include/swift/Demangling/TypeDecoder.h

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -799,9 +799,12 @@ class TypeDecoder {
799799
}
800800
case NodeKind::ImplFunctionType: {
801801
auto calleeConvention = ImplParameterConvention::Direct_Unowned;
802+
BuiltRequirement *witnessMethodConformanceRequirement = nullptr;
802803
llvm::SmallVector<ImplFunctionParam<BuiltType>, 8> parameters;
803804
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> results;
804805
llvm::SmallVector<ImplFunctionResult<BuiltType>, 8> errorResults;
806+
llvm::SmallVector<BuiltType, 4> genericParameters;
807+
llvm::SmallVector<BuiltRequirement, 4> requirements;
805808
ImplFunctionTypeFlags flags;
806809

807810
for (unsigned i = 0; i < Node->getNumChildren(); i++) {
@@ -834,6 +837,9 @@ class TypeDecoder {
834837
} else if (text == "block") {
835838
flags =
836839
flags.withRepresentation(ImplFunctionRepresentation::Block);
840+
} else if (text == "witness_method") {
841+
flags = flags.withRepresentation(
842+
ImplFunctionRepresentation::WitnessMethod);
837843
}
838844
} else if (child->getKind() == NodeKind::ImplFunctionAttribute) {
839845
if (!child->hasText())
@@ -871,6 +877,27 @@ class TypeDecoder {
871877
if (decodeImplFunctionPart(child, errorResults))
872878
return MAKE_NODE_TYPE_ERROR0(child,
873879
"failed to decode function part");
880+
} else if (child->getKind() == NodeKind::DependentGenericSignature) {
881+
llvm::SmallVector<unsigned, 4> genericParamsAtDepth;
882+
883+
if (auto error = decodeDependentGenericSignatureNode(
884+
child, requirements, genericParamsAtDepth))
885+
return *error;
886+
if (flags.getRepresentation() ==
887+
ImplFunctionRepresentation::WitnessMethod) {
888+
// By convention, the first requirement of a witness method is the
889+
// conformance of Self to the protocol.
890+
witnessMethodConformanceRequirement = &requirements[0];
891+
}
892+
893+
for (unsigned long depth = 0, depths = genericParamsAtDepth.size();
894+
depth < depths; ++depth) {
895+
for (unsigned index = 0; index < genericParamsAtDepth[depth];
896+
++index) {
897+
genericParameters.emplace_back(
898+
Builder.createGenericTypeParameterType(depth, index));
899+
}
900+
}
874901
} else {
875902
return MAKE_NODE_TYPE_ERROR0(child, "unexpected kind");
876903
}
@@ -891,11 +918,11 @@ class TypeDecoder {
891918
// TODO: Some cases not handled above, but *probably* they cannot
892919
// appear as the types of values in SIL (yet?):
893920
// - functions with yield returns
894-
// - functions with generic signatures
895921
// - foreign error conventions
896-
return Builder.createImplFunctionType(calleeConvention,
897-
parameters, results,
898-
errorResult, flags);
922+
return Builder.createImplFunctionType(
923+
calleeConvention, witnessMethodConformanceRequirement,
924+
genericParameters, requirements, parameters, results, errorResult,
925+
flags);
899926
}
900927

901928
case NodeKind::ArgumentTuple:
@@ -1066,35 +1093,12 @@ class TypeDecoder {
10661093
return MAKE_NODE_TYPE_ERROR0(substNode, "expected type list");
10671094

10681095
auto *dependentGenericSignatureNode = Node->getChild(1);
1069-
if (dependentGenericSignatureNode->getKind() !=
1070-
NodeKind::DependentGenericSignature)
1071-
return MAKE_NODE_TYPE_ERROR0(dependentGenericSignatureNode,
1072-
"expected dependent generic signature");
1073-
if (dependentGenericSignatureNode->getNumChildren() < 1)
1074-
return MAKE_NODE_TYPE_ERROR(
1075-
dependentGenericSignatureNode,
1076-
"fewer children (%zu) than required (1)",
1077-
dependentGenericSignatureNode->getNumChildren());
1078-
decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,
1079-
BuilderType>(
1080-
dependentGenericSignatureNode, requirements, Builder/*,
1081-
[&](NodePointer Node) -> BuiltType {
1082-
return decodeMangledType(Node).getType();
1083-
},
1084-
[&](LayoutConstraintKind Kind) -> BuiltLayoutConstraint {
1085-
return {}; // Not implemented!
1086-
},
1087-
[&](LayoutConstraintKind Kind, unsigned SizeInBits,
1088-
unsigned Alignment) -> BuiltLayoutConstraint {
1089-
return {}; // Not Implemented!
1090-
}*/);
1091-
// The number of generic parameters at each depth are in a mini
1092-
// state machine and come first.
10931096
llvm::SmallVector<unsigned, 4> genericParamsAtDepth;
1094-
for (auto *reqNode : *dependentGenericSignatureNode)
1095-
if (reqNode->getKind() == NodeKind::DependentGenericParamCount)
1096-
if (reqNode->hasIndex())
1097-
genericParamsAtDepth.push_back(reqNode->getIndex());
1097+
if (auto error = decodeDependentGenericSignatureNode(
1098+
dependentGenericSignatureNode, requirements,
1099+
genericParamsAtDepth))
1100+
return *error;
1101+
10981102
unsigned depth = 0;
10991103
unsigned index = 0;
11001104
for (auto *subst : *substNode) {
@@ -1444,6 +1448,43 @@ class TypeDecoder {
14441448
params.push_back(std::move(param));
14451449
return true;
14461450
}
1451+
1452+
llvm::Optional<TypeLookupError> decodeDependentGenericSignatureNode(
1453+
NodePointer dependentGenericSignatureNode,
1454+
llvm::SmallVectorImpl<BuiltRequirement> &requirements,
1455+
llvm::SmallVectorImpl<unsigned> &genericParamsAtDepth) {
1456+
using NodeKind = Demangle::Node::Kind;
1457+
if (dependentGenericSignatureNode->getKind() !=
1458+
NodeKind::DependentGenericSignature)
1459+
return llvm::Optional<TypeLookupError>(
1460+
MAKE_NODE_TYPE_ERROR0(dependentGenericSignatureNode,
1461+
"expected dependent generic signature"));
1462+
if (dependentGenericSignatureNode->getNumChildren() < 1)
1463+
return llvm::Optional<TypeLookupError>(MAKE_NODE_TYPE_ERROR(
1464+
dependentGenericSignatureNode,
1465+
"fewer children (%zu) than required (1)",
1466+
dependentGenericSignatureNode->getNumChildren()));
1467+
decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,
1468+
BuilderType>(dependentGenericSignatureNode, requirements,
1469+
Builder /*,
1470+
[&](NodePointer Node) -> BuiltType {
1471+
return decodeMangledType(Node).getType();
1472+
},
1473+
[&](LayoutConstraintKind Kind) -> BuiltLayoutConstraint {
1474+
return {}; // Not implemented!
1475+
},
1476+
[&](LayoutConstraintKind Kind, unsigned SizeInBits,
1477+
unsigned Alignment) -> BuiltLayoutConstraint {
1478+
return {}; // Not Implemented!
1479+
}*/);
1480+
// The number of generic parameters at each depth are in a mini
1481+
// state machine and come first.
1482+
for (auto *reqNode : *dependentGenericSignatureNode)
1483+
if (reqNode->getKind() == NodeKind::DependentGenericParamCount)
1484+
if (reqNode->hasIndex())
1485+
genericParamsAtDepth.push_back(reqNode->getIndex());
1486+
return llvm::None;
1487+
}
14471488
};
14481489

14491490
template <typename BuilderType>

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,14 @@ class TypeRefBuilder {
417417
const TypeRef *result, FunctionTypeFlags flags) {
418418
return FunctionTypeRef::create(*this, params, result, flags);
419419
}
420+
using BuiltSubstitution = std::pair<const TypeRef *, const TypeRef *>;
421+
using BuiltRequirement = TypeRefRequirement;
420422

421423
const FunctionTypeRef *createImplFunctionType(
422424
Demangle::ImplParameterConvention calleeConvention,
425+
BuiltRequirement *witnessMethodConformanceRequirement,
426+
const llvm::SmallVectorImpl<BuiltType> &genericParameters,
427+
const llvm::SmallVectorImpl<BuiltRequirement> &requirements,
423428
llvm::ArrayRef<Demangle::ImplFunctionParam<const TypeRef *>> params,
424429
llvm::ArrayRef<Demangle::ImplFunctionResult<const TypeRef *>> results,
425430
llvm::Optional<Demangle::ImplFunctionResult<const TypeRef *>> errorResult,
@@ -519,8 +524,6 @@ class TypeRefBuilder {
519524
}
520525

521526
using BuiltSILBoxField = typename SILBoxTypeWithLayoutTypeRef::Field;
522-
using BuiltSubstitution = std::pair<const TypeRef *, const TypeRef *>;
523-
using BuiltRequirement = TypeRefRequirement;
524527
using BuiltLayoutConstraint = TypeRefLayoutConstraint;
525528
BuiltLayoutConstraint getLayoutConstraint(LayoutConstraintKind kind) {
526529
// FIXME: Implement this.

lib/AST/ASTDemangler.cpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,24 @@ getResultDifferentiability(ImplResultDifferentiability diffKind) {
478478

479479
Type ASTBuilder::createImplFunctionType(
480480
Demangle::ImplParameterConvention calleeConvention,
481+
BuiltRequirement *witnessMethodConformanceRequirement,
482+
ArrayRef<BuiltType> GenericParameters,
483+
ArrayRef<BuiltRequirement> Requirements,
481484
ArrayRef<Demangle::ImplFunctionParam<Type>> params,
482485
ArrayRef<Demangle::ImplFunctionResult<Type>> results,
483486
Optional<Demangle::ImplFunctionResult<Type>> errorResult,
484487
ImplFunctionTypeFlags flags) {
485488
GenericSignature genericSig;
489+
if (GenericParameters.size() > 0) {
490+
llvm::SmallVector<GenericTypeParamType *, 4> CastGenericParameters;
491+
for (auto Parameter : GenericParameters) {
492+
CastGenericParameters.push_back(
493+
Parameter->castTo<GenericTypeParamType>());
494+
}
495+
genericSig = GenericSignature::get(CastGenericParameters, Requirements);
496+
} else {
497+
assert(Requirements.size() == 0);
498+
}
486499

487500
SILCoroutineKind funcCoroutineKind = SILCoroutineKind::None;
488501
ParameterConvention funcCalleeConvention =
@@ -567,11 +580,15 @@ Type ASTBuilder::createImplFunctionType(
567580
representation, flags.isPseudogeneric(), !flags.isEscaping(),
568581
flags.isConcurrent(), flags.isAsync(), diffKind, clangFnType)
569582
.build();
570-
571-
return SILFunctionType::get(genericSig, einfo, funcCoroutineKind,
572-
funcCalleeConvention, funcParams, funcYields,
573-
funcResults, funcErrorResult,
574-
SubstitutionMap(), SubstitutionMap(), Ctx);
583+
auto witnessMethodConformance =
584+
witnessMethodConformanceRequirement
585+
? ProtocolConformanceRef(
586+
witnessMethodConformanceRequirement->getProtocolDecl())
587+
: ProtocolConformanceRef();
588+
return SILFunctionType::get(
589+
genericSig, einfo, funcCoroutineKind, funcCalleeConvention, funcParams,
590+
funcYields, funcResults, funcErrorResult,
591+
SubstitutionMap(), SubstitutionMap(), Ctx, witnessMethodConformance);
575592
}
576593

577594
Type ASTBuilder::createProtocolCompositionType(

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,8 +1499,58 @@ class DecodedMetadataBuilder {
14991499
result);
15001500
}
15011501

1502+
struct BuiltLayoutConstraint {
1503+
bool operator==(BuiltLayoutConstraint rhs) const { return true; }
1504+
operator bool() const { return true; }
1505+
};
1506+
using BuiltLayoutConstraint = BuiltLayoutConstraint;
1507+
BuiltLayoutConstraint getLayoutConstraint(LayoutConstraintKind kind) {
1508+
return {};
1509+
}
1510+
BuiltLayoutConstraint
1511+
getLayoutConstraintWithSizeAlign(LayoutConstraintKind kind, unsigned size,
1512+
unsigned alignment) {
1513+
return {};
1514+
}
1515+
1516+
#if LLVM_PTR_SIZE == 4
1517+
/// Unfortunately the alignment of TypeRef is too large to squeeze in 3 extra
1518+
/// bits on (some?) 32-bit systems.
1519+
class BigBuiltTypeIntPair {
1520+
BuiltType Ptr;
1521+
RequirementKind Int;
1522+
1523+
public:
1524+
BigBuiltTypeIntPair(BuiltType ptr, RequirementKind i) : Ptr(ptr), Int(i) {}
1525+
RequirementKind getInt() const { return Int; }
1526+
BuiltType getPointer() const { return Ptr; }
1527+
uint64_t getOpaqueValue() const {
1528+
return (uint64_t)Ptr | ((uint64_t)Int << 32);
1529+
}
1530+
};
1531+
#endif
1532+
1533+
struct Requirement : public RequirementBase<BuiltType,
1534+
#if LLVM_PTR_SIZE == 4
1535+
BigBuiltTypeIntPair,
1536+
#else
1537+
llvm::PointerIntPair<BuiltType, 3, RequirementKind>,
1538+
1539+
#endif
1540+
BuiltLayoutConstraint> {
1541+
Requirement(RequirementKind kind, BuiltType first, BuiltType second)
1542+
: RequirementBase(kind, first, second) {}
1543+
Requirement(RequirementKind kind, BuiltType first,
1544+
BuiltLayoutConstraint second)
1545+
: RequirementBase(kind, first, second) {}
1546+
};
1547+
using BuiltRequirement = Requirement;
1548+
15021549
TypeLookupErrorOr<BuiltType> createImplFunctionType(
15031550
Demangle::ImplParameterConvention calleeConvention,
1551+
BuiltRequirement *witnessMethodConformanceRequirement,
1552+
llvm::ArrayRef<BuiltType> genericParameters,
1553+
llvm::ArrayRef<BuiltRequirement> requirements,
15041554
llvm::ArrayRef<Demangle::ImplFunctionParam<BuiltType>> params,
15051555
llvm::ArrayRef<Demangle::ImplFunctionResult<BuiltType>> results,
15061556
llvm::Optional<Demangle::ImplFunctionResult<BuiltType>> errorResult,
@@ -1568,51 +1618,6 @@ class DecodedMetadataBuilder {
15681618

15691619
using BuiltSILBoxField = llvm::PointerIntPair<BuiltType, 1>;
15701620
using BuiltSubstitution = std::pair<BuiltType, BuiltType>;
1571-
struct BuiltLayoutConstraint {
1572-
bool operator==(BuiltLayoutConstraint rhs) const { return true; }
1573-
operator bool() const { return true; }
1574-
};
1575-
using BuiltLayoutConstraint = BuiltLayoutConstraint;
1576-
BuiltLayoutConstraint getLayoutConstraint(LayoutConstraintKind kind) {
1577-
return {};
1578-
}
1579-
BuiltLayoutConstraint
1580-
getLayoutConstraintWithSizeAlign(LayoutConstraintKind kind, unsigned size,
1581-
unsigned alignment) {
1582-
return {};
1583-
}
1584-
1585-
#if LLVM_PTR_SIZE == 4
1586-
/// Unfortunately the alignment of TypeRef is too large to squeeze in 3 extra
1587-
/// bits on (some?) 32-bit systems.
1588-
class BigBuiltTypeIntPair {
1589-
BuiltType Ptr;
1590-
RequirementKind Int;
1591-
public:
1592-
BigBuiltTypeIntPair(BuiltType ptr, RequirementKind i) : Ptr(ptr), Int(i) {}
1593-
RequirementKind getInt() const { return Int; }
1594-
BuiltType getPointer() const { return Ptr; }
1595-
uint64_t getOpaqueValue() const {
1596-
return (uint64_t)Ptr | ((uint64_t)Int << 32);
1597-
}
1598-
};
1599-
#endif
1600-
1601-
struct Requirement : public RequirementBase<BuiltType,
1602-
#if LLVM_PTR_SIZE == 4
1603-
BigBuiltTypeIntPair,
1604-
#else
1605-
llvm::PointerIntPair<BuiltType, 3, RequirementKind>,
1606-
1607-
#endif
1608-
BuiltLayoutConstraint> {
1609-
Requirement(RequirementKind kind, BuiltType first, BuiltType second)
1610-
: RequirementBase(kind, first, second) {}
1611-
Requirement(RequirementKind kind, BuiltType first,
1612-
BuiltLayoutConstraint second)
1613-
: RequirementBase(kind, first, second) {}
1614-
};
1615-
using BuiltRequirement = Requirement;
16161621

16171622
TypeLookupErrorOr<BuiltType> createSILBoxTypeWithLayout(
16181623
llvm::ArrayRef<BuiltSILBoxField> Fields,

0 commit comments

Comments
 (0)