[LoongArch] Eliminate the redundant sign extension of division (#107971)
[llvm-project.git] / llvm / tools / llvm-c-test / debuginfo.c
blob49c90f5b87b83a64f166a441244a6d0d5b8b6152
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-test.h"
15 #include "llvm-c/DebugInfo.h"
17 #include <assert.h>
18 #include <stdio.h>
19 #include <string.h>
21 static LLVMMetadataRef
22 declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {
23 LLVMMetadataRef Decl = LLVMDIBuilderCreateStructType(DIB, File, "TestClass", 9, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
24 LLVMMetadataRef SuperDecl = LLVMDIBuilderCreateStructType(DIB, File, "TestSuperClass", 14, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
25 LLVMDIBuilderCreateInheritance(DIB, Decl, SuperDecl, 0, 0, 0);
26 LLVMMetadataRef TestProperty =
27 LLVMDIBuilderCreateObjCProperty(DIB, "test", 4, File, 42, "getTest", 7, "setTest", 7, 0x20 /*copy*/ | 0x40 /*nonatomic*/, SuperDecl);
28 LLVMDIBuilderCreateObjCIVar(DIB, "_test", 5, File, 42, 64, 0, 64, LLVMDIFlagPublic, SuperDecl, TestProperty);
29 return Decl;
32 int llvm_test_dibuilder(void) {
33 const char *Filename = "debuginfo.c";
34 LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
36 LLVMSetIsNewDbgInfoFormat(M, true);
37 assert(LLVMIsNewDbgInfoFormat(M));
39 LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
41 LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,
42 strlen(Filename), ".", 1);
44 LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(
45 DIB, LLVMDWARFSourceLanguageC, File, "llvm-c-test", 11, 0, NULL, 0, 0,
46 NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
48 LLVMMetadataRef Module =
49 LLVMDIBuilderCreateModule(DIB, CompileUnit,
50 "llvm-c-test", 11,
51 "", 0,
52 "/test/include/llvm-c-test.h", 27,
53 "", 0);
55 LLVMMetadataRef OtherModule =
56 LLVMDIBuilderCreateModule(DIB, CompileUnit,
57 "llvm-c-test-import", 18,
58 "", 0,
59 "/test/include/llvm-c-test-import.h", 34,
60 "", 0);
61 LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule(
62 DIB, Module, OtherModule, File, 42, NULL, 0);
63 LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule, File,
64 42, NULL, 0);
66 LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
67 LLVMMetadataRef GlobalClassValueExpr =
68 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
69 LLVMDIBuilderCreateGlobalVariableExpression(
70 DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,
71 GlobalClassValueExpr, NULL, 0);
73 LLVMMetadataRef Int64Ty =
74 LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
75 LLVMMetadataRef Int64TypeDef =
76 LLVMDIBuilderCreateTypedef(DIB, Int64Ty, "int64_t", 7, File, 42, File, 0);
78 LLVMMetadataRef GlobalVarValueExpr =
79 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
80 LLVMDIBuilderCreateGlobalVariableExpression(
81 DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,
82 GlobalVarValueExpr, NULL, 0);
84 LLVMMetadataRef NameSpace =
85 LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
87 LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
88 LLVMMetadataRef StructDbgTy =
89 LLVMDIBuilderCreateStructType(DIB, NameSpace, "MyStruct",
90 8, File, 0, 192, 0, 0, NULL, StructDbgElts, 3,
91 LLVMDWARFSourceLanguageC, NULL, "MyStruct", 8);
93 LLVMMetadataRef StructDbgPtrTy =
94 LLVMDIBuilderCreatePointerType(DIB, StructDbgTy, 192, 0, 0, "", 0);
96 LLVMAddNamedMetadataOperand(M, "FooType",
97 LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));
100 LLVMTypeRef FooParamTys[] = {
101 LLVMInt64Type(),
102 LLVMInt64Type(),
103 LLVMVectorType(LLVMInt64Type(), 10),
105 LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 3, 0);
106 LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy);
107 LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry");
109 LLVMMetadataRef Subscripts[] = {
110 LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),
112 LLVMMetadataRef VectorTy =
113 LLVMDIBuilderCreateVectorType(DIB, 64 * 10, 0,
114 Int64Ty, Subscripts, 1);
117 LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy};
118 LLVMMetadataRef FunctionTy =
119 LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, 3, 0);
121 LLVMMetadataRef ReplaceableFunctionMetadata =
122 LLVMDIBuilderCreateReplaceableCompositeType(DIB, 0x15, "foo", 3,
123 File, File, 42,
124 0, 0, 0,
125 LLVMDIFlagFwdDecl,
126 "", 0);
128 LLVMMetadataRef FooParamLocation =
129 LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0,
130 ReplaceableFunctionMetadata, NULL);
131 LLVMMetadataRef FunctionMetadata =
132 LLVMDIBuilderCreateFunction(DIB, File, "foo", 3, "foo", 3,
133 File, 42, FunctionTy, true, true,
134 42, 0, false);
135 LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);
137 LLVMMetadataRef FooParamExpression =
138 LLVMDIBuilderCreateExpression(DIB, NULL, 0);
139 LLVMMetadataRef FooParamVar1 =
140 LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,
141 42, Int64Ty, true, 0);
143 LLVMDIBuilderInsertDeclareRecordAtEnd(
144 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,
145 FooParamExpression, FooParamLocation, FooEntryBlock);
147 LLVMMetadataRef FooParamVar2 =
148 LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,
149 42, Int64Ty, true, 0);
151 LLVMDIBuilderInsertDeclareRecordAtEnd(
152 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,
153 FooParamExpression, FooParamLocation, FooEntryBlock);
155 LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable(
156 DIB, FunctionMetadata, "c", 1, 3, File, 42, VectorTy, true, 0);
158 LLVMDIBuilderInsertDeclareRecordAtEnd(
159 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,
160 FooParamExpression, FooParamLocation, FooEntryBlock);
162 LLVMSetSubprogram(FooFunction, FunctionMetadata);
164 LLVMMetadataRef FooLexicalBlock =
165 LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);
167 LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(FooFunction, "vars");
168 LLVMMetadataRef FooVarsLocation =
169 LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 43, 0,
170 FunctionMetadata, NULL);
171 LLVMMetadataRef FooVar1 =
172 LLVMDIBuilderCreateAutoVariable(DIB, FooLexicalBlock, "d", 1, File,
173 43, Int64Ty, true, 0, 0);
174 LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);
175 LLVMMetadataRef FooVarValueExpr =
176 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
178 LLVMDIBuilderInsertDbgValueRecordAtEnd(DIB, FooVal1, FooVar1, FooVarValueExpr,
179 FooVarsLocation, FooVarBlock);
181 LLVMMetadataRef MacroFile =
182 LLVMDIBuilderCreateTempMacroFile(DIB, NULL, 0, File);
183 LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
184 "SIMPLE_DEFINE", 13, NULL, 0);
185 LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
186 "VALUE_DEFINE", 12, "1", 1);
188 LLVMMetadataRef EnumeratorTestA =
189 LLVMDIBuilderCreateEnumerator(DIB, "Test_A", strlen("Test_A"), 0, true);
190 LLVMMetadataRef EnumeratorTestB =
191 LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_B"), 1, true);
192 LLVMMetadataRef EnumeratorTestC =
193 LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_C"), 2, true);
194 LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB,
195 EnumeratorTestC};
196 LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType(
197 DIB, NameSpace, "EnumTest", strlen("EnumTest"), File, 0, 64, 0,
198 EnumeratorsTest, 3, Int64Ty);
199 LLVMAddNamedMetadataOperand(
200 M, "EnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), EnumTest));
202 LLVMDIBuilderFinalize(DIB);
204 // Using the new debug format, debug records get attached to instructions.
205 // Insert a `br` and `ret` now to absorb the debug records which are
206 // currently "trailing", meaning that they're associated with a block
207 // but no particular instruction, which is only valid as a transient state.
208 LLVMContextRef Ctx = LLVMGetModuleContext(M);
209 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);
210 LLVMPositionBuilderAtEnd(Builder, FooEntryBlock);
211 // Build `br label %vars` in entry.
212 LLVMBuildBr(Builder, FooVarBlock);
213 // Build `ret i64 0` in vars.
214 LLVMPositionBuilderAtEnd(Builder, FooVarBlock);
215 LLVMTypeRef I64 = LLVMInt64TypeInContext(Ctx);
216 LLVMValueRef Zero = LLVMConstInt(I64, 0, false);
217 LLVMValueRef Ret = LLVMBuildRet(Builder, Zero);
219 // Insert a `phi` before the `ret`. In the new debug info mode we need to
220 // be careful to insert before debug records too, else the debug records
221 // will come before the `phi` (and be absorbed onto it) which is an invalid
222 // state.
223 LLVMValueRef InsertPos = LLVMGetFirstInstruction(FooVarBlock);
224 LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, InsertPos);
225 LLVMValueRef Phi1 = LLVMBuildPhi(Builder, I64, "p1");
226 LLVMAddIncoming(Phi1, &Zero, &FooEntryBlock, 1);
227 // Do the same again using the other position-setting function.
228 LLVMPositionBuilderBeforeDbgRecords(Builder, FooVarBlock, InsertPos);
229 LLVMValueRef Phi2 = LLVMBuildPhi(Builder, I64, "p2");
230 LLVMAddIncoming(Phi2, &Zero, &FooEntryBlock, 1);
231 // Insert a non-phi before the `ret` but not before the debug records to
232 // test that works as expected.
233 LLVMPositionBuilder(Builder, FooVarBlock, Ret);
234 LLVMBuildAdd(Builder, Phi1, Phi2, "a");
236 char *MStr = LLVMPrintModuleToString(M);
237 puts(MStr);
238 LLVMDisposeMessage(MStr);
240 LLVMDisposeBuilder(Builder);
241 LLVMDisposeDIBuilder(DIB);
242 LLVMDisposeModule(M);
244 return 0;
247 int llvm_get_di_tag(void) {
248 LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
249 LLVMContextRef Context = LLVMGetModuleContext(M);
251 const char String[] = "foo";
252 LLVMMetadataRef StringMD =
253 LLVMMDStringInContext2(Context, String, strlen(String));
254 LLVMMetadataRef NodeMD = LLVMMDNodeInContext2(Context, &StringMD, 1);
255 assert(LLVMGetDINodeTag(NodeMD) == 0);
256 (void)NodeMD;
258 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
259 const char Filename[] = "metadata.c";
260 const char Directory[] = ".";
261 LLVMMetadataRef File = LLVMDIBuilderCreateFile(
262 Builder, Filename, strlen(Filename), Directory, strlen(Directory));
263 const char Name[] = "TestClass";
264 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(
265 Builder, File, Name, strlen(Name), File, 42, 64, 0,
266 LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
267 assert(LLVMGetDINodeTag(Struct) == 0x13);
268 (void)Struct;
270 LLVMDisposeDIBuilder(Builder);
271 LLVMDisposeModule(M);
273 return 0;
276 int llvm_di_type_get_name(void) {
277 LLVMModuleRef M = LLVMModuleCreateWithName("Mod");
279 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
280 const char Filename[] = "metadata.c";
281 const char Directory[] = ".";
282 LLVMMetadataRef File = LLVMDIBuilderCreateFile(
283 Builder, Filename, strlen(Filename), Directory, strlen(Directory));
284 const char Name[] = "TestClass";
285 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(
286 Builder, File, Name, strlen(Name), File, 42, 64, 0,
287 LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
289 size_t Len;
290 const char *TypeName = LLVMDITypeGetName(Struct, &Len);
291 assert(Len == strlen(Name));
292 assert(strncmp(TypeName, Name, Len) == 0);
293 (void)TypeName;
295 LLVMDisposeDIBuilder(Builder);
296 LLVMDisposeModule(M);
298 return 0;