@@ -241,25 +241,65 @@ BuiltinTypeInfo::BuiltinTypeInfo(TypeRefBuilder &builder,
241
241
builder.readTypeRef(descriptor, descriptor->TypeName)))
242
242
{}
243
243
244
- bool
245
- BuiltinTypeInfo::readExtraInhabitantIndex (remote::MemoryReader &reader,
246
- remote::RemoteAddress address,
247
- int *extraInhabitantIndex) const {
248
- if (getNumExtraInhabitants () == 0 ) {
249
- *extraInhabitantIndex = -1 ;
250
- return true ;
251
- }
252
- // If it has extra inhabitants, it must be a pointer. (The only non-pointer
253
- // data with extra inhabitants is a non-payload enum, which doesn't get here.)
254
- if (Name == " yyXf" ) {
255
- // But there are two different conventions, one for function pointers:
256
- return reader.readFunctionPointerExtraInhabitantIndex (address, extraInhabitantIndex);
257
- } else {
258
- // And one for pointers to heap-allocated blocks of memory
259
- return reader.readHeapObjectExtraInhabitantIndex (address, extraInhabitantIndex);
260
- }
244
+ bool BuiltinTypeInfo::readExtraInhabitantIndex (
245
+ remote::MemoryReader &reader, remote::RemoteAddress address,
246
+ int *extraInhabitantIndex) const {
247
+ if (getNumExtraInhabitants () == 0 ) {
248
+ *extraInhabitantIndex = -1 ;
249
+ return true ;
261
250
}
251
+ // If it has extra inhabitants, it could be an integer type with extra
252
+ // inhabitants (a bool) or a pointer.
253
+ // Check if it's an integer first. The mangling of an integer type is
254
+ // type ::= 'Bi' NATURAL '_'
255
+ llvm::StringRef nameRef (Name);
256
+ if (nameRef.startswith (" Bi" ) && nameRef.endswith (" _" )) {
257
+ // Drop the front "Bi" and "_" end, check that what we're left with is a
258
+ // bool.
259
+ llvm::StringRef naturalRef = nameRef.drop_front (2 ).drop_back ();
260
+ uint8_t natural;
261
+ if (naturalRef.getAsInteger (10 , natural))
262
+ return false ;
263
+
264
+ assert (natural == 1 &&
265
+ " Reading extra inhabitants of integer with more than 1 byte!" );
266
+ if (natural != 1 )
267
+ return false ;
268
+
269
+ assert (getSize () == 1 && " Reading extra inhabitants of integer but size of "
270
+ " type info is different than 1!" );
271
+ if (getSize () != 1 )
272
+ return false ;
273
+
274
+ assert (getNumExtraInhabitants () == 254 &&
275
+ " Boolean type info should have 254 extra inhabitants!" );
276
+ if (getNumExtraInhabitants () != 254 )
277
+ return false ;
278
+
279
+ uint8_t rawValue;
280
+ if (!reader.readInteger (address, &rawValue))
281
+ return false ;
262
282
283
+ // The max valid value, for a bool valid values are 0 or 1, so this would
284
+ // be 1.
285
+ auto maxValidValue = 1 ;
286
+ // If the raw value falls outside the range of valid values, this is an
287
+ // extra inhabitant.
288
+ if (maxValidValue < rawValue)
289
+ *extraInhabitantIndex = rawValue - maxValidValue - 1 ;
290
+ else
291
+ *extraInhabitantIndex = -1 ;
292
+ return true ;
293
+ } else if (Name == " yyXf" ) {
294
+ // But there are two different conventions, one for function pointers:
295
+ return reader.readFunctionPointerExtraInhabitantIndex (address,
296
+ extraInhabitantIndex);
297
+ } else {
298
+ // And one for pointers to heap-allocated blocks of memory
299
+ return reader.readHeapObjectExtraInhabitantIndex (address,
300
+ extraInhabitantIndex);
301
+ }
302
+ }
263
303
264
304
bool RecordTypeInfo::readExtraInhabitantIndex (remote::MemoryReader &reader,
265
305
remote::RemoteAddress address,
0 commit comments