Index: lib/CodeGen/AsmPrinter/CodeViewDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/CodeViewDebug.h +++ lib/CodeGen/AsmPrinter/CodeViewDebug.h @@ -117,10 +117,8 @@ /// to be confused with type indices for LF_FUNC_ID records. unsigned NextFuncId = 0; - codeview::TypeIndex VoidFnTyIdx; - - /// Get a type index for a generic void function type. - codeview::TypeIndex getGenericFunctionTypeIndex(); + codeview::TypeIndex + getFunctionTypeIndex(const DISubroutineType *SubroutineTy); InlineSite &getInlineSite(const DILocation *InlinedAt, const DISubprogram *Inlinee); Index: lib/CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -122,24 +122,43 @@ return *Site; } -TypeIndex CodeViewDebug::getGenericFunctionTypeIndex() { - if (VoidFnTyIdx.getIndex() != 0) - return VoidFnTyIdx; +TypeIndex +CodeViewDebug::getFunctionTypeIndex(const DISubroutineType *SubroutineTy) { + // Check if we've already translated this type. + auto I = TypeIndices.find(SubroutineTy); + if (I != TypeIndices.end()) + return I->second; + + SmallVector ReturnAndArgTypeIndices; + for (DITypeRef ArgTypeRef : SubroutineTy->getTypeArray()) + ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); + + TypeIndex ReturnTypeIndex = TypeIndex::Void(); + ArrayRef ArgTypeIndices = None; + if (!ReturnAndArgTypeIndices.empty()) { + auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); + ReturnTypeIndex = ReturnAndArgTypesRef.front(); + ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); + } - ArrayRef NoArgs; - ArgListRecord ArgListRec(TypeRecordKind::ArgList, NoArgs); + ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec); - ProcedureRecord Procedure(TypeIndex::Void(), CallingConvention::NearC, + ProcedureRecord Procedure(ReturnTypeIndex, CallingConvention::NearC, FunctionOptions::None, 0, ArgListIndex); - VoidFnTyIdx = TypeTable.writeProcedure(Procedure); - return VoidFnTyIdx; + TypeIndex TI = TypeTable.writeProcedure(Procedure); + + auto InsertResult = TypeIndices.insert({SubroutineTy, TI}); + (void)InsertResult; + assert(InsertResult.second && "DISubroutineType lowered twice"); + return TI; } void CodeViewDebug::recordFuncIdForSubprogram(const DISubprogram *SP) { TypeIndex ParentScope = TypeIndex(0); StringRef DisplayName = SP->getDisplayName(); - FuncIdRecord FuncId(ParentScope, getGenericFunctionTypeIndex(), DisplayName); + FuncIdRecord FuncId(ParentScope, getFunctionTypeIndex(SP->getType()), + DisplayName); TypeIndex TI = TypeTable.writeFuncId(FuncId); TypeIndices[SP] = TI; } @@ -495,7 +514,11 @@ OS.AddComment("Offset before epilogue"); OS.EmitIntValue(0, 4); OS.AddComment("Function type index"); - OS.EmitIntValue(0, 4); + if (const DISubprogram *Subprogram = GV->getSubprogram()) + OS.EmitIntValue(getFunctionTypeIndex(Subprogram->getType()).getIndex(), + 4); + else + OS.EmitIntValue(0, 4); OS.AddComment("Function section relative address"); OS.EmitCOFFSecRel32(Fn); OS.AddComment("Function section index");