22
22
#include " llvm/Support/ErrorHandling.h"
23
23
#include " swift/AST/Availability.h"
24
24
#include " swift/AST/FunctionRefKind.h"
25
- #include " swift/AST/Type.h"
26
25
#include " swift/AST/Types.h"
27
26
28
27
namespace swift {
@@ -47,68 +46,73 @@ enum class OverloadChoiceKind : int {
47
46
BaseType,
48
47
// / \brief The overload choice selects a key path subscripting operation.
49
48
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,
54
49
// / \brief The overload choice selects a particular declaration that
55
50
// / was found by bridging the base value type to its Objective-C
56
51
// / class type.
57
52
DeclViaBridge,
58
53
// / \brief The overload choice selects a particular declaration that
59
54
// / was found by unwrapping an optional context type.
60
55
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,
61
60
};
62
61
63
62
// / \brief Describes a particular choice within an overload set.
64
63
// /
65
- // /
66
64
class OverloadChoice {
67
65
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
69
69
// / "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
72
72
// / optional context type, turning a "Decl" kind into
73
73
// / "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
79
78
};
80
79
81
80
// / \brief The base type to be used when referencing the declaration
82
81
// / along with the two bits above.
83
- llvm::PointerIntPair<Type, 3 , unsigned > BaseAndBits ;
82
+ llvm::PointerIntPair<Type, 3 , unsigned > BaseAndDeclKind ;
84
83
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;
88
93
89
94
// / The kind of function reference.
90
95
// / FIXME: This needs two bits. Can we pack them somewhere?
91
96
FunctionRefKind TheFunctionRefKind;
92
97
93
98
public:
94
99
OverloadChoice ()
95
- : BaseAndBits (nullptr , 0 ), DeclOrKind(0 ),
100
+ : BaseAndDeclKind (nullptr , 0 ), DeclOrKind(0 ),
96
101
TheFunctionRefKind (FunctionRefKind::Unapplied) {}
97
102
98
103
OverloadChoice (Type base, ValueDecl *value,
99
104
FunctionRefKind functionRefKind)
100
- : BaseAndBits (base, 0 ),
105
+ : BaseAndDeclKind (base, 0 ),
101
106
TheFunctionRefKind(functionRefKind) {
102
107
assert (!base || !base->hasTypeParameter ());
103
108
assert ((reinterpret_cast <uintptr_t >(value) & (uintptr_t )0x03 ) == 0 &&
104
109
" Badly aligned decl" );
105
110
106
- DeclOrKind = reinterpret_cast < uintptr_t >( value) ;
111
+ DeclOrKind = value;
107
112
}
108
113
109
114
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)),
112
116
TheFunctionRefKind(FunctionRefKind::Unapplied) {
113
117
assert (base && " Must have a base type for overload choice" );
114
118
assert (!base->hasTypeParameter ());
@@ -120,28 +124,27 @@ class OverloadChoice {
120
124
}
121
125
122
126
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),
127
129
TheFunctionRefKind(FunctionRefKind::Unapplied) {
128
130
assert (base->getRValueType ()->is <TupleType>() && " Must have tuple type" );
129
131
}
130
132
131
133
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;
136
138
}
137
139
138
140
// / Retrieve an overload choice for a declaration that was found via
139
141
// / dynamic lookup.
140
142
static OverloadChoice getDeclViaDynamic (Type base, ValueDecl *value,
141
143
FunctionRefKind functionRefKind) {
142
144
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;
145
148
result.TheFunctionRefKind = functionRefKind;
146
149
return result;
147
150
}
@@ -151,76 +154,58 @@ class OverloadChoice {
151
154
static OverloadChoice getDeclViaBridge (Type base, ValueDecl *value,
152
155
FunctionRefKind functionRefKind) {
153
156
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;
157
160
result.TheFunctionRefKind = functionRefKind;
158
161
return result;
159
162
}
160
163
161
164
// / Retrieve an overload choice for a declaration that was found
162
165
// / 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) {
167
169
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;
171
173
result.TheFunctionRefKind = functionRefKind;
172
174
return result;
173
175
}
174
176
175
177
// / \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
+ }
177
181
178
182
// / \brief Determines the kind of overload choice this is.
179
183
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:
185
189
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
+ }
196
192
}
197
193
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;
200
199
}
201
200
202
201
// / Determine whether this choice is for a declaration.
203
202
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*>();
218
204
}
219
205
220
206
// / \brief Retrieve the declaration that corresponds to this overload choice.
221
207
ValueDecl *getDecl () const {
222
- assert (isDecl () && " Not a declaration" );
223
- return reinterpret_cast <ValueDecl *>(DeclOrKind & ~(uintptr_t )0x03 );
208
+ return DeclOrKind.get <ValueDecl*>();
224
209
}
225
210
226
211
// / Get the name of the overload choice.
@@ -230,12 +215,13 @@ class OverloadChoice {
230
215
// / choice.
231
216
unsigned getTupleIndex () const {
232
217
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;
234
220
}
235
221
236
222
// / \brief Retrieves an opaque choice that ignores the base type.
237
223
void *getOpaqueChoiceSimple () const {
238
- return reinterpret_cast < void *>( DeclOrKind);
224
+ return DeclOrKind. getOpaqueValue ( );
239
225
}
240
226
241
227
FunctionRefKind getFunctionRefKind () const {
0 commit comments