@@ -1227,37 +1227,43 @@ llvm::DICompositeType *IRGenDebugInfo::createStructType(
1227
1227
1228
1228
// / Return an array with the DITypes for each of an enum's elements.
1229
1229
llvm::DINodeArray IRGenDebugInfo::getEnumElements (DebugTypeInfo DbgTy,
1230
- EnumDecl *D ,
1230
+ EnumDecl *ED ,
1231
1231
llvm::DIScope *Scope,
1232
1232
llvm::DIFile *File,
1233
1233
unsigned Flags) {
1234
1234
SmallVector<llvm::Metadata *, 16 > Elements;
1235
1235
1236
- for (auto *ElemDecl : D ->getAllElements ()) {
1236
+ for (auto *ElemDecl : ED ->getAllElements ()) {
1237
1237
// FIXME <rdar://problem/14845818> Support enums.
1238
- // Swift Enums can be both like DWARF enums and DWARF unions.
1239
- // They should probably be emitted as DW_TAG_variant_type.
1238
+ // Swift Enums can be both like DWARF enums and discriminated unions.
1240
1239
if (ElemDecl->hasType ()) {
1241
- // Use Decl as DeclContext.
1242
1240
DebugTypeInfo ElemDbgTy;
1243
- if (ElemDecl->hasArgumentType ())
1244
- ElemDbgTy = DebugTypeInfo (ElemDecl->getArgumentType (),
1245
- DbgTy.StorageType ,
1246
- DbgTy.size , DbgTy.align , D);
1247
- else
1248
- if (D->hasRawType ())
1249
- ElemDbgTy = DebugTypeInfo (D->getRawType (), DbgTy.StorageType ,
1250
- DbgTy.size , DbgTy.align , D);
1251
- else
1252
- // Fallback to Int as the element type.
1253
- ElemDbgTy = DebugTypeInfo (IGM.Context .getIntDecl ()->getDeclaredType (),
1254
- DbgTy.StorageType ,
1255
- DbgTy.size , DbgTy.align , D);
1241
+ if (ED->hasRawType ())
1242
+ // An enum with a raw type (enum E : Int {}), similar to a
1243
+ // DWARF enum.
1244
+ //
1245
+ // The storage occupied by the enum may be smaller than the
1246
+ // one of the raw type as long as it is large enough to hold
1247
+ // all enum values. Use the raw type for the debug type, but
1248
+ // the storage size from the enum.
1249
+ ElemDbgTy = DebugTypeInfo (ED->getRawType (), DbgTy.StorageType ,
1250
+ DbgTy.size , DbgTy.align , ED);
1251
+ else if (ElemDecl->hasArgumentType ()) {
1252
+ // A discriminated union. This should really be described as a
1253
+ // DW_TAG_variant_type. For now only describing the data.
1254
+ auto &TI = IGM.getTypeInfoForUnlowered (ElemDecl->getArgumentType ());
1255
+ ElemDbgTy = DebugTypeInfo (ElemDecl->getArgumentType (), TI, ED);
1256
+ } else {
1257
+ // Discriminated union case without argument. Fallback to Int
1258
+ // as the element type; there is no storage here.
1259
+ Type IntTy = IGM.Context .getIntDecl ()->getDeclaredType ();
1260
+ ElemDbgTy = DebugTypeInfo (IntTy, DbgTy.StorageType , 0 , 1 , ED);
1261
+ }
1256
1262
unsigned Offset = 0 ;
1257
1263
auto MTy = createMemberType (ElemDbgTy, ElemDecl->getName ().str (), Offset,
1258
1264
Scope, File, Flags);
1259
1265
Elements.push_back (MTy);
1260
- if (D ->isIndirect () || ElemDecl->isIndirect ())
1266
+ if (ED ->isIndirect () || ElemDecl->isIndirect ())
1261
1267
IndirectEnumCases.insert (MTy);
1262
1268
}
1263
1269
}
0 commit comments