summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp62
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h8
2 files changed, 47 insertions, 23 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index cd6a6e32e9b..040bef50f0a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -117,31 +117,31 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
Site->SiteFuncId = NextFuncId++;
Site->Inlinee = Inlinee;
InlinedSubprograms.insert(Inlinee);
- recordFuncIdForSubprogram(Inlinee);
+ getFuncIdForSubprogram(Inlinee);
}
return *Site;
}
-TypeIndex CodeViewDebug::getGenericFunctionTypeIndex() {
- if (VoidFnTyIdx.getIndex() != 0)
- return VoidFnTyIdx;
-
- ArrayRef<TypeIndex> NoArgs;
- ArgListRecord ArgListRec(TypeRecordKind::ArgList, NoArgs);
- TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec);
+TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {
+ // It's possible to ask for the FuncId of a function which doesn't have a
+ // subprogram: inlining a function with debug info into a function with none.
+ if (!SP)
+ return TypeIndex::Void();
- ProcedureRecord Procedure(TypeIndex::Void(), CallingConvention::NearC,
- FunctionOptions::None, 0, ArgListIndex);
- VoidFnTyIdx = TypeTable.writeProcedure(Procedure);
- return VoidFnTyIdx;
-}
+ // Check if we've already translated this subprogram.
+ auto I = TypeIndices.find(SP);
+ if (I != TypeIndices.end())
+ return I->second;
-void CodeViewDebug::recordFuncIdForSubprogram(const DISubprogram *SP) {
TypeIndex ParentScope = TypeIndex(0);
StringRef DisplayName = SP->getDisplayName();
- FuncIdRecord FuncId(ParentScope, getGenericFunctionTypeIndex(), DisplayName);
+ FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);
TypeIndex TI = TypeTable.writeFuncId(FuncId);
- TypeIndices[SP] = TI;
+
+ auto InsertResult = TypeIndices.insert({SP, TI});
+ (void)InsertResult;
+ assert(InsertResult.second && "DISubprogram lowered twice");
+ return TI;
}
void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
@@ -495,7 +495,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
OS.AddComment("Offset before epilogue");
OS.EmitIntValue(0, 4);
OS.AddComment("Function type index");
- OS.EmitIntValue(0, 4);
+ OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4);
OS.AddComment("Function section relative address");
OS.EmitCOFFSecRel32(Fn);
OS.AddComment("Function section index");
@@ -744,6 +744,8 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty) {
case dwarf::DW_TAG_const_type:
case dwarf::DW_TAG_volatile_type:
return lowerTypeModifier(cast<DIDerivedType>(Ty));
+ case dwarf::DW_TAG_subroutine_type:
+ return lowerTypeFunction(cast<DISubroutineType>(Ty));
default:
// Use the null type index.
return TypeIndex();
@@ -934,6 +936,32 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
return TypeTable.writeModifier(MR);
}
+TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {
+ SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices;
+ for (DITypeRef ArgTypeRef : Ty->getTypeArray())
+ ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef));
+
+ TypeIndex ReturnTypeIndex = TypeIndex::Void();
+ ArrayRef<TypeIndex> ArgTypeIndices = None;
+ if (!ReturnAndArgTypeIndices.empty()) {
+ auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices);
+ ReturnTypeIndex = ReturnAndArgTypesRef.front();
+ ArgTypeIndices = ReturnAndArgTypesRef.drop_front();
+ }
+
+ ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
+ TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec);
+
+ // TODO: We should use DW_AT_calling_convention to determine what CC this
+ // procedure record should have.
+ // TODO: Some functions are member functions, we should use a more appropriate
+ // record for those.
+ ProcedureRecord Procedure(ReturnTypeIndex, CallingConvention::NearC,
+ FunctionOptions::None, ArgTypeIndices.size(),
+ ArgListIndex);
+ return TypeTable.writeProcedure(Procedure);
+}
+
TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef) {
const DIType *Ty = TypeRef.resolve();
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index 24d785b8d4b..2cadb61405c 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -117,15 +117,10 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
/// 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();
-
InlineSite &getInlineSite(const DILocation *InlinedAt,
const DISubprogram *Inlinee);
- void recordFuncIdForSubprogram(const DISubprogram *SP);
+ codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP);
static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,
const FunctionInfo &FI,
@@ -195,6 +190,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex lowerTypePointer(const DIDerivedType *Ty);
codeview::TypeIndex lowerTypeMemberPointer(const DIDerivedType *Ty);
codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty);
+ codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty);
public:
CodeViewDebug(AsmPrinter *Asm);
OpenPOWER on IntegriCloud