13
13
14
14
#include " CodeViewDebug.h"
15
15
#include " llvm/DebugInfo/CodeView/CodeView.h"
16
+ #include " llvm/DebugInfo/CodeView/FieldListRecordBuilder.h"
16
17
#include " llvm/DebugInfo/CodeView/Line.h"
17
18
#include " llvm/DebugInfo/CodeView/SymbolRecord.h"
18
19
#include " llvm/DebugInfo/CodeView/TypeDumper.h"
@@ -138,12 +139,16 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {
138
139
FuncIdRecord FuncId (ParentScope, getTypeIndex (SP->getType ()), DisplayName);
139
140
TypeIndex TI = TypeTable.writeFuncId (FuncId);
140
141
141
- auto InsertResult = TypeIndices.insert ({SP, TI});
142
- (void )InsertResult;
143
- assert (InsertResult.second && " DISubprogram lowered twice" );
142
+ recordTypeIndexForDINode (SP, TI);
144
143
return TI;
145
144
}
146
145
146
+ void CodeViewDebug::recordTypeIndexForDINode (const DINode *Node, TypeIndex TI) {
147
+ auto InsertResult = TypeIndices.insert ({Node, TI});
148
+ (void )InsertResult;
149
+ assert (InsertResult.second && " DINode was already assigned a type index" );
150
+ }
151
+
147
152
void CodeViewDebug::recordLocalVariable (LocalVariable &&Var,
148
153
const DILocation *InlinedAt) {
149
154
if (InlinedAt) {
@@ -746,6 +751,11 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty) {
746
751
return lowerTypeModifier (cast<DIDerivedType>(Ty));
747
752
case dwarf::DW_TAG_subroutine_type:
748
753
return lowerTypeFunction (cast<DISubroutineType>(Ty));
754
+ case dwarf::DW_TAG_class_type:
755
+ case dwarf::DW_TAG_structure_type:
756
+ return lowerTypeClass (cast<DICompositeType>(Ty));
757
+ case dwarf::DW_TAG_union_type:
758
+ return lowerTypeUnion (cast<DICompositeType>(Ty));
749
759
default :
750
760
// Use the null type index.
751
761
return TypeIndex ();
@@ -961,23 +971,206 @@ TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {
961
971
return TypeTable.writeProcedure (Procedure);
962
972
}
963
973
974
+ static MemberAccess translateAccessFlags (unsigned RecordTag,
975
+ const DIType *Member) {
976
+ switch (Member->getFlags () & DINode::FlagAccessibility) {
977
+ case DINode::FlagPrivate: return MemberAccess::Private;
978
+ case DINode::FlagPublic: return MemberAccess::Public;
979
+ case DINode::FlagProtected: return MemberAccess::Protected;
980
+ case 0 :
981
+ // If there was no explicit access control, provide the default for the tag.
982
+ return RecordTag == dwarf::DW_TAG_class_type ? MemberAccess::Private
983
+ : MemberAccess::Public;
984
+ }
985
+ llvm_unreachable (" access flags are exclusive" );
986
+ }
987
+
988
+ static TypeRecordKind getRecordKind (const DICompositeType *Ty) {
989
+ switch (Ty->getTag ()) {
990
+ case dwarf::DW_TAG_class_type: return TypeRecordKind::Class;
991
+ case dwarf::DW_TAG_structure_type: return TypeRecordKind::Struct;
992
+ }
993
+ llvm_unreachable (" unexpected tag" );
994
+ }
995
+
996
+ // / Return the HasUniqueName option if it should be present in ClassOptions, or
997
+ // / None otherwise.
998
+ static ClassOptions getRecordUniqueNameOption (const DICompositeType *Ty) {
999
+ // MSVC always sets this flag now, even for local types. Clang doesn't always
1000
+ // appear to give every type a linkage name, which may be problematic for us.
1001
+ // FIXME: Investigate the consequences of not following them here.
1002
+ return !Ty->getIdentifier ().empty () ? ClassOptions::HasUniqueName
1003
+ : ClassOptions::None;
1004
+ }
1005
+
1006
+ TypeIndex CodeViewDebug::lowerTypeClass (const DICompositeType *Ty) {
1007
+ // First, construct the forward decl. Don't look into Ty to compute the
1008
+ // forward decl options, since it might not be available in all TUs.
1009
+ TypeRecordKind Kind = getRecordKind (Ty);
1010
+ ClassOptions CO =
1011
+ ClassOptions::ForwardReference | getRecordUniqueNameOption (Ty);
1012
+ TypeIndex FwdDeclTI = TypeTable.writeClass (ClassRecord (
1013
+ Kind, 0 , CO, HfaKind::None, WindowsRTClassKind::None, TypeIndex (),
1014
+ TypeIndex (), TypeIndex (), 0 , Ty->getName (), Ty->getIdentifier ()));
1015
+ return FwdDeclTI;
1016
+ }
1017
+
1018
+ TypeIndex CodeViewDebug::lowerCompleteTypeClass (const DICompositeType *Ty) {
1019
+ // Construct the field list and complete type record.
1020
+ TypeRecordKind Kind = getRecordKind (Ty);
1021
+ // FIXME: Other ClassOptions, like ContainsNestedClass and NestedClass.
1022
+ ClassOptions CO = ClassOptions::None | getRecordUniqueNameOption (Ty);
1023
+ TypeIndex FTI;
1024
+ unsigned FieldCount;
1025
+ std::tie (FTI, FieldCount) = lowerRecordFieldList (Ty);
1026
+
1027
+ uint64_t SizeInBytes = Ty->getSizeInBits () / 8 ;
1028
+ return TypeTable.writeClass (ClassRecord (Kind, FieldCount, CO, HfaKind::None,
1029
+ WindowsRTClassKind::None, FTI,
1030
+ TypeIndex (), TypeIndex (), SizeInBytes,
1031
+ Ty->getName (), Ty->getIdentifier ()));
1032
+ // FIXME: Make an LF_UDT_SRC_LINE record.
1033
+ }
1034
+
1035
+ TypeIndex CodeViewDebug::lowerTypeUnion (const DICompositeType *Ty) {
1036
+ ClassOptions CO =
1037
+ ClassOptions::ForwardReference | getRecordUniqueNameOption (Ty);
1038
+ TypeIndex FwdDeclTI =
1039
+ TypeTable.writeUnion (UnionRecord (0 , CO, HfaKind::None, TypeIndex (), 0 ,
1040
+ Ty->getName (), Ty->getIdentifier ()));
1041
+ return FwdDeclTI;
1042
+ }
1043
+
1044
+ TypeIndex CodeViewDebug::lowerCompleteTypeUnion (const DICompositeType *Ty) {
1045
+ ClassOptions CO = ClassOptions::None | getRecordUniqueNameOption (Ty);
1046
+ TypeIndex FTI;
1047
+ unsigned FieldCount;
1048
+ std::tie (FTI, FieldCount) = lowerRecordFieldList (Ty);
1049
+ uint64_t SizeInBytes = Ty->getSizeInBits () / 8 ;
1050
+ return TypeTable.writeUnion (UnionRecord (FieldCount, CO, HfaKind::None, FTI,
1051
+ SizeInBytes, Ty->getName (),
1052
+ Ty->getIdentifier ()));
1053
+ // FIXME: Make an LF_UDT_SRC_LINE record.
1054
+ }
1055
+
1056
+ std::pair<TypeIndex, unsigned >
1057
+ CodeViewDebug::lowerRecordFieldList (const DICompositeType *Ty) {
1058
+ // Manually count members. MSVC appears to count everything that generates a
1059
+ // field list record. Each individual overload in a method overload group
1060
+ // contributes to this count, even though the overload group is a single field
1061
+ // list record.
1062
+ unsigned MemberCount = 0 ;
1063
+ FieldListRecordBuilder Fields;
1064
+ for (const DINode *Element : Ty->getElements ()) {
1065
+ // We assume that the frontend provides all members in source declaration
1066
+ // order, which is what MSVC does.
1067
+ if (!Element)
1068
+ continue ;
1069
+ if (auto *SP = dyn_cast<DISubprogram>(Element)) {
1070
+ // C++ method.
1071
+ // FIXME: Overloaded methods are grouped together, so we'll need two
1072
+ // passes to group them.
1073
+ (void )SP;
1074
+ } else if (auto *Member = dyn_cast<DIDerivedType>(Element)) {
1075
+ if (Member->getTag () == dwarf::DW_TAG_member) {
1076
+ if (Member->isStaticMember ()) {
1077
+ // Static data member.
1078
+ Fields.writeStaticDataMember (StaticDataMemberRecord (
1079
+ translateAccessFlags (Ty->getTag (), Member),
1080
+ getTypeIndex (Member->getBaseType ()), Member->getName ()));
1081
+ MemberCount++;
1082
+ } else {
1083
+ // Data member.
1084
+ // FIXME: Make a BitFieldRecord for bitfields.
1085
+ Fields.writeDataMember (DataMemberRecord (
1086
+ translateAccessFlags (Ty->getTag (), Member),
1087
+ getTypeIndex (Member->getBaseType ()),
1088
+ Member->getOffsetInBits () / 8 , Member->getName ()));
1089
+ MemberCount++;
1090
+ }
1091
+ } else if (Member->getTag () == dwarf::DW_TAG_friend) {
1092
+ // Ignore friend members. It appears that MSVC emitted info about
1093
+ // friends in the past, but modern versions do not.
1094
+ }
1095
+ // FIXME: Get clang to emit nested types here and do something with
1096
+ // them.
1097
+ }
1098
+ // Skip other unrecognized kinds of elements.
1099
+ }
1100
+ return {TypeTable.writeFieldList (Fields), MemberCount};
1101
+ }
1102
+
964
1103
TypeIndex CodeViewDebug::getTypeIndex (DITypeRef TypeRef) {
965
1104
const DIType *Ty = TypeRef.resolve ();
966
1105
967
1106
// The null DIType is the void type. Don't try to hash it.
968
1107
if (!Ty)
969
1108
return TypeIndex::Void ();
970
1109
971
- // Check if we've already translated this type.
1110
+ // Check if we've already translated this type. Don't try to do a
1111
+ // get-or-create style insertion that caches the hash lookup across the
1112
+ // lowerType call. It will update the TypeIndices map.
972
1113
auto I = TypeIndices.find (Ty);
973
1114
if (I != TypeIndices.end ())
974
1115
return I->second ;
975
1116
976
1117
TypeIndex TI = lowerType (Ty);
977
1118
978
- auto InsertResult = TypeIndices.insert ({Ty, TI});
979
- (void )InsertResult;
980
- assert (InsertResult.second && " DIType lowered twice" );
1119
+ recordTypeIndexForDINode (Ty, TI);
1120
+ return TI;
1121
+ }
1122
+
1123
+ TypeIndex CodeViewDebug::getCompleteTypeIndex (DITypeRef TypeRef) {
1124
+ const DIType *Ty = TypeRef.resolve ();
1125
+
1126
+ // The null DIType is the void type. Don't try to hash it.
1127
+ if (!Ty)
1128
+ return TypeIndex::Void ();
1129
+
1130
+ // If this is a non-record type, the complete type index is the same as the
1131
+ // normal type index. Just call getTypeIndex.
1132
+ switch (Ty->getTag ()) {
1133
+ case dwarf::DW_TAG_class_type:
1134
+ case dwarf::DW_TAG_structure_type:
1135
+ case dwarf::DW_TAG_union_type:
1136
+ break ;
1137
+ default :
1138
+ return getTypeIndex (Ty);
1139
+ }
1140
+
1141
+ // Check if we've already translated the complete record type. Lowering a
1142
+ // complete type should never trigger lowering another complete type, so we
1143
+ // can reuse the hash table lookup result.
1144
+ const auto *CTy = cast<DICompositeType>(Ty);
1145
+ auto InsertResult = CompleteTypeIndices.insert ({CTy, TypeIndex ()});
1146
+ if (!InsertResult.second )
1147
+ return InsertResult.first ->second ;
1148
+
1149
+ // Make sure the forward declaration is emitted first. It's unclear if this
1150
+ // is necessary, but MSVC does it, and we should follow suit until we can show
1151
+ // otherwise.
1152
+ TypeIndex FwdDeclTI = getTypeIndex (CTy);
1153
+
1154
+ // Just use the forward decl if we don't have complete type info. This might
1155
+ // happen if the frontend is using modules and expects the complete definition
1156
+ // to be emitted elsewhere.
1157
+ if (CTy->isForwardDecl ())
1158
+ return FwdDeclTI;
1159
+
1160
+ TypeIndex TI;
1161
+ switch (CTy->getTag ()) {
1162
+ case dwarf::DW_TAG_class_type:
1163
+ case dwarf::DW_TAG_structure_type:
1164
+ TI = lowerCompleteTypeClass (CTy);
1165
+ break ;
1166
+ case dwarf::DW_TAG_union_type:
1167
+ TI = lowerCompleteTypeUnion (CTy);
1168
+ break ;
1169
+ default :
1170
+ llvm_unreachable (" not a record" );
1171
+ }
1172
+
1173
+ InsertResult.first ->second = TI;
981
1174
return TI;
982
1175
}
983
1176
@@ -999,7 +1192,7 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
999
1192
Flags |= LocalSymFlags::IsOptimizedOut;
1000
1193
1001
1194
OS.AddComment (" TypeIndex" );
1002
- TypeIndex TI = getTypeIndex (Var.DIVar ->getType ());
1195
+ TypeIndex TI = getCompleteTypeIndex (Var.DIVar ->getType ());
1003
1196
OS.EmitIntValue (TI.getIndex (), 4 );
1004
1197
OS.AddComment (" Flags" );
1005
1198
OS.EmitIntValue (static_cast <uint16_t >(Flags), 2 );
0 commit comments