Skip to content

Commit d3587a7

Browse files
authored
Merge pull request #64222 from slavapestov/demangle-variadic-generic-types
Demangling variadic generic types to metadata
2 parents 1b13b59 + d776f71 commit d3587a7

File tree

16 files changed

+940
-479
lines changed

16 files changed

+940
-479
lines changed

include/swift/ABI/Metadata.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4917,6 +4917,8 @@ class TargetPackPointer {
49174917
using PointerType = typename Runtime::template Pointer<const Pointee<Runtime>>;
49184918

49194919
public:
4920+
explicit TargetPackPointer() : Ptr(0) {}
4921+
49204922
explicit TargetPackPointer(typename Runtime::StoredSize rawPtr) : Ptr(rawPtr) {}
49214923

49224924
explicit TargetPackPointer(const void *rawPtr)
@@ -4926,6 +4928,10 @@ class TargetPackPointer {
49264928
: Ptr(reinterpret_cast<typename Runtime::StoredSize>(ptr) |
49274929
(lifetime == PackLifetime::OnHeap ? 1 : 0)) {}
49284930

4931+
explicit operator bool() const {
4932+
return Ptr != 0;
4933+
}
4934+
49294935
// Strips off the LSB.
49304936
const PointerType *getElements() const {
49314937
return reinterpret_cast<const PointerType *>(Ptr & ~1);
@@ -4944,6 +4950,14 @@ class TargetPackPointer {
49444950
PackLifetime getLifetime() const {
49454951
return (bool)(Ptr & 1) ? PackLifetime::OnHeap : PackLifetime::OnStack;
49464952
}
4953+
4954+
// Get the number of elements in the pack, only valid for on-heap packs.
4955+
size_t getNumElements() const {
4956+
if (getLifetime() == PackLifetime::OnHeap)
4957+
return *(reinterpret_cast<const size_t *>(Ptr & ~1) - 1);
4958+
4959+
fatalError(0, "Cannot get length of on-stack pack");
4960+
}
49474961
};
49484962

49494963
/// A pointer to a metadata pack.

include/swift/AST/Requirement.h

Lines changed: 86 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#define SWIFT_AST_REQUIREMENT_H
1919

2020
#include "swift/AST/LayoutConstraint.h"
21-
#include "swift/AST/RequirementBase.h"
21+
#include "swift/AST/RequirementKind.h"
2222
#include "swift/AST/Type.h"
2323
#include "swift/Basic/Debug.h"
2424
#include "llvm/ADT/Hashing.h"
@@ -29,18 +29,97 @@ namespace swift {
2929

3030
/// A single requirement placed on the type parameters (or associated
3131
/// types thereof) of a
32-
class Requirement
33-
: public RequirementBase<Type,
34-
llvm::PointerIntPair<Type, 3, RequirementKind>,
35-
LayoutConstraint> {
32+
class Requirement {
33+
llvm::PointerIntPair<Type, 3, RequirementKind> FirstTypeAndKind;
34+
/// The second element of the requirement. Its content is dependent
35+
/// on the requirement kind.
36+
/// The payload of the following enum should always match the kind!
37+
/// Any access to the fields of this enum should first check if the
38+
/// requested access matches the kind of the requirement.
39+
union {
40+
Type SecondType;
41+
LayoutConstraint SecondLayout;
42+
};
43+
3644
public:
3745
/// Create a conformance or same-type requirement.
3846
Requirement(RequirementKind kind, Type first, Type second)
39-
: RequirementBase(kind, first, second) {}
47+
: FirstTypeAndKind(first, kind), SecondType(second) {
48+
assert(first);
49+
assert(second);
50+
assert(kind != RequirementKind::Layout);
51+
}
4052

4153
/// Create a layout constraint requirement.
4254
Requirement(RequirementKind kind, Type first, LayoutConstraint second)
43-
: RequirementBase(kind, first, second) {}
55+
: FirstTypeAndKind(first, kind), SecondLayout(second) {
56+
assert(first);
57+
assert(second);
58+
assert(kind == RequirementKind::Layout);
59+
}
60+
61+
62+
/// Determine the kind of requirement.
63+
RequirementKind getKind() const { return FirstTypeAndKind.getInt(); }
64+
65+
/// Retrieve the first type.
66+
Type getFirstType() const {
67+
return FirstTypeAndKind.getPointer();
68+
}
69+
70+
/// Retrieve the second type.
71+
Type getSecondType() const {
72+
assert(getKind() != RequirementKind::Layout);
73+
return SecondType;
74+
}
75+
76+
/// Retrieve the layout constraint.
77+
LayoutConstraint getLayoutConstraint() const {
78+
assert(getKind() == RequirementKind::Layout);
79+
return SecondLayout;
80+
}
81+
82+
friend llvm::hash_code hash_value(const Requirement &requirement) {
83+
using llvm::hash_value;
84+
85+
llvm::hash_code first =
86+
hash_value(requirement.FirstTypeAndKind.getOpaqueValue());
87+
llvm::hash_code second;
88+
switch (requirement.getKind()) {
89+
case RequirementKind::SameShape:
90+
case RequirementKind::Conformance:
91+
case RequirementKind::Superclass:
92+
case RequirementKind::SameType:
93+
second = hash_value(requirement.getSecondType());
94+
break;
95+
96+
case RequirementKind::Layout:
97+
second = hash_value(requirement.getLayoutConstraint());
98+
break;
99+
}
100+
101+
return llvm::hash_combine(first, second);
102+
}
103+
104+
friend bool operator==(const Requirement &lhs,
105+
const Requirement &rhs) {
106+
if (lhs.FirstTypeAndKind.getOpaqueValue()
107+
!= rhs.FirstTypeAndKind.getOpaqueValue())
108+
return false;
109+
110+
switch (lhs.getKind()) {
111+
case RequirementKind::SameShape:
112+
case RequirementKind::Conformance:
113+
case RequirementKind::Superclass:
114+
case RequirementKind::SameType:
115+
return lhs.getSecondType().getPointer() ==
116+
rhs.getSecondType().getPointer();
117+
118+
case RequirementKind::Layout:
119+
return lhs.getLayoutConstraint() == rhs.getLayoutConstraint();
120+
}
121+
llvm_unreachable("Unhandled RequirementKind in switch");
122+
}
44123

45124
/// Whether this requirement's types contain ErrorTypes.
46125
bool hasError() const;

include/swift/AST/RequirementBase.h

Lines changed: 0 additions & 144 deletions
This file was deleted.

include/swift/AST/RequirementKind.h

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- RequirementKind.h - Swift RequirementKind AST ---------*- 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 file defines the RequirementKind enum.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_REQUIREMENTKIND_H
18+
#define SWIFT_AST_REQUIREMENTKIND_H
19+
20+
namespace swift {
21+
/// Describes the kind of a requirement that occurs within a requirements
22+
/// clause.
23+
enum class RequirementKind : unsigned {
24+
/// A conformance requirement T : P, where T is a type that depends
25+
/// on a generic parameter and P is a protocol to which T must conform.
26+
Conformance,
27+
/// A superclass requirement T : C, where T is a type that depends
28+
/// on a generic parameter and C is a concrete class type which T must
29+
/// equal or be a subclass of.
30+
Superclass,
31+
/// A same-type requirement T == U, where T and U are types that shall be
32+
/// equivalent.
33+
SameType,
34+
/// A layout bound T : L, where T is a type that depends on a generic
35+
/// parameter and L is some layout specification that should bound T.
36+
Layout,
37+
/// A same-shape requirement shape(T) == shape(U), where T and U are pack
38+
/// parameters.
39+
SameShape
40+
41+
// Note: there is code that packs this enum in a 3-bit bitfield. Audit users
42+
// when adding enumerators.
43+
};
44+
45+
} // namespace swift
46+
#endif

include/swift/Demangling/TypeDecoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "swift/Basic/LLVM.h"
2323
#include "swift/ABI/MetadataValues.h"
2424
#include "swift/AST/LayoutConstraintKind.h"
25-
#include "swift/AST/RequirementBase.h"
25+
#include "swift/AST/RequirementKind.h"
2626
#include "swift/Basic/Unreachable.h"
2727
#include "swift/Demangling/Demangler.h"
2828
#include "swift/Demangling/NamespaceMacros.h"

0 commit comments

Comments
 (0)