Skip to content

Commit 75c3ebf

Browse files
committedJun 2, 2016
[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
1 parent 49471df commit 75c3ebf

File tree

8 files changed

+116
-46
lines changed

8 files changed

+116
-46
lines changed
 

‎llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

+45-17
Original file line numberDiff line numberDiff line change
@@ -117,31 +117,31 @@ CodeViewDebug::getInlineSite(const DILocation *InlinedAt,
117117
Site->SiteFuncId = NextFuncId++;
118118
Site->Inlinee = Inlinee;
119119
InlinedSubprograms.insert(Inlinee);
120-
recordFuncIdForSubprogram(Inlinee);
120+
getFuncIdForSubprogram(Inlinee);
121121
}
122122
return *Site;
123123
}
124124

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();
132130

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;
138135

139-
void CodeViewDebug::recordFuncIdForSubprogram(const DISubprogram *SP) {
140136
TypeIndex ParentScope = TypeIndex(0);
141137
StringRef DisplayName = SP->getDisplayName();
142-
FuncIdRecord FuncId(ParentScope, getGenericFunctionTypeIndex(), DisplayName);
138+
FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);
143139
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;
145145
}
146146

147147
void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
@@ -495,7 +495,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
495495
OS.AddComment("Offset before epilogue");
496496
OS.EmitIntValue(0, 4);
497497
OS.AddComment("Function type index");
498-
OS.EmitIntValue(0, 4);
498+
OS.EmitIntValue(getFuncIdForSubprogram(GV->getSubprogram()).getIndex(), 4);
499499
OS.AddComment("Function section relative address");
500500
OS.EmitCOFFSecRel32(Fn);
501501
OS.AddComment("Function section index");
@@ -744,6 +744,8 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty) {
744744
case dwarf::DW_TAG_const_type:
745745
case dwarf::DW_TAG_volatile_type:
746746
return lowerTypeModifier(cast<DIDerivedType>(Ty));
747+
case dwarf::DW_TAG_subroutine_type:
748+
return lowerTypeFunction(cast<DISubroutineType>(Ty));
747749
default:
748750
// Use the null type index.
749751
return TypeIndex();
@@ -934,6 +936,32 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
934936
return TypeTable.writeModifier(MR);
935937
}
936938

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+
937965
TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef) {
938966
const DIType *Ty = TypeRef.resolve();
939967

‎llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,10 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
117117
/// to be confused with type indices for LF_FUNC_ID records.
118118
unsigned NextFuncId = 0;
119119

120-
codeview::TypeIndex VoidFnTyIdx;
121-
122-
/// Get a type index for a generic void function type.
123-
codeview::TypeIndex getGenericFunctionTypeIndex();
124-
125120
InlineSite &getInlineSite(const DILocation *InlinedAt,
126121
const DISubprogram *Inlinee);
127122

128-
void recordFuncIdForSubprogram(const DISubprogram *SP);
123+
codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP);
129124

130125
static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,
131126
const FunctionInfo &FI,
@@ -195,6 +190,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
195190
codeview::TypeIndex lowerTypePointer(const DIDerivedType *Ty);
196191
codeview::TypeIndex lowerTypeMemberPointer(const DIDerivedType *Ty);
197192
codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty);
193+
codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty);
198194

199195
public:
200196
CodeViewDebug(AsmPrinter *Asm);

‎llvm/test/DebugInfo/COFF/asm.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
; X86-NEXT: .long [[END_OF_F]]-_f
3838
; X86-NEXT: .long 0
3939
; X86-NEXT: .long 0
40-
; X86-NEXT: .long 0
40+
; X86-NEXT: .long 4098
4141
; X86-NEXT: .secrel32 _f
4242
; X86-NEXT: .secidx _f
4343
; X86-NEXT: .byte 0
@@ -130,7 +130,7 @@
130130
; X64-NEXT: .long [[END_OF_F]]-f
131131
; X64-NEXT: .long 0
132132
; X64-NEXT: .long 0
133-
; X64-NEXT: .long 0
133+
; X64-NEXT: .long 4098
134134
; X64-NEXT: .secrel32 f
135135
; X64-NEXT: .secidx f
136136
; X64-NEXT: .byte 0

‎llvm/test/DebugInfo/COFF/inlining.ll

+7-1
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@
138138
; OBJ: FunctionType: void () (0x1001)
139139
; OBJ: Name: foo
140140
; OBJ: }
141+
; OBJ: FuncId (0x1004) {
142+
; OBJ: TypeLeafKind: LF_FUNC_ID (0x1601)
143+
; OBJ: ParentScope: 0x0
144+
; OBJ: FunctionType: void () (0x1001)
145+
; OBJ: Name: baz
146+
; OBJ: }
141147
; OBJ-NOT: TypeLeafKind: LF_FUNC_ID
142148
; OBJ: ]
143149

