@@ -1037,79 +1037,135 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
10371037 return DITy;
10381038 }
10391039
1040- llvm::DICompositeType *createEnumType (CompletedDebugTypeInfo DbgTy,
1041- EnumDecl *Decl, StringRef MangledName,
1042- llvm::DIScope *Scope,
1043- llvm::DIFile *File, unsigned Line,
1044- llvm::DINode::DIFlags Flags) {
1040+ // / Create debug information for an enum with a raw type (enum E : Int {}).
1041+ llvm::DICompositeType *createRawEnumType (CompletedDebugTypeInfo DbgTy,
1042+ EnumDecl *Decl,
1043+ StringRef MangledName,
1044+ llvm::DIScope *Scope,
1045+ llvm::DIFile *File, unsigned Line,
1046+ llvm::DINode::DIFlags Flags) {
1047+ assert (
1048+ Decl->hasRawType () &&
1049+ " Trying to create a raw enum debug info from enum with no raw type!" );
1050+
10451051 StringRef Name = Decl->getName ().str ();
10461052 unsigned SizeInBits = DbgTy.getSizeInBits ();
10471053 // Default, since Swift doesn't allow specifying a custom alignment.
10481054 unsigned AlignInBits = 0 ;
10491055
1050- // FIXME: Is DW_TAG_union_type the right thing here?
1051- // Consider using a DW_TAG_variant_type instead.
10521056 auto FwdDecl = llvm::TempDIType (DBuilder.createReplaceableCompositeType (
1053- llvm::dwarf::DW_TAG_union_type , MangledName, Scope, File, Line,
1057+ llvm::dwarf::DW_TAG_enumeration_type , MangledName, Scope, File, Line,
10541058 llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
10551059 MangledName));
10561060
10571061 auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
10581062 DITypeCache[DbgTy.getType ()] = TH;
10591063
1064+ auto RawType = Decl->getRawType ();
1065+ auto &TI = IGM.getTypeInfoForUnlowered (RawType);
1066+ llvm::Optional<CompletedDebugTypeInfo> ElemDbgTy =
1067+ CompletedDebugTypeInfo::getFromTypeInfo (RawType, TI, IGM);
1068+ if (!ElemDbgTy)
1069+ // Without complete type info we can only create a forward decl.
1070+ return DBuilder.createForwardDecl (
1071+ llvm::dwarf::DW_TAG_enumeration_type, Name, Scope, File, Line,
1072+ llvm::dwarf::DW_LANG_Swift, SizeInBits, 0 , MangledName);
1073+
10601074 SmallVector<llvm::Metadata *, 16 > Elements;
1075+ for (auto *ElemDecl : Decl->getAllElements ()) {
1076+ // TODO: add the option to emit an enumerator with no value, and use that
1077+ // instead of emitting a 0.
1078+ auto MTy =
1079+ DBuilder.createEnumerator (ElemDecl->getBaseIdentifier ().str (), 0 );
1080+ Elements.push_back (MTy);
1081+ }
1082+
1083+ auto EnumType = getOrCreateType (*ElemDbgTy);
1084+ auto DITy = DBuilder.createEnumerationType (
1085+ Scope, Name, File, Line, SizeInBits, AlignInBits,
1086+ DBuilder.getOrCreateArray (Elements), EnumType,
1087+ llvm::dwarf::DW_LANG_Swift, MangledName, false );
1088+
1089+ DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
1090+ return DITy;
1091+ }
1092+
1093+ // Create debug information for an enum with no raw type.
1094+ llvm::DICompositeType *createVariantType (CompletedDebugTypeInfo DbgTy,
1095+ EnumDecl *Decl,
1096+ StringRef MangledName,
1097+ llvm::DIScope *Scope,
1098+ llvm::DIFile *File, unsigned Line,
1099+ llvm::DINode::DIFlags Flags) {
1100+ assert (!Decl->getRawType () &&
1101+ " Attempting to create variant debug info from raw enum!" );
1102+
1103+ StringRef Name = Decl->getName ().str ();
1104+ unsigned SizeInBits = DbgTy.getSizeInBits ();
1105+ // Default, since Swift doesn't allow specifying a custom alignment.
1106+ unsigned AlignInBits = 0 ;
1107+ auto NumExtraInhabitants = DbgTy.getNumExtraInhabitants ();
1108+
1109+ // A variant part should actually be a child to a DW_TAG_structure_type
1110+ // according to the DWARF spec.
1111+ auto FwdDecl = llvm::TempDIType (DBuilder.createReplaceableCompositeType (
1112+ llvm::dwarf::DW_TAG_structure_type, MangledName, Scope, File, Line,
1113+ llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1114+ MangledName));
1115+
1116+ auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
1117+ DITypeCache[DbgTy.getType ()] = TH;
10611118
1119+ SmallVector<llvm::Metadata *, 16 > Elements;
10621120 for (auto *ElemDecl : Decl->getAllElements ()) {
1063- // FIXME <rdar://problem/14845818> Support enums.
1064- // Swift Enums can be both like DWARF enums and discriminated unions.
1065- // LLVM now supports variant types in debug metadata, which may be a
1066- // better fit.
10671121 llvm::Optional<CompletedDebugTypeInfo> ElemDbgTy;
1068- if (Decl->hasRawType ()) {
1069- // An enum with a raw type (enum E : Int {}), similar to a
1070- // DWARF enum.
1071- //
1072- // The storage occupied by the enum may be smaller than the
1073- // one of the raw type as long as it is large enough to hold
1074- // all enum values. Use the raw type for the debug type, but
1075- // the storage size from the enum.
1076- auto RawType = Decl->getRawType ();
1077- auto &TI = IGM.getTypeInfoForUnlowered (RawType);
1078- ElemDbgTy = CompletedDebugTypeInfo::getFromTypeInfo (RawType, TI, IGM);
1079- } else if (auto ArgTy = ElemDecl->getArgumentInterfaceType ()) {
1080- // A discriminated union. This should really be described as a
1081- // DW_TAG_variant_type. For now only describing the data.
1122+ if (auto ArgTy = ElemDecl->getArgumentInterfaceType ()) {
1123+ // A variant case which carries a payload.
10821124 ArgTy = ElemDecl->getParentEnum ()->mapTypeIntoContext (ArgTy);
10831125 auto &TI = IGM.getTypeInfoForUnlowered (ArgTy);
10841126 ElemDbgTy = CompletedDebugTypeInfo::getFromTypeInfo (ArgTy, TI, IGM);
1127+ if (!ElemDbgTy) {
1128+ // Without complete type info we can only create a forward decl.
1129+ return DBuilder.createForwardDecl (
1130+ llvm::dwarf::DW_TAG_structure_type, Name, Scope, File, Line,
1131+ llvm::dwarf::DW_LANG_Swift, SizeInBits, 0 , MangledName);
1132+ }
1133+ unsigned Offset = 0 ;
1134+ auto MTy =
1135+ createMemberType (*ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
1136+ Offset, Scope, File, Flags);
1137+ Elements.push_back (MTy);
10851138 } else {
1086- // Discriminated union case without argument. Fallback to Int
1087- // as the element type; there is no storage here.
1088- Type IntTy = IGM.Context .getIntType ();
1089- auto &TI = IGM.getTypeInfoForUnlowered (IntTy);
1090- ElemDbgTy = CompletedDebugTypeInfo::getFromTypeInfo (IntTy, TI, IGM);
1091- }
1092- if (!ElemDbgTy) {
1093- // Without complete type info we can only create a forward decl.
1094- return DBuilder.createForwardDecl (
1095- llvm::dwarf::DW_TAG_union_type, Name, Scope, File, Line,
1096- llvm::dwarf::DW_LANG_Swift, SizeInBits, 0 , MangledName);
1139+ // A variant with no payload.
1140+ auto MTy = DBuilder.createMemberType (
1141+ Scope, ElemDecl->getBaseIdentifier ().str (), File, 0 , 0 , 0 , 0 , Flags,
1142+ nullptr );
1143+ Elements.push_back (MTy);
10971144 }
1098- unsigned Offset = 0 ;
1099- auto MTy =
1100- createMemberType (*ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
1101- Offset, Scope, File, Flags);
1102- Elements.push_back (MTy);
11031145 }
1104- auto DITy = DBuilder.createUnionType (
1105- Scope, Name, File, Line, SizeInBits, AlignInBits,
1106- Flags, DBuilder.getOrCreateArray (Elements),
1107- llvm::dwarf::DW_LANG_Swift, MangledName);
1108-
1146+ auto VPTy = DBuilder.createVariantPart (Scope, {}, File, Line, SizeInBits,
1147+ AlignInBits, Flags, nullptr ,
1148+ DBuilder.getOrCreateArray (Elements));
1149+ auto DITy = DBuilder.createStructType (
1150+ Scope, Name, File, Line, SizeInBits, AlignInBits, Flags, nullptr ,
1151+ DBuilder.getOrCreateArray (VPTy), llvm::dwarf::DW_LANG_Swift, nullptr ,
1152+ MangledName, NumExtraInhabitants ? *NumExtraInhabitants : 0 );
11091153 DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
11101154 return DITy;
11111155 }
11121156
1157+ llvm::DICompositeType *createEnumType (CompletedDebugTypeInfo DbgTy,
1158+ EnumDecl *Decl, StringRef MangledName,
1159+ llvm::DIScope *Scope,
1160+ llvm::DIFile *File, unsigned Line,
1161+ llvm::DINode::DIFlags Flags) {
1162+ if (Decl->hasRawType ())
1163+ return createRawEnumType (DbgTy, Decl, MangledName, Scope, File, Line,
1164+ Flags);
1165+ return createVariantType (DbgTy, Decl, MangledName, Scope, File, Line,
1166+ Flags);
1167+ }
1168+
11131169 llvm::DIType *getOrCreateDesugaredType (Type Ty, DebugTypeInfo DbgTy) {
11141170 DebugTypeInfo BlandDbgTy (Ty, DbgTy.getFragmentStorageType (),
11151171 DbgTy.getRawSizeInBits (), DbgTy.getAlignment (),
0 commit comments