1/*===-- debuginfo.c - tool for testing libLLVM and llvm-c API -------------===*\
2|* *|
3|* Part of the LLVM Project, under the Apache License v2.0 with LLVM *|
4|* Exceptions. *|
5|* See https://llvm.org/LICENSE.txt for license information. *|
6|* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception *|
7|* *|
8|*===----------------------------------------------------------------------===*|
9|* *|
10|* Tests for the LLVM C DebugInfo API *|
11|* *|
12\*===----------------------------------------------------------------------===*/
13
14#include "llvm-c/DebugInfo.h"
15#include "llvm-c-test.h"
16#include "llvm-c/Core.h"
17#include "llvm-c/Types.h"
18
19#include <assert.h>
20#include <stdio.h>
21#include <string.h>
22
23static LLVMMetadataRef
24declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {
25 LLVMMetadataRef Decl = LLVMDIBuilderCreateStructType(Builder: DIB, Scope: File, Name: "TestClass", NameLen: 9, File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0);
26 LLVMMetadataRef SuperDecl = LLVMDIBuilderCreateStructType(Builder: DIB, Scope: File, Name: "TestSuperClass", NameLen: 14, File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0);
27 LLVMDIBuilderCreateInheritance(Builder: DIB, Ty: Decl, BaseTy: SuperDecl, BaseOffset: 0, VBPtrOffset: 0, Flags: 0);
28 LLVMMetadataRef TestProperty =
29 LLVMDIBuilderCreateObjCProperty(Builder: DIB, Name: "test", NameLen: 4, File, LineNo: 42, GetterName: "getTest", GetterNameLen: 7, SetterName: "setTest", SetterNameLen: 7, PropertyAttributes: 0x20 /*copy*/ | 0x40 /*nonatomic*/, Ty: SuperDecl);
30 LLVMDIBuilderCreateObjCIVar(Builder: DIB, Name: "_test", NameLen: 5, File, LineNo: 42, SizeInBits: 64, AlignInBits: 0, OffsetInBits: 64, Flags: LLVMDIFlagPublic, Ty: SuperDecl, PropertyNode: TestProperty);
31 return Decl;
32}
33
34int llvm_test_dibuilder(void) {
35 const char *Filename = "debuginfo.c";
36 LLVMContextRef C = LLVMContextCreate();
37 LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleID: Filename, C);
38
39 LLVMSetIsNewDbgInfoFormat(M, true);
40 assert(LLVMIsNewDbgInfoFormat(M));
41
42 LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
43
44 LLVMMetadataRef File = LLVMDIBuilderCreateFile(Builder: DIB, Filename,
45 FilenameLen: strlen(s: Filename), Directory: ".", DirectoryLen: 1);
46
47 LLVMMetadataRef FileCS = LLVMDIBuilderCreateFileWithChecksum(
48 Builder: DIB, Filename, FilenameLen: strlen(s: Filename), Directory: ".", DirectoryLen: 1, ChecksumKind: CSK_MD5, Checksum: "1234", ChecksumLen: 4, Source: "source", SourceLen: 6);
49
50 LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(
51 Builder: DIB, Lang: LLVMDWARFSourceLanguageC, FileRef: File, Producer: "llvm-c-test", ProducerLen: 11, isOptimized: 0, NULL, FlagsLen: 0, RuntimeVer: 0,
52 NULL, SplitNameLen: 0, Kind: LLVMDWARFEmissionFull, DWOId: 0, SplitDebugInlining: 0, DebugInfoForProfiling: 0, SysRoot: "/", SysRootLen: 1, SDK: "", SDKLen: 0);
53
54 LLVMMetadataRef Module =
55 LLVMDIBuilderCreateModule(Builder: DIB, ParentScope: CompileUnit,
56 Name: "llvm-c-test", NameLen: 11,
57 ConfigMacros: "", ConfigMacrosLen: 0,
58 IncludePath: "/test/include/llvm-c-test.h", IncludePathLen: 27,
59 APINotesFile: "", APINotesFileLen: 0);
60
61 LLVMMetadataRef OtherModule =
62 LLVMDIBuilderCreateModule(Builder: DIB, ParentScope: CompileUnit,
63 Name: "llvm-c-test-import", NameLen: 18,
64 ConfigMacros: "", ConfigMacrosLen: 0,
65 IncludePath: "/test/include/llvm-c-test-import.h", IncludePathLen: 34,
66 APINotesFile: "", APINotesFileLen: 0);
67 LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule(
68 Builder: DIB, Scope: Module, M: OtherModule, File: FileCS, Line: 42, NULL, NumElements: 0);
69 LLVMDIBuilderCreateImportedModuleFromAlias(Builder: DIB, Scope: Module, ImportedEntity: ImportedModule, File,
70 Line: 42, NULL, NumElements: 0);
71
72 LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
73 LLVMMetadataRef GlobalClassValueExpr =
74 LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0);
75 LLVMDIBuilderCreateGlobalVariableExpression(
76 Builder: DIB, Scope: Module, Name: "globalClass", NameLen: 11, Linkage: "", LinkLen: 0, File, LineNo: 1, Ty: ClassTy, true,
77 Expr: GlobalClassValueExpr, NULL, AlignInBits: 0);
78
79 LLVMMetadataRef Int64Ty =
80 LLVMDIBuilderCreateBasicType(Builder: DIB, Name: "Int64", NameLen: 5, SizeInBits: 64, Encoding: 0, Flags: LLVMDIFlagZero);
81 LLVMMetadataRef Int64TypeDef =
82 LLVMDIBuilderCreateTypedef(Builder: DIB, Type: Int64Ty, Name: "int64_t", NameLen: 7, File, LineNo: 42, Scope: File, AlignInBits: 0);
83
84 LLVMMetadataRef GlobalVarValueExpr =
85 LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0);
86 LLVMDIBuilderCreateGlobalVariableExpression(
87 Builder: DIB, Scope: Module, Name: "global", NameLen: 6, Linkage: "", LinkLen: 0, File, LineNo: 1, Ty: Int64TypeDef, true,
88 Expr: GlobalVarValueExpr, NULL, AlignInBits: 0);
89
90 LLVMMetadataRef NameSpace =
91 LLVMDIBuilderCreateNameSpace(Builder: DIB, ParentScope: Module, Name: "NameSpace", NameLen: 9, false);
92
93 LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
94 LLVMMetadataRef StructDbgTy =
95 LLVMDIBuilderCreateStructType(Builder: DIB, Scope: NameSpace, Name: "MyStruct",
96 NameLen: 8, File, LineNumber: 0, SizeInBits: 192, AlignInBits: 0, Flags: 0, NULL, Elements: StructDbgElts, NumElements: 3,
97 RunTimeLang: LLVMDWARFSourceLanguageC, NULL, UniqueId: "MyStruct", UniqueIdLen: 8);
98
99 LLVMMetadataRef StructDbgPtrTy =
100 LLVMDIBuilderCreatePointerType(Builder: DIB, PointeeTy: StructDbgTy, SizeInBits: 192, AlignInBits: 0, AddressSpace: 0, Name: "", NameLen: 0);
101
102 LLVMAddNamedMetadataOperand(M, Name: "FooType",
103 Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: StructDbgPtrTy));
104
105 LLVMTypeRef I64Ty = LLVMInt64TypeInContext(C);
106 LLVMTypeRef FooParamTys[] = {
107 I64Ty,
108 I64Ty,
109 LLVMVectorType(ElementType: I64Ty, ElementCount: 10),
110 };
111 LLVMTypeRef FooFuncTy = LLVMFunctionType(ReturnType: I64Ty, ParamTypes: FooParamTys, ParamCount: 3, IsVarArg: 0);
112 LLVMValueRef FooFunction = LLVMAddFunction(M, Name: "foo", FunctionTy: FooFuncTy);
113 LLVMBasicBlockRef FooEntryBlock =
114 LLVMAppendBasicBlockInContext(C, Fn: FooFunction, Name: "entry");
115
116 LLVMMetadataRef Subscripts[] = {
117 LLVMDIBuilderGetOrCreateSubrange(Builder: DIB, LowerBound: 0, Count: 10),
118 };
119 LLVMMetadataRef VectorTy =
120 LLVMDIBuilderCreateVectorType(Builder: DIB, Size: 64 * 10, AlignInBits: 0,
121 Ty: Int64Ty, Subscripts, NumSubscripts: 1);
122
123
124 LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy};
125 LLVMMetadataRef FunctionTy =
126 LLVMDIBuilderCreateSubroutineType(Builder: DIB, File, ParameterTypes: ParamTypes, NumParameterTypes: 3, Flags: 0);
127
128 LLVMMetadataRef ReplaceableFunctionMetadata =
129 LLVMDIBuilderCreateReplaceableCompositeType(Builder: DIB, Tag: 0x15, Name: "foo", NameLen: 3,
130 Scope: File, File, Line: 42,
131 RuntimeLang: 0, SizeInBits: 0, AlignInBits: 0,
132 Flags: LLVMDIFlagFwdDecl,
133 UniqueIdentifier: "", UniqueIdentifierLen: 0);
134
135 LLVMMetadataRef FooParamLocation = LLVMDIBuilderCreateDebugLocation(
136 Ctx: C, Line: 42, Column: 0, Scope: ReplaceableFunctionMetadata, NULL);
137 LLVMMetadataRef FunctionMetadata = LLVMDIBuilderCreateFunction(
138 Builder: DIB, Scope: File, Name: "foo", NameLen: 3, LinkageName: "foo", LinkageNameLen: 3, File, LineNo: 42, NULL, true, true, ScopeLine: 42, Flags: 0, false);
139 LLVMMetadataReplaceAllUsesWith(TempTargetMetadata: ReplaceableFunctionMetadata, Replacement: FunctionMetadata);
140
141 LLVMDISubprogramReplaceType(Subprogram: FunctionMetadata, SubroutineType: FunctionTy);
142
143 LLVMMetadataRef FooParamExpression =
144 LLVMDIBuilderCreateExpression(Builder: DIB, NULL, Length: 0);
145 LLVMMetadataRef FooParamVar1 =
146 LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "a", NameLen: 1, ArgNo: 1, File,
147 LineNo: 42, Ty: Int64Ty, true, Flags: 0);
148
149 LLVMDIBuilderInsertDeclareRecordAtEnd(Builder: DIB, Storage: LLVMConstInt(IntTy: I64Ty, N: 0, false),
150 VarInfo: FooParamVar1, Expr: FooParamExpression,
151 DebugLoc: FooParamLocation, Block: FooEntryBlock);
152
153 LLVMMetadataRef FooParamVar2 =
154 LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "b", NameLen: 1, ArgNo: 2, File,
155 LineNo: 42, Ty: Int64Ty, true, Flags: 0);
156
157 LLVMDIBuilderInsertDeclareRecordAtEnd(Builder: DIB, Storage: LLVMConstInt(IntTy: I64Ty, N: 0, false),
158 VarInfo: FooParamVar2, Expr: FooParamExpression,
159 DebugLoc: FooParamLocation, Block: FooEntryBlock);
160
161 LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable(
162 Builder: DIB, Scope: FunctionMetadata, Name: "c", NameLen: 1, ArgNo: 3, File, LineNo: 42, Ty: VectorTy, true, Flags: 0);
163
164 LLVMDIBuilderInsertDeclareRecordAtEnd(Builder: DIB, Storage: LLVMConstInt(IntTy: I64Ty, N: 0, false),
165 VarInfo: FooParamVar3, Expr: FooParamExpression,
166 DebugLoc: FooParamLocation, Block: FooEntryBlock);
167
168 LLVMSetSubprogram(Func: FooFunction, SP: FunctionMetadata);
169
170 LLVMMetadataRef FooLabel1 = LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata,
171 Name: "label1", NameLen: 6, File, LineNo: 42, false);
172 LLVMDIBuilderInsertLabelAtEnd(Builder: DIB, LabelInfo: FooLabel1, Location: FooParamLocation,
173 InsertAtEnd: FooEntryBlock);
174
175 LLVMMetadataRef FooLexicalBlock =
176 LLVMDIBuilderCreateLexicalBlock(Builder: DIB, Scope: FunctionMetadata, File, Line: 42, Column: 0);
177
178 LLVMBasicBlockRef FooVarBlock =
179 LLVMAppendBasicBlockInContext(C, Fn: FooFunction, Name: "vars");
180 LLVMMetadataRef FooVarsLocation =
181 LLVMDIBuilderCreateDebugLocation(Ctx: C, Line: 43, Column: 0, Scope: FunctionMetadata, NULL);
182 LLVMMetadataRef FooVar1 =
183 LLVMDIBuilderCreateAutoVariable(Builder: DIB, Scope: FooLexicalBlock, Name: "d", NameLen: 1, File,
184 LineNo: 43, Ty: Int64Ty, true, Flags: 0, AlignInBits: 0);
185 LLVMValueRef FooVal1 = LLVMConstInt(IntTy: I64Ty, N: 0, false);
186 LLVMMetadataRef FooVarValueExpr1 =
187 LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0);
188
189 LLVMDIBuilderInsertDbgValueRecordAtEnd(
190 Builder: DIB, Val: FooVal1, VarInfo: FooVar1, Expr: FooVarValueExpr1, DebugLoc: FooVarsLocation, Block: FooVarBlock);
191
192 LLVMMetadataRef FooVar2 = LLVMDIBuilderCreateAutoVariable(
193 Builder: DIB, Scope: FooLexicalBlock, Name: "e", NameLen: 1, File, LineNo: 44, Ty: Int64Ty, true, Flags: 0, AlignInBits: 0);
194 LLVMValueRef FooVal2 = LLVMConstInt(IntTy: I64Ty, N: 1, false);
195 LLVMMetadataRef FooVarValueExpr2 =
196 LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 1);
197
198 LLVMDIBuilderInsertDbgValueRecordAtEnd(
199 Builder: DIB, Val: FooVal2, VarInfo: FooVar2, Expr: FooVarValueExpr2, DebugLoc: FooVarsLocation, Block: FooVarBlock);
200
201 LLVMMetadataRef MacroFile =
202 LLVMDIBuilderCreateTempMacroFile(Builder: DIB, NULL, Line: 0, File);
203 LLVMDIBuilderCreateMacro(Builder: DIB, ParentMacroFile: MacroFile, Line: 0, RecordType: LLVMDWARFMacinfoRecordTypeDefine,
204 Name: "SIMPLE_DEFINE", NameLen: 13, NULL, ValueLen: 0);
205 LLVMDIBuilderCreateMacro(Builder: DIB, ParentMacroFile: MacroFile, Line: 0, RecordType: LLVMDWARFMacinfoRecordTypeDefine,
206 Name: "VALUE_DEFINE", NameLen: 12, Value: "1", ValueLen: 1);
207
208 LLVMMetadataRef EnumeratorTestA =
209 LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_A", NameLen: strlen(s: "Test_A"), Value: 0, true);
210 LLVMMetadataRef EnumeratorTestB =
211 LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_B", NameLen: strlen(s: "Test_B"), Value: 1, true);
212 LLVMMetadataRef EnumeratorTestC =
213 LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_B", NameLen: strlen(s: "Test_C"), Value: 2, true);
214 LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB,
215 EnumeratorTestC};
216 LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType(
217 Builder: DIB, Scope: NameSpace, Name: "EnumTest", NameLen: strlen(s: "EnumTest"), File, LineNumber: 0, SizeInBits: 64, AlignInBits: 0,
218 Elements: EnumeratorsTest, NumElements: 3, ClassTy: Int64Ty);
219 LLVMAddNamedMetadataOperand(
220 M, Name: "EnumTest", Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: EnumTest));
221
222 LLVMMetadataRef UInt128Ty = LLVMDIBuilderCreateBasicType(
223 Builder: DIB, Name: "UInt128", NameLen: strlen(s: "UInt128"), SizeInBits: 128, Encoding: 0, Flags: LLVMDIFlagZero);
224 const uint64_t WordsTestD[] = {0x098a224000000000ull, 0x4b3b4ca85a86c47aull};
225 const uint64_t WordsTestE[] = {0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull};
226
227 LLVMMetadataRef LargeEnumeratorTestD =
228 LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision(
229 Builder: DIB, Name: "Test_D", NameLen: strlen(s: "Test_D"), SizeInBits: 128, Words: WordsTestD, false);
230 LLVMMetadataRef LargeEnumeratorTestE =
231 LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision(
232 Builder: DIB, Name: "Test_E", NameLen: strlen(s: "Test_E"), SizeInBits: 128, Words: WordsTestE, false);
233 LLVMMetadataRef LargeEnumeratorsTest[] = {LargeEnumeratorTestD,
234 LargeEnumeratorTestE};
235 LLVMMetadataRef LargeEnumTest = LLVMDIBuilderCreateEnumerationType(
236 Builder: DIB, Scope: NameSpace, Name: "LargeEnumTest", NameLen: strlen(s: "LargeEnumTest"), File, LineNumber: 0, SizeInBits: 128, AlignInBits: 0,
237 Elements: LargeEnumeratorsTest, NumElements: 2, ClassTy: UInt128Ty);
238 LLVMAddNamedMetadataOperand(
239 M, Name: "LargeEnumTest",
240 Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: LargeEnumTest));
241
242 LLVMValueRef FooVal3 = LLVMConstInt(IntTy: I64Ty, N: 8, false);
243 LLVMValueRef FooVal4 = LLVMConstInt(IntTy: I64Ty, N: 4, false);
244 LLVMMetadataRef lo = LLVMValueAsMetadata(Val: FooVal1);
245 LLVMMetadataRef hi = LLVMValueAsMetadata(Val: FooVal2);
246 LLVMMetadataRef strd = LLVMValueAsMetadata(Val: FooVal3);
247 LLVMMetadataRef bias = LLVMValueAsMetadata(Val: FooVal4);
248 LLVMMetadataRef SubrangeMetadataTy = LLVMDIBuilderCreateSubrangeType(
249 Builder: DIB, Scope: File, Name: "foo", NameLen: 3, LineNo: 42, File, SizeInBits: 64, AlignInBits: 0, Flags: 0, BaseTy: Int64Ty, LowerBound: lo, UpperBound: hi, Stride: strd, Bias: bias);
250 LLVMAddNamedMetadataOperand(
251 M, Name: "SubrangeType",
252 Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: SubrangeMetadataTy));
253
254 LLVMMetadataRef SetMetadataTy1 = LLVMDIBuilderCreateSetType(
255 Builder: DIB, Scope: File, Name: "enumset", NameLen: 7, File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, BaseTy: EnumTest);
256 LLVMMetadataRef SetMetadataTy2 = LLVMDIBuilderCreateSetType(
257 Builder: DIB, Scope: File, Name: "subrangeset", NameLen: 11, File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, BaseTy: SubrangeMetadataTy);
258 LLVMAddNamedMetadataOperand(
259 M, Name: "SetType1",
260 Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: SetMetadataTy1));
261 LLVMAddNamedMetadataOperand(
262 M, Name: "SetType2",
263 Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: SetMetadataTy2));
264
265 LLVMMetadataRef DynSubscripts[] = {
266 LLVMDIBuilderGetOrCreateSubrange(Builder: DIB, LowerBound: 0, Count: 10),
267 };
268 LLVMMetadataRef Loc = LLVMDIBuilderCreateExpression(Builder: DIB, NULL, Length: 0);
269 LLVMMetadataRef Rank = LLVMDIBuilderCreateExpression(Builder: DIB, NULL, Length: 0);
270 LLVMMetadataRef DynamicArrayMetadataTy = LLVMDIBuilderCreateDynamicArrayType(
271 Builder: DIB, Scope: File, Name: "foo", NameLen: 3, LineNo: 42, File, Size: 64 * 10, AlignInBits: 0, Ty: Int64Ty, Subscripts: DynSubscripts, NumSubscripts: 1, DataLocation: Loc,
272 Associated: FooVar1, NULL, Rank, NULL);
273 LLVMAddNamedMetadataOperand(
274 M, Name: "DynType",
275 Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: DynamicArrayMetadataTy));
276
277 LLVMMetadataRef StructPTy = LLVMDIBuilderCreateForwardDecl(
278 Builder: DIB, Tag: 2 /*DW_TAG_class_type*/, Name: "Class1", NameLen: 5, Scope: NameSpace, File, Line: 0, RuntimeLang: 0, SizeInBits: 192, AlignInBits: 0,
279 UniqueIdentifier: "FooClass", UniqueIdentifierLen: 8);
280
281 LLVMMetadataRef Int32Ty =
282 LLVMDIBuilderCreateBasicType(Builder: DIB, Name: "Int32", NameLen: 5, SizeInBits: 32, Encoding: 0, Flags: LLVMDIFlagZero);
283 LLVMMetadataRef StructElts[] = {Int64Ty, Int64Ty, Int32Ty};
284 LLVMMetadataRef ClassArr = LLVMDIBuilderGetOrCreateArray(Builder: DIB, Data: StructElts, NumElements: 3);
285 LLVMReplaceArrays(Builder: DIB, T: &StructPTy, Elements: &ClassArr, NumElements: 1);
286 LLVMAddNamedMetadataOperand(
287 M, Name: "ClassType", Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: StructPTy));
288
289 // Using the new debug format, debug records get attached to instructions.
290 // Insert a `br` and `ret` now to absorb the debug records which are
291 // currently "trailing", meaning that they're associated with a block
292 // but no particular instruction, which is only valid as a transient state.
293 LLVMContextRef Ctx = LLVMGetModuleContext(M);
294 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(C: Ctx);
295 LLVMPositionBuilderAtEnd(Builder, Block: FooEntryBlock);
296 // Build `br label %vars` in entry.
297 LLVMBuildBr(Builder, Dest: FooVarBlock);
298
299 // Build another br for the sake of testing labels.
300 LLVMMetadataRef FooLabel2 = LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata,
301 Name: "label2", NameLen: 6, File, LineNo: 42, false);
302 LLVMDIBuilderInsertLabelBefore(Builder: DIB, LabelInfo: FooLabel2, Location: FooParamLocation,
303 InsertBefore: LLVMBuildBr(Builder, Dest: FooVarBlock));
304 // label3 will be emitted, but label4 won't be emitted
305 // because label3 is AlwaysPreserve and label4 is not.
306 LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata,
307 Name: "label3", NameLen: 6, File, LineNo: 42, true);
308 LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata,
309 Name: "label4", NameLen: 6, File, LineNo: 42, false);
310 LLVMDIBuilderFinalize(Builder: DIB);
311
312 // Build `ret i64 0` in vars.
313 LLVMPositionBuilderAtEnd(Builder, Block: FooVarBlock);
314 LLVMTypeRef I64 = LLVMInt64TypeInContext(C: Ctx);
315 LLVMValueRef Zero = LLVMConstInt(IntTy: I64, N: 0, false);
316 LLVMValueRef Ret = LLVMBuildRet(Builder, V: Zero);
317
318 // Insert a `phi` before the `ret`. In the new debug info mode we need to
319 // be careful to insert before debug records too, else the debug records
320 // will come before the `phi` (and be absorbed onto it) which is an invalid
321 // state.
322 LLVMValueRef InsertPos = LLVMGetFirstInstruction(BB: FooVarBlock);
323 LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, Instr: InsertPos);
324 LLVMValueRef Phi1 = LLVMBuildPhi(Builder, Ty: I64, Name: "p1");
325 LLVMAddIncoming(PhiNode: Phi1, IncomingValues: &Zero, IncomingBlocks: &FooEntryBlock, Count: 1);
326
327 // Do the same again using the other position-setting function.
328 LLVMPositionBuilderBeforeDbgRecords(Builder, Block: FooVarBlock, Inst: InsertPos);
329 LLVMValueRef Phi2 = LLVMBuildPhi(Builder, Ty: I64, Name: "p2");
330 LLVMAddIncoming(PhiNode: Phi2, IncomingValues: &Zero, IncomingBlocks: &FooEntryBlock, Count: 1);
331
332 // Test that LLVMGetFirstDbgRecord and LLVMGetLastDbgRecord return NULL for
333 // instructions without debug info.
334 LLVMDbgRecordRef Phi1FirstDbgRecord = LLVMGetFirstDbgRecord(Inst: Phi1);
335 (void)Phi1FirstDbgRecord;
336 assert(Phi1FirstDbgRecord == NULL);
337 LLVMDbgRecordRef Phi1LastDbgRecord = LLVMGetLastDbgRecord(Inst: Phi1);
338 (void)Phi1LastDbgRecord;
339 assert(Phi1LastDbgRecord == NULL);
340
341 // Insert a non-phi before the `ret` but not before the debug records to
342 // test that works as expected.
343 LLVMPositionBuilder(Builder, Block: FooVarBlock, Instr: Ret);
344 LLVMValueRef Add = LLVMBuildAdd(Builder, LHS: Phi1, RHS: Phi2, Name: "a");
345
346 // Iterate over debug records in the add instruction. There should be two.
347 LLVMDbgRecordRef AddDbgRecordFirst = LLVMGetFirstDbgRecord(Inst: Add);
348 assert(AddDbgRecordFirst != NULL);
349 LLVMDbgRecordRef AddDbgRecordSecond = LLVMGetNextDbgRecord(DbgRecord: AddDbgRecordFirst);
350 assert(AddDbgRecordSecond != NULL);
351 LLVMDbgRecordRef AddDbgRecordLast = LLVMGetLastDbgRecord(Inst: Add);
352 assert(AddDbgRecordLast != NULL);
353 (void)AddDbgRecordLast;
354 assert(AddDbgRecordSecond == AddDbgRecordLast);
355 LLVMDbgRecordRef AddDbgRecordOverTheRange =
356 LLVMGetNextDbgRecord(DbgRecord: AddDbgRecordSecond);
357 assert(AddDbgRecordOverTheRange == NULL);
358 (void)AddDbgRecordOverTheRange;
359 LLVMDbgRecordRef AddDbgRecordFirstPrev =
360 LLVMGetPreviousDbgRecord(DbgRecord: AddDbgRecordSecond);
361 assert(AddDbgRecordFirstPrev != NULL);
362 assert(AddDbgRecordFirst == AddDbgRecordFirstPrev);
363 LLVMDbgRecordRef AddDbgRecordUnderTheRange =
364 LLVMGetPreviousDbgRecord(DbgRecord: AddDbgRecordFirstPrev);
365 assert(AddDbgRecordUnderTheRange == NULL);
366 (void)AddDbgRecordUnderTheRange;
367
368 // Test that we can read the first debug record.
369 LLVMMetadataRef AddDbgRecordFirstDebugLoc =
370 LLVMDbgRecordGetDebugLoc(Rec: AddDbgRecordFirst);
371 (void)AddDbgRecordFirstDebugLoc;
372 assert(LLVMDILocationGetLine(AddDbgRecordFirstDebugLoc) == 43);
373 assert(LLVMDbgRecordGetKind(AddDbgRecordFirst) == LLVMDbgRecordValue);
374 LLVMValueRef AddDbgRecordFirstValue =
375 LLVMDbgVariableRecordGetValue(Rec: AddDbgRecordFirst, OpIdx: 0);
376 (void)AddDbgRecordFirstValue;
377 assert(LLVMGetValueKind(AddDbgRecordFirstValue) == LLVMConstantIntValueKind);
378 assert(LLVMConstIntGetZExtValue(AddDbgRecordFirstValue) == 0);
379 LLVMMetadataRef AddDbgRecordFirstVariable =
380 LLVMDbgVariableRecordGetVariable(Rec: AddDbgRecordFirst);
381 (void)AddDbgRecordFirstVariable;
382 assert(LLVMGetMetadataKind(AddDbgRecordFirstVariable) ==
383 LLVMDILocalVariableMetadataKind);
384 // TODO: For now, there is no way to get the name.
385 LLVMMetadataRef AddDbgRecordFirstVariableScope =
386 LLVMDIVariableGetScope(Var: AddDbgRecordFirstVariable);
387 (void)AddDbgRecordFirstVariableScope;
388 assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableScope) ==
389 LLVMDILexicalBlockMetadataKind);
390 LLVMMetadataRef AddDbgRecordFirstVariableFile =
391 LLVMDIScopeGetFile(Scope: AddDbgRecordFirstVariableScope);
392 (void)AddDbgRecordFirstVariableFile;
393 assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableFile) ==
394 LLVMDIFileMetadataKind);
395 unsigned FileLen = 0;
396 assert(strcmp(LLVMDIFileGetFilename(AddDbgRecordFirstVariableFile, &FileLen),
397 "debuginfo.c") == 0);
398 (void)FileLen;
399 LLVMMetadataRef AddDbgRecordFirstExpr =
400 LLVMDbgVariableRecordGetExpression(Rec: AddDbgRecordFirst);
401 assert(LLVMGetMetadataKind(AddDbgRecordFirstExpr) ==
402 LLVMDIExpressionMetadataKind);
403 (void)AddDbgRecordFirstExpr;
404
405 char *MStr = LLVMPrintModuleToString(M);
406 puts(s: MStr);
407 LLVMDisposeMessage(Message: MStr);
408
409 LLVMDisposeBuilder(Builder);
410 LLVMDisposeDIBuilder(Builder: DIB);
411 LLVMDisposeModule(M);
412 LLVMContextDispose(C);
413
414 return 0;
415}
416
417int llvm_get_di_tag(void) {
418 LLVMContextRef Context = LLVMContextCreate();
419 LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleID: "Mod", C: Context);
420
421 const char String[] = "foo";
422 LLVMMetadataRef StringMD =
423 LLVMMDStringInContext2(C: Context, Str: String, SLen: strlen(s: String));
424 LLVMMetadataRef NodeMD = LLVMMDNodeInContext2(C: Context, MDs: &StringMD, Count: 1);
425 assert(LLVMGetDINodeTag(NodeMD) == 0);
426 (void)NodeMD;
427
428 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
429 const char Filename[] = "metadata.c";
430 const char Directory[] = ".";
431 LLVMMetadataRef File = LLVMDIBuilderCreateFile(
432 Builder, Filename, FilenameLen: strlen(s: Filename), Directory, DirectoryLen: strlen(s: Directory));
433 const char Name[] = "TestClass";
434 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(
435 Builder, Scope: File, Name, NameLen: strlen(s: Name), File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0,
436 Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0);
437 assert(LLVMGetDINodeTag(Struct) == 0x13);
438 (void)Struct;
439
440 LLVMDisposeDIBuilder(Builder);
441 LLVMDisposeModule(M);
442 LLVMContextDispose(C: Context);
443
444 return 0;
445}
446
447int llvm_di_type_get_name(void) {
448 LLVMContextRef C = LLVMContextCreate();
449 LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleID: "Mod", C);
450
451 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
452 const char Filename[] = "metadata.c";
453 const char Directory[] = ".";
454 LLVMMetadataRef File = LLVMDIBuilderCreateFile(
455 Builder, Filename, FilenameLen: strlen(s: Filename), Directory, DirectoryLen: strlen(s: Directory));
456 const char Name[] = "TestClass";
457 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(
458 Builder, Scope: File, Name, NameLen: strlen(s: Name), File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0,
459 Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0);
460
461 size_t Len;
462 const char *TypeName = LLVMDITypeGetName(DType: Struct, Length: &Len);
463 assert(Len == strlen(Name));
464 assert(strncmp(TypeName, Name, Len) == 0);
465 (void)TypeName;
466
467 LLVMDisposeDIBuilder(Builder);
468 LLVMDisposeModule(M);
469 LLVMContextDispose(C);
470
471 return 0;
472}
473
474int llvm_add_globaldebuginfo(void) {
475 const char *Filename = "debuginfo.c";
476 LLVMContextRef C = LLVMContextCreate();
477 LLVMModuleRef M = LLVMModuleCreateWithNameInContext(ModuleID: Filename, C);
478 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
479 LLVMMetadataRef File =
480 LLVMDIBuilderCreateFile(Builder, Filename, FilenameLen: strlen(s: Filename), Directory: ".", DirectoryLen: 1);
481
482 LLVMMetadataRef GlobalVarValueExpr =
483 LLVMDIBuilderCreateConstantValueExpression(Builder, Value: 0);
484 LLVMMetadataRef Int64Ty =
485 LLVMDIBuilderCreateBasicType(Builder, Name: "Int64", NameLen: 5, SizeInBits: 64, Encoding: 0, Flags: LLVMDIFlagZero);
486 LLVMMetadataRef Int64TypeDef = LLVMDIBuilderCreateTypedef(
487 Builder, Type: Int64Ty, Name: "int64_t", NameLen: 7, File, LineNo: 42, Scope: File, AlignInBits: 0);
488
489 LLVMMetadataRef GVE = LLVMDIBuilderCreateGlobalVariableExpression(
490 Builder, Scope: File, Name: "global", NameLen: 6, Linkage: "", LinkLen: 0, File, LineNo: 1, Ty: Int64TypeDef, true,
491 Expr: GlobalVarValueExpr, NULL, AlignInBits: 0);
492
493 LLVMTypeRef RecType = LLVMStructCreateNamed(C, Name: "struct");
494 LLVMValueRef Global = LLVMAddGlobal(M, Ty: RecType, Name: "global");
495
496 LLVMGlobalAddDebugInfo(Global, GVE);
497 // use AddMetadata to add twice
498 int kindId = LLVMGetMDKindIDInContext(C, Name: "dbg", SLen: 3);
499 LLVMGlobalAddMetadata(Global, Kind: kindId, MD: GVE);
500 size_t numEntries;
501 LLVMValueMetadataEntry *ME = LLVMGlobalCopyAllMetadata(Value: Global, NumEntries: &numEntries);
502 assert(ME != NULL);
503 assert(numEntries == 2);
504
505 LLVMDisposeValueMetadataEntries(Entries: ME);
506 LLVMDisposeDIBuilder(Builder);
507 LLVMDisposeModule(M);
508 LLVMContextDispose(C);
509
510 return 0;
511}
512