@@ -164,7 +170,7 @@
164170
; OBJ: CodeSize: 0x3D
165171
; OBJ: DbgStart: 0x0
166172
; OBJ: DbgEnd: 0x0
167-
; OBJ: FunctionType: 0x0
173+
; OBJ: FunctionType: baz (0x1004)
168174
; OBJ: CodeOffset: ?baz@@YAXXZ+0x0
169175
; OBJ: Segment: 0x0
170176
; OBJ: Flags [ (0x0)

‎llvm/test/DebugInfo/COFF/multifile.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
; X86-NEXT: .long [[END_OF_F]]-_f
4747
; X86-NEXT: .long 0
4848
; X86-NEXT: .long 0
49-
; X86-NEXT: .long 0
49+
; X86-NEXT: .long 4098
5050
; X86-NEXT: .secrel32 _f
5151
; X86-NEXT: .secidx _f
5252
; X86-NEXT: .byte 0
@@ -154,7 +154,7 @@
154154
; X64-NEXT: .long [[END_OF_F]]-f
155155
; X64-NEXT: .long 0
156156
; X64-NEXT: .long 0
157-
; X64-NEXT: .long 0
157+
; X64-NEXT: .long 4098
158158
; X64-NEXT: .secrel32 f
159159
; X64-NEXT: .secidx f
160160
; X64-NEXT: .byte 0

‎llvm/test/DebugInfo/COFF/multifunction.ll

+6-6
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@
6767
; X86-NEXT: .long [[END_OF_X]]-_x
6868
; X86-NEXT: .long 0
6969
; X86-NEXT: .long 0
70-
; X86-NEXT: .long 0
70+
; X86-NEXT: .long 4098
7171
; X86-NEXT: .secrel32 _x
7272
; X86-NEXT: .secidx _x
7373
; X86-NEXT: .byte 0
@@ -92,7 +92,7 @@
9292
; X86-NEXT: .long [[END_OF_Y]]-_y
9393
; X86-NEXT: .long 0
9494
; X86-NEXT: .long 0
95-
; X86-NEXT: .long 0
95+
; X86-NEXT: .long 4099
9696
; X86-NEXT: .secrel32 _y
9797
; X86-NEXT: .secidx _y
9898
; X86-NEXT: .byte 0
@@ -117,7 +117,7 @@
117117
; X86-NEXT: .long [[END_OF_F]]-_f
118118
; X86-NEXT: .long 0
119119
; X86-NEXT: .long 0
120-
; X86-NEXT: .long 0
120+
; X86-NEXT: .long 4100
121121
; X86-NEXT: .secrel32 _f
122122
; X86-NEXT: .secidx _f
123123
; X86-NEXT: .byte 0
@@ -331,7 +331,7 @@
331331
; X64-NEXT: .long [[END_OF_X]]-x
332332
; X64-NEXT: .long 0
333333
; X64-NEXT: .long 0
334-
; X64-NEXT: .long 0
334+
; X64-NEXT: .long 4098
335335
; X64-NEXT: .secrel32 x
336336
; X64-NEXT: .secidx x
337337
; X64-NEXT: .byte 0
@@ -356,7 +356,7 @@
356356
; X64-NEXT: .long [[END_OF_Y]]-y
357357
; X64-NEXT: .long 0
358358
; X64-NEXT: .long 0
359-
; X64-NEXT: .long 0
359+
; X64-NEXT: .long 4099
360360
; X64-NEXT: .secrel32 y
361361
; X64-NEXT: .secidx y
362362
; X64-NEXT: .byte 0
@@ -381,7 +381,7 @@
381381
; X64-NEXT: .long [[END_OF_F]]-f
382382
; X64-NEXT: .long 0
383383
; X64-NEXT: .long 0
384-
; X64-NEXT: .long 0
384+
; X64-NEXT: .long 4100
385385
; X64-NEXT: .secrel32 f
386386
; X64-NEXT: .secidx f
387387
; X64-NEXT: .byte 0

‎llvm/test/DebugInfo/COFF/simple.ll

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
; X86-NEXT: .long [[END_OF_F]]-_f
3737
; X86-NEXT: .long 0
3838
; X86-NEXT: .long 0
39-
; X86-NEXT: .long 0
39+
; X86-NEXT: .long 4098
4040
; X86-NEXT: .secrel32 _f
4141
; X86-NEXT: .secidx _f
4242
; X86-NEXT: .byte 0
@@ -126,7 +126,7 @@
126126
; X64-NEXT: .long [[END_OF_F]]-f
127127
; X64-NEXT: .long 0
128128
; X64-NEXT: .long 0
129-
; X64-NEXT: .long 0
129+
; X64-NEXT: .long 4098
130130
; X64-NEXT: .secrel32 f
131131
; X64-NEXT: .secidx f
132132
; X64-NEXT: .byte 0

‎llvm/test/DebugInfo/COFF/types-basic.ll

+50-10
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,40 @@
3232
; $ clang t.cpp -S -emit-llvm -g -gcodeview -o t.ll
3333

3434
; CHECK: CodeViewTypes [
35-
; CHECK: Modifier (0x1000) {
35+
; CHECK: ArgList (0x1000) {
36+
; CHECK: TypeLeafKind: LF_ARGLIST (0x1201)
37+
; CHECK: NumArgs: 3
38+
; CHECK: Arguments [
39+
; CHECK: ArgType: float (0x40)
40+
; CHECK: ArgType: double (0x41)
41+
; CHECK: ArgType: __int64 (0x13)
42+
; CHECK: ]
43+
; CHECK: }
44+
; CHECK: Procedure (0x1001) {
45+
; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008)
46+
; CHECK: ReturnType: void (0x3)
47+
; CHECK: CallingConvention: NearC (0x0)
48+
; CHECK: FunctionOptions [ (0x0)
49+
; CHECK: ]
50+
; CHECK: NumParameters: 3
51+
; CHECK: ArgListType: (float, double, __int64) (0x1000)
52+
; CHECK: }
53+
; CHECK: FuncId (0x1002) {
54+
; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601)
55+
; CHECK: ParentScope: 0x0
56+
; CHECK: FunctionType: void (float, double, __int64) (0x1001)
57+
; CHECK: Name: f
58+
; CHECK: }
59+
; CHECK: Modifier (0x1003) {
3660
; CHECK: TypeLeafKind: LF_MODIFIER (0x1001)
3761
; CHECK: ModifiedType: int (0x74)
3862
; CHECK: Modifiers [ (0x1)
3963
; CHECK: Const (0x1)
4064
; CHECK: ]
4165
; CHECK: }
42-
; CHECK: Pointer (0x1001) {
66+
; CHECK: Pointer (0x1004) {
4367
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
44-
; CHECK: PointeeType: const int (0x1000)
68+
; CHECK: PointeeType: const int (0x1003)
4569
; CHECK: PointerAttributes: 0x1000C
4670
; CHECK: PtrType: Near64 (0xC)
4771
; CHECK: PtrMode: Pointer (0x0)
@@ -50,7 +74,7 @@
5074
; CHECK: IsVolatile: 0
5175
; CHECK: IsUnaligned: 0
5276
; CHECK: }
53-
; CHECK: Pointer (0x1002) {
77+
; CHECK: Pointer (0x1005) {
5478
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
5579
; CHECK: PointeeType: int (0x74)
5680
; CHECK: PointerAttributes: 0x804C
@@ -63,9 +87,25 @@
6387
; CHECK: ClassType: 0x0
6488
; CHECK: Representation: Unknown (0x0)
6589
; CHECK: }
66-
; CHECK: Pointer (0x1003) {
90+
; CHECK: ArgList (0x1006) {
91+
; CHECK: TypeLeafKind: LF_ARGLIST (0x1201)
92+
; CHECK: NumArgs: 1
93+
; CHECK: Arguments [
94+
; CHECK: ArgType: <unknown simple type> (0x600)
95+
; CHECK: ]
96+
; CHECK: }
97+
; CHECK: Procedure (0x1007) {
98+
; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008)
99+
; CHECK: ReturnType: void (0x3)
100+
; CHECK: CallingConvention: NearC (0x0)
101+
; CHECK: FunctionOptions [ (0x0)
102+
; CHECK: ]
103+
; CHECK: NumParameters: 1
104+
; CHECK: ArgListType: (<unknown simple type>) (0x1006)
105+
; CHECK: }
106+
; CHECK: Pointer (0x1008) {
67107
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
68-
; CHECK: PointeeType: 0x0
108+
; CHECK: PointeeType: void (<unknown simple type>) (0x1007)
69109
; CHECK: PointerAttributes: 0x1006C
70110
; CHECK: PtrType: Near64 (0xC)
71111
; CHECK: PtrMode: PointerToMemberFunction (0x3)
@@ -83,7 +123,7 @@
83123
; CHECK: ProcStart {
84124
; CHECK: DbgStart: 0x0
85125
; CHECK: DbgEnd: 0x0
86-
; CHECK: FunctionType: 0x0
126+
; CHECK: FunctionType: f (0x1002)
87127
; CHECK: CodeOffset: ?f@@YAXMN_J@Z+0x0
88128
; CHECK: Segment: 0x0
89129
; CHECK: Flags [ (0x0)
@@ -121,19 +161,19 @@
121161
; CHECK: VarName: v2
122162
; CHECK: }
123163
; CHECK: Local {
124-
; CHECK: Type: const int* (0x1001)
164+
; CHECK: Type: const int* (0x1004)
125165
; CHECK: VarName: v21
126166
; CHECK: }
127167
; CHECK: Local {
128168
; CHECK: Type: void* (0x603)
129169
; CHECK: VarName: v3
130170
; CHECK: }
131171
; CHECK: Local {
132-
; CHECK: Type: int <no type>::* (0x1002)
172+
; CHECK: Type: int <no type>::* (0x1005)
133173
; CHECK: VarName: v4
134174
; CHECK: }
135175
; CHECK: Local {
136-
; CHECK: Type: <no type> <no type>::* (0x1003)
176+
; CHECK: Type: void (<unknown simple type>) <no type>::* (0x1008)
137177
; CHECK: VarName: v5
138178
; CHECK: }
139179
; CHECK: Local {

0 commit comments

Comments
 (0)
Please sign in to comment.