@@ -241,25 +241,65 @@ BuiltinTypeInfo::BuiltinTypeInfo(TypeRefBuilder &builder,
241241 builder.readTypeRef(descriptor, descriptor->TypeName)))
242242{}
243243
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 ;
261250 }
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 ;
262282
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+ }
263303
264304bool RecordTypeInfo::readExtraInhabitantIndex (remote::MemoryReader &reader,
265305 remote::RemoteAddress address,
0 commit comments