@@ -117,31 +117,31 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
117
117
Site->SiteFuncId = NextFuncId++;
118
118
Site->Inlinee = Inlinee;
119
119
InlinedSubprograms.insert (Inlinee);
120
- recordFuncIdForSubprogram (Inlinee);
120
+ getFuncIdForSubprogram (Inlinee);
121
121
}
122
122
return *Site;
123
123
}
124
124
125
- TypeIndex CodeViewDebug::getGenericFunctionTypeIndex () {
126
- if (VoidFnTyIdx.getIndex () != 0 )
127
- return VoidFnTyIdx;
128
-
129
- ArrayRef<TypeIndex> NoArgs;
130
- ArgListRecord ArgListRec (TypeRecordKind::ArgList, NoArgs);
131
- TypeIndex ArgListIndex = TypeTable.writeArgList (ArgListRec);
125
+ TypeIndex CodeViewDebug::getFuncIdForSubprogram (const DISubprogram *SP) {
126
+ // It's possible to ask for the FuncId of a function which doesn't have a
127
+ // subprogram: inlining a function with debug info into a function with none.
128
+ if (!SP)
129
+ return TypeIndex::Void ();
132
130
133
- ProcedureRecord Procedure (TypeIndex::Void (), CallingConvention::NearC,
134
- FunctionOptions::None, 0 , ArgListIndex);
135
- VoidFnTyIdx = TypeTable.writeProcedure (Procedure);
136
- return VoidFnTyIdx;
137
- }
131
+ // Check if we've already translated this subprogram.
132
+ auto I = TypeIndices.find (SP);
133
+ if (I != TypeIndices.end ())
134
+ return I->second ;
138
135
139
- void CodeViewDebug::recordFuncIdForSubprogram (const DISubprogram *SP) {
140
136
TypeIndex ParentScope = TypeIndex (0 );
141
137
StringRef DisplayName = SP->getDisplayName ();
142
- FuncIdRecord FuncId (ParentScope, getGenericFunctionTypeIndex ( ), DisplayName);
138
+ FuncIdRecord FuncId (ParentScope, getTypeIndex (SP-> getType () ), DisplayName);
143
139
TypeIndex TI = TypeTable.writeFuncId (FuncId);
144
- TypeIndices[SP] = TI;
140
+
141
+ auto InsertResult = TypeIndices.insert ({SP, TI});
142
+ (void )InsertResult;
143
+ assert (InsertResult.second && " DISubprogram lowered twice" );
144
+ return TI;
145
145
}
146
146
147
147
void CodeViewDebug::recordLocalVariable (LocalVariable &&Var,
@@ -495,7 +495,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
495
495
OS.AddComment (" Offset before epilogue" );
496
496
OS.EmitIntValue (0 , 4 );
497
497
OS.AddComment (" Function type index" );
498
- OS.EmitIntValue (0 , 4 );
498
+ OS.EmitIntValue (getFuncIdForSubprogram (GV-> getSubprogram ()). getIndex () , 4 );
499
499
OS.AddComment (" Function section relative address" );
500
500
OS.EmitCOFFSecRel32 (Fn);
501
501
OS.AddComment (" Function section index" );
@@ -744,6 +744,8 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty) {
744
744
case dwarf::DW_TAG_const_type:
745
745
case dwarf::DW_TAG_volatile_type:
746
746
return lowerTypeModifier (cast<DIDerivedType>(Ty));
747
+ case dwarf::DW_TAG_subroutine_type:
748
+ return lowerTypeFunction (cast<DISubroutineType>(Ty));
747
749
default :
748
750
// Use the null type index.
749
751
return TypeIndex ();
@@ -934,6 +936,32 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
934
936
return TypeTable.writeModifier (MR);
935
937
}
936
938
939
+ TypeIndex CodeViewDebug::lowerTypeFunction (const DISubroutineType *Ty) {
940
+ SmallVector<TypeIndex, 8 > ReturnAndArgTypeIndices;
941
+ for (DITypeRef ArgTypeRef : Ty->getTypeArray ())
942
+ ReturnAndArgTypeIndices.push_back (getTypeIndex (ArgTypeRef));
943
+
944
+ TypeIndex ReturnTypeIndex = TypeIndex::Void ();
945
+ ArrayRef<TypeIndex> ArgTypeIndices = None;
946
+ if (!ReturnAndArgTypeIndices.empty ()) {
947
+ auto ReturnAndArgTypesRef = makeArrayRef (ReturnAndArgTypeIndices);
948
+ ReturnTypeIndex = ReturnAndArgTypesRef.front ();
949
+ ArgTypeIndices = ReturnAndArgTypesRef.drop_front ();
950
+ }
951
+
952
+ ArgListRecord ArgListRec (TypeRecordKind::ArgList, ArgTypeIndices);
953
+ TypeIndex ArgListIndex = TypeTable.writeArgList (ArgListRec);
954
+
955
+ // TODO: We should use DW_AT_calling_convention to determine what CC this
956
+ // procedure record should have.
957
+ // TODO: Some functions are member functions, we should use a more appropriate
958
+ // record for those.
959
+ ProcedureRecord Procedure (ReturnTypeIndex, CallingConvention::NearC,
960
+ FunctionOptions::None, ArgTypeIndices.size (),
961
+ ArgListIndex);
962
+ return TypeTable.writeProcedure (Procedure);
963
+ }
964
+
937
965
TypeIndex CodeViewDebug::getTypeIndex (DITypeRef TypeRef) {
938
966
const DIType *Ty = TypeRef.resolve ();
939
967
0 commit comments