[CodeView] Implement function-type indices

We still need to do something about member functions and calling
conventions.

Differential Revision: http://reviews.llvm.org/D20900

llvm-svn: 271541
This commit is contained in:
David Majnemer 2016-06-02 17:13:53 +00:00
parent 49471dfb31
commit 75c3ebfa02
8 changed files with 116 additions and 46 deletions

View File

@ -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;
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();
ArrayRef<TypeIndex> NoArgs;
ArgListRecord ArgListRec(TypeRecordKind::ArgList, NoArgs);
TypeIndex ArgListIndex = TypeTable.writeArgList(ArgListRec);
// Check if we've already translated this subprogram.
auto I = TypeIndices.find(SP);
if (I != TypeIndices.end())
return I->second;
ProcedureRecord Procedure(TypeIndex::Void(), CallingConvention::NearC,
FunctionOptions::None, 0, ArgListIndex);
VoidFnTyIdx = TypeTable.writeProcedure(Procedure);
return VoidFnTyIdx;
}
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();

View File

@ -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);

View File

@ -37,7 +37,7 @@
; X86-NEXT: .long [[END_OF_F]]-_f
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 4098
; X86-NEXT: .secrel32 _f
; X86-NEXT: .secidx _f
; X86-NEXT: .byte 0
@ -130,7 +130,7 @@
; X64-NEXT: .long [[END_OF_F]]-f
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 4098
; X64-NEXT: .secrel32 f
; X64-NEXT: .secidx f
; X64-NEXT: .byte 0

View File

