forked from OSchip/llvm-project
[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:
parent
49471dfb31
commit
75c3ebfa02
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue