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-test.h"
15#include "llvm-c/Core.h"
16#include "llvm-c/DebugInfo.h"
17#include <stdio.h>
18#include <string.h>
19
20static LLVMMetadataRef
21declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {
22  LLVMMetadataRef Decl = LLVMDIBuilderCreateStructType(DIB, File, "TestClass", 9, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
23  LLVMMetadataRef SuperDecl = LLVMDIBuilderCreateStructType(DIB, File, "TestSuperClass", 14, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);
24  LLVMDIBuilderCreateInheritance(DIB, Decl, SuperDecl, 0, 0, 0);
25  LLVMMetadataRef TestProperty =
26      LLVMDIBuilderCreateObjCProperty(DIB, "test", 4, File, 42, "getTest", 7, "setTest", 7, 0x20 /*copy*/ | 0x40 /*nonatomic*/, SuperDecl);
27  LLVMDIBuilderCreateObjCIVar(DIB, "_test", 5, File, 42, 64, 0, 64, LLVMDIFlagPublic, SuperDecl, TestProperty);
28  return Decl;
29}
30
31int llvm_test_dibuilder(void) {
32  const char *Filename = "debuginfo.c";
33  LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
34  LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);
35
36  LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,
37    strlen(Filename), ".", 1);
38
39  LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(
40      DIB, LLVMDWARFSourceLanguageC, File, "llvm-c-test", 11, 0, NULL, 0, 0,
41      NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);
42
43  LLVMMetadataRef Module =
44    LLVMDIBuilderCreateModule(DIB, CompileUnit,
45                              "llvm-c-test", 11,
46                              "", 0,
47                              "/test/include/llvm-c-test.h", 27,
48                              "", 0);
49
50  LLVMMetadataRef OtherModule =
51    LLVMDIBuilderCreateModule(DIB, CompileUnit,
52                              "llvm-c-test-import", 18,
53                              "", 0,
54                              "/test/include/llvm-c-test-import.h", 34,
55                              "", 0);
56  LLVMMetadataRef ImportedModule =
57    LLVMDIBuilderCreateImportedModuleFromModule(DIB, Module, OtherModule,
58                                                File, 42);
59  LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule,
60                                             File, 42);
61
62  LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
63  LLVMMetadataRef GlobalClassValueExpr =
64      LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
65  LLVMDIBuilderCreateGlobalVariableExpression(
66      DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,
67      GlobalClassValueExpr, NULL, 0);
68
69  LLVMMetadataRef Int64Ty =
70      LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
71  LLVMMetadataRef Int64TypeDef =
72      LLVMDIBuilderCreateTypedef(DIB, Int64Ty, "int64_t", 7, File, 42, File, 0);
73
74  LLVMMetadataRef GlobalVarValueExpr =
75      LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
76  LLVMDIBuilderCreateGlobalVariableExpression(
77      DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,
78      GlobalVarValueExpr, NULL, 0);
79
80  LLVMMetadataRef NameSpace =
81      LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
82
83  LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
84  LLVMMetadataRef StructDbgTy =
85    LLVMDIBuilderCreateStructType(DIB, NameSpace, "MyStruct",
86    8, File, 0, 192, 0, 0, NULL, StructDbgElts, 3,
87    LLVMDWARFSourceLanguageC, NULL, "MyStruct", 8);
88
89  LLVMMetadataRef StructDbgPtrTy =
90    LLVMDIBuilderCreatePointerType(DIB, StructDbgTy, 192, 0, 0, "", 0);
91
92  LLVMAddNamedMetadataOperand(M, "FooType",
93    LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));
94
95
96  LLVMTypeRef FooParamTys[] = {
97    LLVMInt64Type(),
98    LLVMInt64Type(),
99    LLVMVectorType(LLVMInt64Type(), 10),
100  };
101  LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 3, 0);
102  LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy);
103  LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry");
104
105  LLVMMetadataRef Subscripts[] = {
106    LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),
107  };
108  LLVMMetadataRef VectorTy =
109    LLVMDIBuilderCreateVectorType(DIB, 64 * 10, 0,
110                                  Int64Ty, Subscripts, 1);
111
112
113  LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy};
114  LLVMMetadataRef FunctionTy =
115    LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, 3, 0);
116
117  LLVMMetadataRef ReplaceableFunctionMetadata =
118    LLVMDIBuilderCreateReplaceableCompositeType(DIB, 0x15, "foo", 3,
119                                                File, File, 42,
120                                                0, 0, 0,
121                                                LLVMDIFlagFwdDecl,
122                                                "", 0);
123
124  LLVMMetadataRef FooParamLocation =
125    LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0,
126                                     ReplaceableFunctionMetadata, NULL);
127  LLVMMetadataRef FunctionMetadata =
128    LLVMDIBuilderCreateFunction(DIB, File, "foo", 3, "foo", 3,
129                                File, 42, FunctionTy, true, true,
130                                42, 0, false);
131  LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);
132
133  LLVMMetadataRef FooParamExpression =
134    LLVMDIBuilderCreateExpression(DIB, NULL, 0);
135  LLVMMetadataRef FooParamVar1 =
136    LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,
137                                         42, Int64Ty, true, 0);
138  LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false),
139                                  FooParamVar1, FooParamExpression,
140                                  FooParamLocation, FooEntryBlock);
141  LLVMMetadataRef FooParamVar2 =
142    LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,
143                                         42, Int64Ty, true, 0);
144  LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false),
145                                  FooParamVar2, FooParamExpression,
146                                  FooParamLocation, FooEntryBlock);
147  LLVMMetadataRef FooParamVar3 =
148    LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "c", 1, 3, File,
149                                         42, VectorTy, true, 0);
150  LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false),
151                                  FooParamVar3, FooParamExpression,
152                                  FooParamLocation, FooEntryBlock);
153
154  LLVMSetSubprogram(FooFunction, FunctionMetadata);
155
156  LLVMMetadataRef FooLexicalBlock =
157    LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);
158
159  LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(FooFunction, "vars");
160  LLVMMetadataRef FooVarsLocation =
161    LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 43, 0,
162                                     FunctionMetadata, NULL);
163  LLVMMetadataRef FooVar1 =
164    LLVMDIBuilderCreateAutoVariable(DIB, FooLexicalBlock, "d", 1, File,
165                                    43, Int64Ty, true, 0, 0);
166  LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);
167  LLVMMetadataRef FooVarValueExpr =
168    LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
169
170  LLVMDIBuilderInsertDbgValueAtEnd(DIB, FooVal1, FooVar1, FooVarValueExpr,
171                                   FooVarsLocation, FooVarBlock);
172
173  LLVMMetadataRef MacroFile =
174      LLVMDIBuilderCreateTempMacroFile(DIB, NULL, 0, File);
175  LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
176                           "SIMPLE_DEFINE", 13, NULL, 0);
177  LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
178                           "VALUE_DEFINE", 12, "1", 1);
179
180  LLVMMetadataRef EnumeratorTestA =
181      LLVMDIBuilderCreateEnumerator(DIB, "Test_A", strlen("Test_A"), 0, true);
182  LLVMMetadataRef EnumeratorTestB =
183      LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_B"), 1, true);
184  LLVMMetadataRef EnumeratorTestC =
185      LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_C"), 2, true);
186  LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB,
187                                       EnumeratorTestC};
188  LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType(
189      DIB, NameSpace, "EnumTest", strlen("EnumTest"), File, 0, 64, 0,
190      EnumeratorsTest, 3, Int64Ty);
191  LLVMAddNamedMetadataOperand(
192      M, "EnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), EnumTest));
193
194  LLVMDIBuilderFinalize(DIB);
195
196  char *MStr = LLVMPrintModuleToString(M);
197  puts(MStr);
198  LLVMDisposeMessage(MStr);
199
200  LLVMDisposeDIBuilder(DIB);
201  LLVMDisposeModule(M);
202
203  return 0;
204}
205