Skip to content

Commit 735e28b

Browse files
authored
Merge pull request swiftlang#72336 from DougGregor/demangle-inverse-requirements-to-ast
Demangle inverse requirements when building AST types
2 parents 95abb73 + a2ae214 commit 735e28b

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)