Skip to content

Commit a2ae214

Browse files
committed
Demangle inverse requirements when building AST types
Extend TypeDecoder with support for inverse requirements, passing them along to the type builder. Then implement support for inverse requirements within the AST demangler, which addresses the round-trip demangling failures we've been seeing. The runtime and remote inspection facilities still need metadata to deal with inverse requirements. Fixes rdar://124564447.
1 parent 77512f8 commit a2ae214

File tree

9 files changed

+213
-35
lines changed

9 files changed

+213
-35
lines changed

include/swift/AST/ASTDemangler.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class ASTBuilder {
8383
using BuiltProtocolDecl = swift::ProtocolDecl *;
8484
using BuiltGenericSignature = swift::GenericSignature;
8585
using BuiltRequirement = swift::Requirement;
86+
using BuiltInverseRequirement = swift::InverseRequirement;
8687
using BuiltSubstitutionMap = swift::SubstitutionMap;
8788

8889
static constexpr bool needsToPrecomputeParentGenericContextShapes = false;
@@ -161,8 +162,10 @@ class ASTBuilder {
161162

162163
Type createProtocolTypeFromDecl(ProtocolDecl *protocol);
163164

164-
Type createConstrainedExistentialType(Type base,
165-
ArrayRef<BuiltRequirement> constraints);
165+
Type createConstrainedExistentialType(
166+
Type base,
167+
ArrayRef<BuiltRequirement> constraints,
168+
ArrayRef<BuiltInverseRequirement> inverseRequirements);
166169

167170
Type createSymbolicExtendedExistentialType(NodePointer shapeNode,
168171
ArrayRef<Type> genArgs);
@@ -193,9 +196,11 @@ class ASTBuilder {
193196
using BuiltSILBoxField = llvm::PointerIntPair<Type, 1>;
194197
using BuiltSubstitution = std::pair<Type, Type>;
195198
using BuiltLayoutConstraint = swift::LayoutConstraint;
196-
Type createSILBoxTypeWithLayout(ArrayRef<BuiltSILBoxField> Fields,
197-
ArrayRef<BuiltSubstitution> Substitutions,
198-
ArrayRef<BuiltRequirement> Requirements);
199+
Type createSILBoxTypeWithLayout(
200+
ArrayRef<BuiltSILBoxField> Fields,
201+
ArrayRef<BuiltSubstitution> Substitutions,
202+
ArrayRef<BuiltRequirement> Requirements,
203+
ArrayRef<BuiltInverseRequirement> inverseRequirements);
199204

200205
bool isExistential(Type type) {
201206
return type->isExistentialType();
@@ -238,6 +243,9 @@ class ASTBuilder {
238243
unsigned size,
239244
unsigned alignment);
240245

246+
InverseRequirement createInverseRequirement(
247+
Type subject, InvertibleProtocolKind kind);
248+
241249
private:
242250
bool validateParentType(TypeDecl *decl, Type parent);
243251
CanGenericSignature demangleGenericSignature(
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===--- InvertibleProtocolKind.h - -----------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This header declares the InvertibleProtocolKind enum and some
14+
// related operations.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_AST_INVERTIBLEPROTOCOLKIND_H
19+
#define SWIFT_AST_INVERTIBLEPROTOCOLKIND_H
20+
21+
#include <stdint.h>
22+
23+
namespace swift {
24+
25+
enum class InvertibleProtocolKind : uint8_t {
26+
#define INVERTIBLE_PROTOCOL_WITH_NAME(Id, Name) Id,
27+
#include "swift/AST/KnownProtocols.def"
28+
};
29+
30+
31+
} // end namespace swift
32+
33+
#endif // SWIFT_AST_INVERTIBLEPROTOCOLKIND_H

include/swift/AST/KnownProtocols.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "swift/Basic/InlineBitfield.h"
1717
#include "swift/Basic/FixedBitSet.h"
18+
#include "swift/AST/InvertibleProtocolKind.h"
1819
#include "swift/Config.h"
1920

2021
namespace llvm {
@@ -57,11 +58,6 @@ enum : uint8_t {
5758
#include "swift/AST/KnownProtocols.def"
5859
};
5960

60-
enum class InvertibleProtocolKind : uint8_t {
61-
#define INVERTIBLE_PROTOCOL_WITH_NAME(Id, Name) Id,
62-
#include "swift/AST/KnownProtocols.def"
63-
};
64-
6561
using InvertibleProtocolSet = FixedBitSet<NumInvertibleProtocols,
6662
InvertibleProtocolKind>;
6763

include/swift/Demangling/TypeDecoder.h

Lines changed: 55 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "swift/Basic/LLVM.h"
2323

2424
#include "swift/ABI/MetadataValues.h"
25+
#include "swift/AST/InvertibleProtocolKind.h"
2526
#include "swift/AST/LayoutConstraintKind.h"
2627
#include "swift/AST/RequirementKind.h"
2728
#include "swift/Basic/OptionSet.h"
@@ -422,10 +423,13 @@ getObjCClassOrProtocolName(NodePointer node) {
422423
#endif
423424

424425
template <typename BuiltType, typename BuiltRequirement,
426+
typename BuiltInverseRequirement,
425427
typename BuiltLayoutConstraint, typename BuilderType>
426-
void decodeRequirement(NodePointer node,
427-
llvm::SmallVectorImpl<BuiltRequirement> &requirements,
428-
BuilderType &Builder) {
428+
void decodeRequirement(
429+
NodePointer node,
430+
llvm::SmallVectorImpl<BuiltRequirement> &requirements,
431+
llvm::SmallVectorImpl<BuiltInverseRequirement> &inverseRequirements,
432+
BuilderType &Builder) {
429433
for (auto &child : *node) {
430434
if (child->getKind() == Demangle::Node::Kind::DependentGenericParamCount ||
431435
child->getKind() == Demangle::Node::Kind::DependentGenericParamPackMarker)
@@ -451,9 +455,40 @@ void decodeRequirement(NodePointer node,
451455
return;
452456
} else if (child->getKind() ==
453457
Demangle::Node::Kind::DependentGenericInverseConformanceRequirement) {
454-
// FIXME(kavon): this is unimplemented! We should build a PCT here with
455-
// the inverse in it.
456-
return;
458+
// Type child
459+
auto constraintNode = child->getChild(1);
460+
if (constraintNode->getKind() != Demangle::Node::Kind::Type ||
461+
constraintNode->getNumChildren() != 1)
462+
return;
463+
464+
// Protocol child
465+
auto protocolNode = constraintNode->getChild(0);
466+
if (protocolNode->getKind() != Demangle::Node::Kind::Protocol ||
467+
protocolNode->getNumChildren() != 2)
468+
return;
469+
470+
auto moduleNode = protocolNode->getChild(0);
471+
if (moduleNode->getKind() != Demangle::Node::Kind::Module ||
472+
moduleNode->getText() != "Swift")
473+
return;
474+
475+
auto protocolNameNode = protocolNode->getChild(1);
476+
if (protocolNameNode->getKind() != Demangle::Node::Kind::Identifier)
477+
return;
478+
479+
auto protocolName = protocolNameNode->getText();
480+
using OptInvertibleKind = std::optional<InvertibleProtocolKind>;
481+
auto protocolKind = llvm::StringSwitch<OptInvertibleKind>(protocolName)
482+
#define INVERTIBLE_PROTOCOL_WITH_NAME(Id, Name) \
483+
.Case(Name, InvertibleProtocolKind::Id)
484+
#include "swift/AST/KnownProtocols.def"
485+
.Default(std::nullopt);
486+
if (!protocolKind)
487+
return;
488+
489+
inverseRequirements.push_back(
490+
Builder.createInverseRequirement(subjectType, *protocolKind));
491+
continue;
457492
}
458493

459494

@@ -538,6 +573,7 @@ class TypeDecoder {
538573
using Field = typename BuilderType::BuiltSILBoxField;
539574
using BuiltSubstitution = typename BuilderType::BuiltSubstitution;
540575
using BuiltRequirement = typename BuilderType::BuiltRequirement;
576+
using BuiltInverseRequirement = typename BuilderType::BuiltInverseRequirement;
541577
using BuiltLayoutConstraint = typename BuilderType::BuiltLayoutConstraint;
542578
using BuiltGenericSignature = typename BuilderType::BuiltGenericSignature;
543579
using BuiltSubstitutionMap = typename BuilderType::BuiltSubstitutionMap;
@@ -800,16 +836,19 @@ class TypeDecoder {
800836
return protocolType;
801837

802838
llvm::SmallVector<BuiltRequirement, 8> requirements;
839+
llvm::SmallVector<BuiltInverseRequirement, 8> inverseRequirements;
803840

804841
auto *reqts = Node->getChild(1);
805842
if (reqts->getKind() != NodeKind::ConstrainedExistentialRequirementList)
806843
return MAKE_NODE_TYPE_ERROR0(reqts, "is not requirement list");
807844

808-
decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,
809-
BuilderType>(reqts, requirements, Builder);
845+
decodeRequirement<BuiltType, BuiltRequirement, BuiltInverseRequirement,
846+
BuiltLayoutConstraint, BuilderType>(
847+
reqts, requirements, inverseRequirements, Builder);
810848

811849
return Builder.createConstrainedExistentialType(protocolType.getType(),
812-
requirements);
850+
requirements,
851+
inverseRequirements);
813852
}
814853
case NodeKind::ConstrainedExistentialSelf:
815854
return Builder.createGenericTypeParameterType(/*depth*/ 0, /*index*/ 0);
@@ -1280,6 +1319,7 @@ class TypeDecoder {
12801319
llvm::SmallVector<Field, 4> fields;
12811320
llvm::SmallVector<BuiltSubstitution, 4> substitutions;
12821321
llvm::SmallVector<BuiltRequirement, 4> requirements;
1322+
llvm::SmallVector<BuiltInverseRequirement, 8> inverseRequirements;
12831323
llvm::SmallVector<BuiltType, 4> genericParams;
12841324

12851325
if (Node->getNumChildren() < 1)
@@ -1332,10 +1372,10 @@ class TypeDecoder {
13321372
}
13331373

13341374
// Decode requirements.
1335-
decodeRequirement<BuiltType, BuiltRequirement, BuiltLayoutConstraint,
1336-
BuilderType>(dependentGenericSignatureNode,
1337-
requirements,
1338-
Builder);
1375+
decodeRequirement<BuiltType, BuiltRequirement, BuiltInverseRequirement,
1376+
BuiltLayoutConstraint, BuilderType>(
1377+
dependentGenericSignatureNode, requirements, inverseRequirements,
1378+
Builder);
13391379

13401380
// Decode substitutions.
13411381
for (unsigned i = 0, e = substNode->getNumChildren(); i < e; ++i) {
@@ -1373,7 +1413,8 @@ class TypeDecoder {
13731413
}
13741414

13751415
return Builder.createSILBoxTypeWithLayout(fields, substitutions,
1376-
requirements);
1416+
requirements,
1417+
inverseRequirements);
13771418
}
13781419
case NodeKind::SugaredOptional: {
13791420
if (Node->getNumChildren() < 1)

include/swift/RemoteInspection/TypeRef.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,25 @@ class TypeRefRequirement {
192192
}
193193
};
194194

195+
class TypeRefInverseRequirement {
196+
llvm::PointerIntPair<const TypeRef *, 3, InvertibleProtocolKind> Storage;
197+
198+
public:
199+
TypeRefInverseRequirement(const TypeRef *first, InvertibleProtocolKind proto)
200+
: Storage(first, proto) {
201+
assert(first);
202+
}
203+
204+
/// Retrieve the first type.
205+
const TypeRef *getFirstType() const {
206+
return Storage.getPointer();
207+
}
208+
209+
/// Determine the kind of requirement.
210+
InvertibleProtocolKind getKind() const { return Storage.getInt(); }
211+
};
212+
213+
195214
// On 32-bit systems this needs more than just pointer alignment to fit the
196215
// extra bits needed by TypeRefRequirement.
197216
class alignas(8) TypeRef {

include/swift/RemoteInspection/TypeRefBuilder.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ class TypeRefBuilder {
389389
std::optional<std::pair<std::string, bool /*isObjC*/>>;
390390
using BuiltSubstitution = std::pair<const TypeRef *, const TypeRef *>;
391391
using BuiltRequirement = TypeRefRequirement;
392+
using BuiltInverseRequirement = TypeRefInverseRequirement;
392393
using BuiltLayoutConstraint = TypeRefLayoutConstraint;
393394
using BuiltGenericTypeParam = const GenericTypeParameterTypeRef *;
394395
using BuiltGenericSignature = const GenericSignatureRef *;
@@ -1221,7 +1222,9 @@ class TypeRefBuilder {
12211222
}
12221223

12231224
const ConstrainedExistentialTypeRef *createConstrainedExistentialType(
1224-
const TypeRef *base, llvm::ArrayRef<BuiltRequirement> constraints) {
1225+
const TypeRef *base, llvm::ArrayRef<BuiltRequirement> constraints,
1226+
llvm::ArrayRef<BuiltInverseRequirement> InverseRequirements) {
1227+
// FIXME: Handle inverse requirements.
12251228
auto *baseProto = llvm::dyn_cast<ProtocolCompositionTypeRef>(base);
12261229
if (!baseProto)
12271230
return nullptr;
@@ -1295,10 +1298,17 @@ class TypeRefBuilder {
12951298
return {};
12961299
}
12971300

1301+
BuiltInverseRequirement createInverseRequirement(
1302+
const TypeRef *subject, InvertibleProtocolKind proto) {
1303+
return TypeRefInverseRequirement(subject, proto);
1304+
}
1305+
12981306
const SILBoxTypeWithLayoutTypeRef *createSILBoxTypeWithLayout(
12991307
const llvm::SmallVectorImpl<BuiltSILBoxField> &Fields,
13001308
const llvm::SmallVectorImpl<BuiltSubstitution> &Substitutions,
1301-
const llvm::SmallVectorImpl<BuiltRequirement> &Requirements) {
1309+
const llvm::SmallVectorImpl<BuiltRequirement> &Requirements,
1310+
llvm::ArrayRef<BuiltInverseRequirement> InverseRequirements) {
1311+
// FIXME: Handle inverse requirements.
13021312
return SILBoxTypeWithLayoutTypeRef::create(*this, Fields, Substitutions,
13031313
Requirements);
13041314
}

0 commit comments

Comments
 (0)