Skip to content

Commit 0670def

Browse files
committed
Rework OverloadChoice to use PointerEmbeddedInt instead of reimplementing it
in a gross way. Also, handle DeclViaDynamic the same way as DeclViaBridge and DeclViaUnwrappedOptional. Also, OverloadChoiceKind says that TupleIndex must be the last entry in the enum list, so make it the last one (even though this doesn't actually cause a bug right now). All this is just cleanup, NFC.
1 parent e402c10 commit 0670def

File tree

1 file changed

+65
-79
lines changed

1 file changed

+65
-79
lines changed

lib/Sema/OverloadChoice.h

Lines changed: 65 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "llvm/Support/ErrorHandling.h"
2323
#include "swift/AST/Availability.h"
2424
#include "swift/AST/FunctionRefKind.h"
25-
#include "swift/AST/Type.h"
2625
#include "swift/AST/Types.h"
2726

2827
namespace swift {
@@ -47,68 +46,73 @@ enum class OverloadChoiceKind : int {
4746
BaseType,
4847
/// \brief The overload choice selects a key path subscripting operation.
4948
KeyPathApplication,
50-
/// \brief The overload choice indexes into a tuple. Index zero will
51-
/// have the value of this enumerator, index one will have the value of this
52-
/// enumerator + 1, and so on. Thus, this enumerator must always be last.
53-
TupleIndex,
5449
/// \brief The overload choice selects a particular declaration that
5550
/// was found by bridging the base value type to its Objective-C
5651
/// class type.
5752
DeclViaBridge,
5853
/// \brief The overload choice selects a particular declaration that
5954
/// was found by unwrapping an optional context type.
6055
DeclViaUnwrappedOptional,
56+
/// \brief The overload choice indexes into a tuple. Index zero will
57+
/// have the value of this enumerator, index one will have the value of this
58+
/// enumerator + 1, and so on. Thus, this enumerator must always be last.
59+
TupleIndex,
6160
};
6261

6362
/// \brief Describes a particular choice within an overload set.
6463
///
65-
///
6664
class OverloadChoice {
6765
enum : unsigned {
68-
/// Indicates whether this declaration was bridged, turning a
66+
/// Indicates that this is a normal "Decl" kind, or isn't a decl.
67+
IsDecl = 0x00,
68+
/// Indicates that this declaration was bridged, turning a
6969
/// "Decl" kind into "DeclViaBridge" kind.
70-
IsBridgedBit = 0x02,
71-
/// Indicates whether this declaration was resolved by unwrapping an
70+
IsDeclViaBridge = 0x01,
71+
/// Indicates that this declaration was resolved by unwrapping an
7272
/// optional context type, turning a "Decl" kind into
7373
/// "DeclViaUnwrappedOptional".
74-
IsUnwrappedOptionalBit = 0x04,
75-
76-
// IsBridged and IsUnwrappedOptional are mutually exclusive, so there is
77-
// room for another mutually exclusive OverloadChoiceKind to be packed into
78-
// those two bits.
74+
IsDeclViaUnwrappedOptional = 0x02,
75+
/// Indicates that this declaration was dynamic, turning a
76+
/// "Decl" kind into "DeclViaDynamic" kind.
77+
IsDeclViaDynamic = 0x03
7978
};
8079

8180
/// \brief The base type to be used when referencing the declaration
8281
/// along with the two bits above.
83-
llvm::PointerIntPair<Type, 3, unsigned> BaseAndBits;
82+
llvm::PointerIntPair<Type, 3, unsigned> BaseAndDeclKind;
8483

85-
/// \brief Either the declaration pointer (if the low bit is clear) or the
86-
/// overload choice kind shifted two bits with the low bit set.
87-
uintptr_t DeclOrKind;
84+
/// We mash together OverloadChoiceKind with tuple indices into a single
85+
/// integer representation.
86+
typedef llvm::PointerEmbeddedInt<uint32_t, 29>
87+
OverloadChoiceKindWithTupleIndex;
88+
89+
/// \brief Either the declaration pointer or the overload choice kind. The
90+
/// second case is represented as an OverloadChoiceKind, but has additional
91+
/// values at the top end that represent the tuple index.
92+
llvm::PointerUnion<ValueDecl*, OverloadChoiceKindWithTupleIndex> DeclOrKind;
8893

8994
/// The kind of function reference.
9095
/// FIXME: This needs two bits. Can we pack them somewhere?
9196
FunctionRefKind TheFunctionRefKind;
9297

9398
public:
9499
OverloadChoice()
95-
: BaseAndBits(nullptr, 0), DeclOrKind(0),
100+
: BaseAndDeclKind(nullptr, 0), DeclOrKind(0),
96101
TheFunctionRefKind(FunctionRefKind::Unapplied) {}
97102

98103
OverloadChoice(Type base, ValueDecl *value,
99104
FunctionRefKind functionRefKind)
100-
: BaseAndBits(base, 0),
105+
: BaseAndDeclKind(base, 0),
101106
TheFunctionRefKind(functionRefKind) {
102107
assert(!base || !base->hasTypeParameter());
103108
assert((reinterpret_cast<uintptr_t>(value) & (uintptr_t)0x03) == 0 &&
104109
"Badly aligned decl");
105110

106-
DeclOrKind = reinterpret_cast<uintptr_t>(value);
111+
DeclOrKind = value;
107112
}
108113

109114
OverloadChoice(Type base, OverloadChoiceKind kind)
110-
: BaseAndBits(base, 0),
111-
DeclOrKind((uintptr_t)kind << 2 | (uintptr_t)0x03),
115+
: BaseAndDeclKind(base, 0), DeclOrKind(uint32_t(kind)),
112116
TheFunctionRefKind(FunctionRefKind::Unapplied) {
113117
assert(base && "Must have a base type for overload choice");
114118
assert(!base->hasTypeParameter());
@@ -120,28 +124,27 @@ class OverloadChoice {
120124
}
121125

122126
OverloadChoice(Type base, unsigned index)
123-
: BaseAndBits(base, 0),
124-
DeclOrKind(((uintptr_t)index
125-
+ (uintptr_t)OverloadChoiceKind::TupleIndex) << 2
126-
| (uintptr_t)0x03),
127+
: BaseAndDeclKind(base, 0),
128+
DeclOrKind(uint32_t(OverloadChoiceKind::TupleIndex)+index),
127129
TheFunctionRefKind(FunctionRefKind::Unapplied) {
128130
assert(base->getRValueType()->is<TupleType>() && "Must have tuple type");
129131
}
130132

131133
bool isInvalid() const {
132-
return BaseAndBits.getPointer().isNull()
133-
&& BaseAndBits.getInt() == 0
134-
&& DeclOrKind == 0
135-
&& TheFunctionRefKind == FunctionRefKind::Unapplied;
134+
return BaseAndDeclKind.getPointer().isNull() &&
135+
BaseAndDeclKind.getInt() == 0 &&
136+
DeclOrKind.isNull() &&
137+
TheFunctionRefKind == FunctionRefKind::Unapplied;
136138
}
137139

138140
/// Retrieve an overload choice for a declaration that was found via
139141
/// dynamic lookup.
140142
static OverloadChoice getDeclViaDynamic(Type base, ValueDecl *value,
141143
FunctionRefKind functionRefKind) {
142144
OverloadChoice result;
143-
result.BaseAndBits.setPointer(base);
144-
result.DeclOrKind = reinterpret_cast<uintptr_t>(value) | 0x02;
145+
result.BaseAndDeclKind.setPointer(base);
146+
result.BaseAndDeclKind.setInt(IsDeclViaDynamic);
147+
result.DeclOrKind = value;
145148
result.TheFunctionRefKind = functionRefKind;
146149
return result;
147150
}
@@ -151,76 +154,58 @@ class OverloadChoice {
151154
static OverloadChoice getDeclViaBridge(Type base, ValueDecl *value,
152155
FunctionRefKind functionRefKind) {
153156
OverloadChoice result;
154-
result.BaseAndBits.setPointer(base);
155-
result.BaseAndBits.setInt(IsBridgedBit);
156-
result.DeclOrKind = reinterpret_cast<uintptr_t>(value);
157+
result.BaseAndDeclKind.setPointer(base);
158+
result.BaseAndDeclKind.setInt(IsDeclViaBridge);
159+
result.DeclOrKind = value;
157160
result.TheFunctionRefKind = functionRefKind;
158161
return result;
159162
}
160163

161164
/// Retrieve an overload choice for a declaration that was found
162165
/// by unwrapping an optional context type.
163-
static OverloadChoice getDeclViaUnwrappedOptional(
164-
Type base,
165-
ValueDecl *value,
166-
FunctionRefKind functionRefKind) {
166+
static OverloadChoice
167+
getDeclViaUnwrappedOptional(Type base, ValueDecl *value,
168+
FunctionRefKind functionRefKind) {
167169
OverloadChoice result;
168-
result.BaseAndBits.setPointer(base);
169-
result.BaseAndBits.setInt(IsUnwrappedOptionalBit);
170-
result.DeclOrKind = reinterpret_cast<uintptr_t>(value);
170+
result.BaseAndDeclKind.setPointer(base);
171+
result.BaseAndDeclKind.setInt(IsDeclViaUnwrappedOptional);
172+
result.DeclOrKind = value;
171173
result.TheFunctionRefKind = functionRefKind;
172174
return result;
173175
}
174176

175177
/// \brief Retrieve the base type used to refer to the declaration.
176-
Type getBaseType() const { return BaseAndBits.getPointer(); }
178+
Type getBaseType() const {
179+
return BaseAndDeclKind.getPointer();
180+
}
177181

178182
/// \brief Determines the kind of overload choice this is.
179183
OverloadChoiceKind getKind() const {
180-
switch (DeclOrKind & 0x03) {
181-
case 0x00:
182-
if (BaseAndBits.getInt() & IsBridgedBit)
183-
return OverloadChoiceKind::DeclViaBridge;
184-
if (BaseAndBits.getInt() & IsUnwrappedOptionalBit)
184+
if (DeclOrKind.is<ValueDecl*>()) {
185+
switch (BaseAndDeclKind.getInt()) {
186+
case IsDeclViaBridge: return OverloadChoiceKind::DeclViaBridge;
187+
case IsDeclViaDynamic: return OverloadChoiceKind::DeclViaDynamic;
188+
case IsDeclViaUnwrappedOptional:
185189
return OverloadChoiceKind::DeclViaUnwrappedOptional;
186-
187-
return OverloadChoiceKind::Decl;
188-
189-
case 0x02: return OverloadChoiceKind::DeclViaDynamic;
190-
case 0x03: {
191-
uintptr_t value = DeclOrKind >> 2;
192-
if (value >= (uintptr_t)OverloadChoiceKind::TupleIndex)
193-
return OverloadChoiceKind::TupleIndex;
194-
195-
return (OverloadChoiceKind)value;
190+
default: return OverloadChoiceKind::Decl;
191+
}
196192
}
197193

198-
default: llvm_unreachable("basic math has escaped me");
199-
}
194+
uint32_t kind = DeclOrKind.get<OverloadChoiceKindWithTupleIndex>();
195+
if (kind >= (uint32_t)OverloadChoiceKind::TupleIndex)
196+
return OverloadChoiceKind::TupleIndex;
197+
198+
return (OverloadChoiceKind)kind;
200199
}
201200

202201
/// Determine whether this choice is for a declaration.
203202
bool isDecl() const {
204-
switch (getKind()) {
205-
case OverloadChoiceKind::Decl:
206-
case OverloadChoiceKind::DeclViaDynamic:
207-
case OverloadChoiceKind::DeclViaBridge:
208-
case OverloadChoiceKind::DeclViaUnwrappedOptional:
209-
return true;
210-
211-
case OverloadChoiceKind::BaseType:
212-
case OverloadChoiceKind::TupleIndex:
213-
case OverloadChoiceKind::KeyPathApplication:
214-
return false;
215-
}
216-
217-
llvm_unreachable("Unhandled OverloadChoiceKind in switch.");
203+
return DeclOrKind.is<ValueDecl*>();
218204
}
219205

220206
/// \brief Retrieve the declaration that corresponds to this overload choice.
221207
ValueDecl *getDecl() const {
222-
assert(isDecl() && "Not a declaration");
223-
return reinterpret_cast<ValueDecl *>(DeclOrKind & ~(uintptr_t)0x03);
208+
return DeclOrKind.get<ValueDecl*>();
224209
}
225210

226211
/// Get the name of the overload choice.
@@ -230,12 +215,13 @@ class OverloadChoice {
230215
/// choice.
231216
unsigned getTupleIndex() const {
232217
assert(getKind() == OverloadChoiceKind::TupleIndex);
233-
return (DeclOrKind >> 2) - (uintptr_t)OverloadChoiceKind::TupleIndex;
218+
uint32_t kind = DeclOrKind.get<OverloadChoiceKindWithTupleIndex>();
219+
return kind-(uint32_t)OverloadChoiceKind::TupleIndex;
234220
}
235221

236222
/// \brief Retrieves an opaque choice that ignores the base type.
237223
void *getOpaqueChoiceSimple() const {
238-
return reinterpret_cast<void*>(DeclOrKind);
224+
return DeclOrKind.getOpaqueValue();
239225
}
240226

241227
FunctionRefKind getFunctionRefKind() const {

0 commit comments

Comments
 (0)