@ -138,6 +138,12 @@
; OBJ: FunctionType: void () (0x1001)
; OBJ: Name: foo
; OBJ: }
; OBJ: FuncId (0x1004) {
; OBJ: TypeLeafKind: LF_FUNC_ID (0x1601)
; OBJ: ParentScope: 0x0
; OBJ: FunctionType: void () (0x1001)
; OBJ: Name: baz
; OBJ: }
; OBJ-NOT: TypeLeafKind: LF_FUNC_ID
; OBJ: ]
@ -164,7 +170,7 @@
; OBJ: CodeSize: 0x3D
; OBJ: DbgStart: 0x0
; OBJ: DbgEnd: 0x0
; OBJ: FunctionType: 0x0
; OBJ: FunctionType: baz (0x1004)
; OBJ: CodeOffset: ?baz@@YAXXZ+0x0
; OBJ: Segment: 0x0
; OBJ: Flags [ (0x0)

View File

@ -46,7 +46,7 @@
; X86-NEXT: .long [[END_OF_F]]-_f
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 4098
; X86-NEXT: .secrel32 _f
; X86-NEXT: .secidx _f
; X86-NEXT: .byte 0
@ -154,7 +154,7 @@
; X64-NEXT: .long [[END_OF_F]]-f
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 4098
; X64-NEXT: .secrel32 f
; X64-NEXT: .secidx f
; X64-NEXT: .byte 0

View File

@ -67,7 +67,7 @@
; X86-NEXT: .long [[END_OF_X]]-_x
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 4098
; X86-NEXT: .secrel32 _x
; X86-NEXT: .secidx _x
; X86-NEXT: .byte 0
@ -92,7 +92,7 @@
; X86-NEXT: .long [[END_OF_Y]]-_y
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 4099
; X86-NEXT: .secrel32 _y
; X86-NEXT: .secidx _y
; X86-NEXT: .byte 0
@ -117,7 +117,7 @@
; X86-NEXT: .long [[END_OF_F]]-_f
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 4100
; X86-NEXT: .secrel32 _f
; X86-NEXT: .secidx _f
; X86-NEXT: .byte 0
@ -331,7 +331,7 @@
; X64-NEXT: .long [[END_OF_X]]-x
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 4098
; X64-NEXT: .secrel32 x
; X64-NEXT: .secidx x
; X64-NEXT: .byte 0
@ -356,7 +356,7 @@
; X64-NEXT: .long [[END_OF_Y]]-y
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 4099
; X64-NEXT: .secrel32 y
; X64-NEXT: .secidx y
; X64-NEXT: .byte 0
@ -381,7 +381,7 @@
; X64-NEXT: .long [[END_OF_F]]-f
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 4100
; X64-NEXT: .secrel32 f
; X64-NEXT: .secidx f
; X64-NEXT: .byte 0

View File

@ -36,7 +36,7 @@
; X86-NEXT: .long [[END_OF_F]]-_f
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 0
; X86-NEXT: .long 4098
; X86-NEXT: .secrel32 _f
; X86-NEXT: .secidx _f
; X86-NEXT: .byte 0
@ -126,7 +126,7 @@
; X64-NEXT: .long [[END_OF_F]]-f
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 0
; X64-NEXT: .long 4098
; X64-NEXT: .secrel32 f
; X64-NEXT: .secidx f
; X64-NEXT: .byte 0

View File

@ -32,16 +32,40 @@
; $ clang t.cpp -S -emit-llvm -g -gcodeview -o t.ll
; CHECK: CodeViewTypes [
; CHECK: Modifier (0x1000) {
; CHECK: ArgList (0x1000) {
; CHECK: TypeLeafKind: LF_ARGLIST (0x1201)
; CHECK: NumArgs: 3
; CHECK: Arguments [
; CHECK: ArgType: float (0x40)
; CHECK: ArgType: double (0x41)
; CHECK: ArgType: __int64 (0x13)
; CHECK: ]
; CHECK: }
; CHECK: Procedure (0x1001) {
; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008)
; CHECK: ReturnType: void (0x3)
; CHECK: CallingConvention: NearC (0x0)
; CHECK: FunctionOptions [ (0x0)
; CHECK: ]
; CHECK: NumParameters: 3
; CHECK: ArgListType: (float, double, __int64) (0x1000)
; CHECK: }
; CHECK: FuncId (0x1002) {
; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601)
; CHECK: ParentScope: 0x0
; CHECK: FunctionType: void (float, double, __int64) (0x1001)
; CHECK: Name: f
; CHECK: }
; CHECK: Modifier (0x1003) {
; CHECK: TypeLeafKind: LF_MODIFIER (0x1001)
; CHECK: ModifiedType: int (0x74)
; CHECK: Modifiers [ (0x1)
; CHECK: Const (0x1)
; CHECK: ]
; CHECK: }
; CHECK: Pointer (0x1001) {
; CHECK: Pointer (0x1004) {
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
; CHECK: PointeeType: const int (0x1000)
; CHECK: PointeeType: const int (0x1003)
; CHECK: PointerAttributes: 0x1000C
; CHECK: PtrType: Near64 (0xC)
; CHECK: PtrMode: Pointer (0x0)
@ -50,7 +74,7 @@
; CHECK: IsVolatile: 0
; CHECK: IsUnaligned: 0
; CHECK: }
; CHECK: Pointer (0x1002) {
; CHECK: Pointer (0x1005) {
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
; CHECK: PointeeType: int (0x74)
; CHECK: PointerAttributes: 0x804C
@ -63,9 +87,25 @@
; CHECK: ClassType: 0x0
; CHECK: Representation: Unknown (0x0)
; CHECK: }
; CHECK: Pointer (0x1003) {
; CHECK: ArgList (0x1006) {
; CHECK: TypeLeafKind: LF_ARGLIST (0x1201)
; CHECK: NumArgs: 1
; CHECK: Arguments [
; CHECK: ArgType: <unknown simple type> (0x600)
; CHECK: ]
; CHECK: }
; CHECK: Procedure (0x1007) {
; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008)
; CHECK: ReturnType: void (0x3)
; CHECK: CallingConvention: NearC (0x0)
; CHECK: FunctionOptions [ (0x0)
; CHECK: ]
; CHECK: NumParameters: 1
; CHECK: ArgListType: (<unknown simple type>) (0x1006)
; CHECK: }
; CHECK: Pointer (0x1008) {
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
; CHECK: PointeeType: 0x0
; CHECK: PointeeType: void (<unknown simple type>) (0x1007)
; CHECK: PointerAttributes: 0x1006C
; CHECK: PtrType: Near64 (0xC)
; CHECK: PtrMode: PointerToMemberFunction (0x3)
@ -83,7 +123,7 @@
; CHECK: ProcStart {
; CHECK: DbgStart: 0x0
; CHECK: DbgEnd: 0x0
; CHECK: FunctionType: 0x0
; CHECK: FunctionType: f (0x1002)
; CHECK: CodeOffset: ?f@@YAXMN_J@Z+0x0
; CHECK: Segment: 0x0
; CHECK: Flags [ (0x0)
@ -121,7 +161,7 @@
; CHECK: VarName: v2
; CHECK: }
; CHECK: Local {
; CHECK: Type: const int* (0x1001)
; CHECK: Type: const int* (0x1004)
; CHECK: VarName: v21
; CHECK: }
; CHECK: Local {
@ -129,11 +169,11 @@
; CHECK: VarName: v3
; CHECK: }
; CHECK: Local {
; CHECK: Type: int <no type>::* (0x1002)
; CHECK: Type: int <no type>::* (0x1005)
; CHECK: VarName: v4
; CHECK: }
; CHECK: Local {
; CHECK: Type: <no type> <no type>::* (0x1003)
; CHECK: Type: void (<unknown simple type>) <no type>::* (0x1008)
; CHECK: VarName: v5
; CHECK: }
; CHECK: Local {