Revert "[lldb][test] Remove compiler version check and use regex" (#124101)
[llvm-project.git] / llvm / tools / llvm-c-test / debuginfo.c
blobbaf4ddfcc9a37bf5742cde5182f7749d68a2c596
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 \*===----------------------------------------------------------------------===*/
14 #include "llvm-c/DebugInfo.h"
15 #include "llvm-c-test.h"
16 #include "llvm-c/Core.h"
17 #include "llvm-c/Types.h"
19 #include <assert.h>
20 #include <stdio.h>
21 #include <string.h>
23 static LLVMMetadataRef
24 declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {
25 LLVMMetadataRef Decl = LLVMDIBuilderCreateStructType(DIB, File, "TestClass", 9, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
26 LLVMMetadataRef SuperDecl = LLVMDIBuilderCreateStructType(DIB, File, "TestSuperClass", 14, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
27 LLVMDIBuilderCreateInheritance(DIB, Decl, SuperDecl, 0, 0, 0);
28 LLVMMetadataRef TestProperty =
29 LLVMDIBuilderCreateObjCProperty(DIB, "test", 4, File, 42, "getTest", 7, "setTest", 7, 0x20 /*copy*/ | 0x40 /*nonatomic*/, SuperDecl);
30 LLVMDIBuilderCreateObjCIVar(DIB, "_test", 5, File, 42, 64, 0, 64, LLVMDIFlagPublic, SuperDecl, TestProperty);
31 return Decl;
34 int llvm_test_dibuilder(void) {
35 const char *Filename = "debuginfo.c";
36 LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
38 LLVMSetIsNewDbgInfoFormat(M, true);
39 assert(LLVMIsNewDbgInfoFormat(M));
41 LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
43 LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,
44 strlen(Filename), ".", 1);
46 LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(
47 DIB, LLVMDWARFSourceLanguageC, File, "llvm-c-test", 11, 0, NULL, 0, 0,
48 NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
50 LLVMMetadataRef Module =
51 LLVMDIBuilderCreateModule(DIB, CompileUnit,
52 "llvm-c-test", 11,
53 "", 0,
54 "/test/include/llvm-c-test.h", 27,
55 "", 0);
57 LLVMMetadataRef OtherModule =
58 LLVMDIBuilderCreateModule(DIB, CompileUnit,
59 "llvm-c-test-import", 18,
60 "", 0,
61 "/test/include/llvm-c-test-import.h", 34,
62 "", 0);
63 LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule(
64 DIB, Module, OtherModule, File, 42, NULL, 0);
65 LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule, File,
66 42, NULL, 0);
68 LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
69 LLVMMetadataRef GlobalClassValueExpr =
70 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
71 LLVMDIBuilderCreateGlobalVariableExpression(
72 DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,
73 GlobalClassValueExpr, NULL, 0);
75 LLVMMetadataRef Int64Ty =
76 LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
77 LLVMMetadataRef Int64TypeDef =
78 LLVMDIBuilderCreateTypedef(DIB, Int64Ty, "int64_t", 7, File, 42, File, 0);
80 LLVMMetadataRef GlobalVarValueExpr =
81 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
82 LLVMDIBuilderCreateGlobalVariableExpression(
83 DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,
84 GlobalVarValueExpr, NULL, 0);
86 LLVMMetadataRef NameSpace =
87 LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
89 LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
90 LLVMMetadataRef StructDbgTy =
91 LLVMDIBuilderCreateStructType(DIB, NameSpace, "MyStruct",
92 8, File, 0, 192, 0, 0, NULL, StructDbgElts, 3,
93 LLVMDWARFSourceLanguageC, NULL, "MyStruct", 8);
95 LLVMMetadataRef StructDbgPtrTy =
96 LLVMDIBuilderCreatePointerType(DIB, StructDbgTy, 192, 0, 0, "", 0);
98 LLVMAddNamedMetadataOperand(M, "FooType",
99 LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));
102 LLVMTypeRef FooParamTys[] = {
103 LLVMInt64Type(),
104 LLVMInt64Type(),
105 LLVMVectorType(LLVMInt64Type(), 10),
107 LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 3, 0);
108 LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy);
109 LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry");
111 LLVMMetadataRef Subscripts[] = {
112 LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),
114 LLVMMetadataRef VectorTy =
115 LLVMDIBuilderCreateVectorType(DIB, 64 * 10, 0,
116 Int64Ty, Subscripts, 1);
119 LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy};
120 LLVMMetadataRef FunctionTy =
121 LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, 3, 0);
123 LLVMMetadataRef ReplaceableFunctionMetadata =
124 LLVMDIBuilderCreateReplaceableCompositeType(DIB, 0x15, "foo", 3,
125 File, File, 42,
126 0, 0, 0,
127 LLVMDIFlagFwdDecl,
128 "", 0);
130 LLVMMetadataRef FooParamLocation =
131 LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0,
132 ReplaceableFunctionMetadata, NULL);
133 LLVMMetadataRef FunctionMetadata =
134 LLVMDIBuilderCreateFunction(DIB, File, "foo", 3, "foo", 3,
135 File, 42, FunctionTy, true, true,
136 42, 0, false);
137 LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);
139 LLVMMetadataRef FooParamExpression =
140 LLVMDIBuilderCreateExpression(DIB, NULL, 0);
141 LLVMMetadataRef FooParamVar1 =
142 LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,
143 42, Int64Ty, true, 0);
145 LLVMDIBuilderInsertDeclareRecordAtEnd(
146 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,
147 FooParamExpression, FooParamLocation, FooEntryBlock);
149 LLVMMetadataRef FooParamVar2 =
150 LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,
151 42, Int64Ty, true, 0);
153 LLVMDIBuilderInsertDeclareRecordAtEnd(
154 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,
155 FooParamExpression, FooParamLocation, FooEntryBlock);
157 LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable(
158 DIB, FunctionMetadata, "c", 1, 3, File, 42, VectorTy, true, 0);
160 LLVMDIBuilderInsertDeclareRecordAtEnd(
161 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,
162 FooParamExpression, FooParamLocation, FooEntryBlock);
164 LLVMSetSubprogram(FooFunction, FunctionMetadata);
166 LLVMMetadataRef FooLabel1 = LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
167 "label1", 6, File, 42, false);
168 LLVMDIBuilderInsertLabelAtEnd(DIB, FooLabel1, FooParamLocation,
169 FooEntryBlock);
171 LLVMMetadataRef FooLexicalBlock =
172 LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);
174 LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(FooFunction, "vars");
175 LLVMMetadataRef FooVarsLocation =
176 LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 43, 0,
177 FunctionMetadata, NULL);
178 LLVMMetadataRef FooVar1 =
179 LLVMDIBuilderCreateAutoVariable(DIB, FooLexicalBlock, "d", 1, File,
180 43, Int64Ty, true, 0, 0);
181 LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);
182 LLVMMetadataRef FooVarValueExpr1 =
183 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
185 LLVMDIBuilderInsertDbgValueRecordAtEnd(
186 DIB, FooVal1, FooVar1, FooVarValueExpr1, FooVarsLocation, FooVarBlock);
188 LLVMMetadataRef FooVar2 = LLVMDIBuilderCreateAutoVariable(
189 DIB, FooLexicalBlock, "e", 1, File, 44, Int64Ty, true, 0, 0);
190 LLVMValueRef FooVal2 = LLVMConstInt(LLVMInt64Type(), 1, false);
191 LLVMMetadataRef FooVarValueExpr2 =
192 LLVMDIBuilderCreateConstantValueExpression(DIB, 1);
194 LLVMDIBuilderInsertDbgValueRecordAtEnd(
195 DIB, FooVal2, FooVar2, FooVarValueExpr2, FooVarsLocation, FooVarBlock);
197 LLVMMetadataRef MacroFile =
198 LLVMDIBuilderCreateTempMacroFile(DIB, NULL, 0, File);
199 LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
200 "SIMPLE_DEFINE", 13, NULL, 0);
201 LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
202 "VALUE_DEFINE", 12, "1", 1);
204 LLVMMetadataRef EnumeratorTestA =
205 LLVMDIBuilderCreateEnumerator(DIB, "Test_A", strlen("Test_A"), 0, true);
206 LLVMMetadataRef EnumeratorTestB =
207 LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_B"), 1, true);
208 LLVMMetadataRef EnumeratorTestC =
209 LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_C"), 2, true);
210 LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB,
211 EnumeratorTestC};
212 LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType(
213 DIB, NameSpace, "EnumTest", strlen("EnumTest"), File, 0, 64, 0,
214 EnumeratorsTest, 3, Int64Ty);
215 LLVMAddNamedMetadataOperand(
216 M, "EnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), EnumTest));
218 // Using the new debug format, debug records get attached to instructions.
219 // Insert a `br` and `ret` now to absorb the debug records which are
220 // currently "trailing", meaning that they're associated with a block
221 // but no particular instruction, which is only valid as a transient state.
222 LLVMContextRef Ctx = LLVMGetModuleContext(M);
223 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
224 LLVMPositionBuilderAtEnd(Builder, FooEntryBlock);
225 // Build `br label %vars` in entry.
226 LLVMBuildBr(Builder, FooVarBlock);
228 // Build another br for the sake of testing labels.
229 LLVMMetadataRef FooLabel2 = LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
230 "label2", 6, File, 42, false);
231 LLVMDIBuilderInsertLabelBefore(DIB, FooLabel2, FooParamLocation,
232 LLVMBuildBr(Builder, FooVarBlock));
233 // label3 will be emitted, but label4 won't be emitted
234 // because label3 is AlwaysPreserve and label4 is not.
235 LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
236 "label3", 6, File, 42, true);
237 LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,
238 "label4", 6, File, 42, false);
239 LLVMDIBuilderFinalize(DIB);
241 // Build `ret i64 0` in vars.
242 LLVMPositionBuilderAtEnd(Builder, FooVarBlock);
243 LLVMTypeRef I64 = LLVMInt64TypeInContext(Ctx);
244 LLVMValueRef Zero = LLVMConstInt(I64, 0, false);
245 LLVMValueRef Ret = LLVMBuildRet(Builder, Zero);
247 // Insert a `phi` before the `ret`. In the new debug info mode we need to
248 // be careful to insert before debug records too, else the debug records
249 // will come before the `phi` (and be absorbed onto it) which is an invalid
250 // state.
251 LLVMValueRef InsertPos = LLVMGetFirstInstruction(FooVarBlock);
252 LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, InsertPos);
253 LLVMValueRef Phi1 = LLVMBuildPhi(Builder, I64, "p1");
254 LLVMAddIncoming(Phi1, &Zero, &FooEntryBlock, 1);
256 // Do the same again using the other position-setting function.
257 LLVMPositionBuilderBeforeDbgRecords(Builder, FooVarBlock, InsertPos);
258 LLVMValueRef Phi2 = LLVMBuildPhi(Builder, I64, "p2");
259 LLVMAddIncoming(Phi2, &Zero, &FooEntryBlock, 1);
261 // Insert a non-phi before the `ret` but not before the debug records to
262 // test that works as expected.
263 LLVMPositionBuilder(Builder, FooVarBlock, Ret);
264 LLVMValueRef Add = LLVMBuildAdd(Builder, Phi1, Phi2, "a");
266 // Iterate over debug records in the add instruction. There should be two.
267 LLVMDbgRecordRef AddDbgRecordFirst = LLVMGetFirstDbgRecord(Add);
268 assert(AddDbgRecordFirst != NULL);
269 LLVMDbgRecordRef AddDbgRecordSecond = LLVMGetNextDbgRecord(AddDbgRecordFirst);
270 assert(AddDbgRecordSecond != NULL);
271 LLVMDbgRecordRef AddDbgRecordLast = LLVMGetLastDbgRecord(Add);
272 assert(AddDbgRecordLast != NULL);
273 (void)AddDbgRecordLast;
274 assert(AddDbgRecordSecond == AddDbgRecordLast);
275 LLVMDbgRecordRef AddDbgRecordOverTheRange =
276 LLVMGetNextDbgRecord(AddDbgRecordSecond);
277 assert(AddDbgRecordOverTheRange == NULL);
278 (void)AddDbgRecordOverTheRange;
279 LLVMDbgRecordRef AddDbgRecordFirstPrev =
280 LLVMGetPreviousDbgRecord(AddDbgRecordSecond);
281 assert(AddDbgRecordFirstPrev != NULL);
282 assert(AddDbgRecordFirst == AddDbgRecordFirstPrev);
283 LLVMDbgRecordRef AddDbgRecordUnderTheRange =
284 LLVMGetPreviousDbgRecord(AddDbgRecordFirstPrev);
285 assert(AddDbgRecordUnderTheRange == NULL);
286 (void)AddDbgRecordUnderTheRange;
288 char *MStr = LLVMPrintModuleToString(M);
289 puts(MStr);
290 LLVMDisposeMessage(MStr);
292 LLVMDisposeBuilder(Builder);
293 LLVMDisposeDIBuilder(DIB);
294 LLVMDisposeModule(M);
296 return 0;
299 int llvm_get_di_tag(void) {
300 LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
301 LLVMContextRef Context = LLVMGetModuleContext(M);
303 const char String[] = "foo";
304 LLVMMetadataRef StringMD =
305 LLVMMDStringInContext2(Context, String, strlen(String));
306 LLVMMetadataRef NodeMD = LLVMMDNodeInContext2(Context, &StringMD, 1);
307 assert(LLVMGetDINodeTag(NodeMD) == 0);
308 (void)NodeMD;
310 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
311 const char Filename[] = "metadata.c";
312 const char Directory[] = ".";
313 LLVMMetadataRef File = LLVMDIBuilderCreateFile(
314 Builder, Filename, strlen(Filename), Directory, strlen(Directory));
315 const char Name[] = "TestClass";
316 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(
317 Builder, File, Name, strlen(Name), File, 42, 64, 0,
318 LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
319 assert(LLVMGetDINodeTag(Struct) == 0x13);
320 (void)Struct;
322 LLVMDisposeDIBuilder(Builder);
323 LLVMDisposeModule(M);
325 return 0;
328 int llvm_di_type_get_name(void) {
329 LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
331 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
332 const char Filename[] = "metadata.c";
333 const char Directory[] = ".";
334 LLVMMetadataRef File = LLVMDIBuilderCreateFile(
335 Builder, Filename, strlen(Filename), Directory, strlen(Directory));
336 const char Name[] = "TestClass";
337 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(
338 Builder, File, Name, strlen(Name), File, 42, 64, 0,
339 LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
341 size_t Len;
342 const char *TypeName = LLVMDITypeGetName(Struct, &Len);
343 assert(Len == strlen(Name));
344 assert(strncmp(TypeName, Name, Len) == 0);
345 (void)TypeName;
347 LLVMDisposeDIBuilder(Builder);
348 LLVMDisposeModule(M);
350 return 0;