@@ -1037,79 +1037,135 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
1037
1037
return DITy;
1038
1038
}
1039
1039
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
+
1045
1051
StringRef Name = Decl->getName ().str ();
1046
1052
unsigned SizeInBits = DbgTy.getSizeInBits ();
1047
1053
// Default, since Swift doesn't allow specifying a custom alignment.
1048
1054
unsigned AlignInBits = 0 ;
1049
1055
1050
- // FIXME: Is DW_TAG_union_type the right thing here?
1051
- // Consider using a DW_TAG_variant_type instead.
1052
1056
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,
1054
1058
llvm::dwarf::DW_LANG_Swift, SizeInBits, AlignInBits, Flags,
1055
1059
MangledName));
1056
1060
1057
1061
auto TH = llvm::TrackingMDNodeRef (FwdDecl.get ());
1058
1062
DITypeCache[DbgTy.getType ()] = TH;
1059
1063
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
+
1060
1074
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;
1061
1118
1119
+ SmallVector<llvm::Metadata *, 16 > Elements;
1062
1120
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.
1067
1121
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.
1082
1124
ArgTy = ElemDecl->getParentEnum ()->mapTypeIntoContext (ArgTy);
1083
1125
auto &TI = IGM.getTypeInfoForUnlowered (ArgTy);
1084
1126
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);
1085
1138
} 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);
1097
1144
}
1098
- unsigned Offset = 0 ;
1099
- auto MTy =
1100
- createMemberType (*ElemDbgTy, ElemDecl->getBaseIdentifier ().str (),
1101
- Offset, Scope, File, Flags);
1102
- Elements.push_back (MTy);
1103
1145
}
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 );
1109
1153
DBuilder.replaceTemporary (std::move (FwdDecl), DITy);
1110
1154
return DITy;
1111
1155
}
1112
1156
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
+
1113
1169
llvm::DIType *getOrCreateDesugaredType (Type Ty, DebugTypeInfo DbgTy) {
1114
1170
DebugTypeInfo BlandDbgTy (Ty, DbgTy.getFragmentStorageType (),
1115
1171
DbgTy.getRawSizeInBits (), DbgTy.getAlignment (),
0 commit comments