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 
20 static LLVMMetadataRef
declare_objc_class(LLVMDIBuilderRef DIB,LLVMMetadataRef File)21 declare_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 
llvm_test_dibuilder(void)31 int 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 = LLVMDIBuilderCreateImportedModuleFromModule(
57       DIB, Module, OtherModule, File, 42, NULL, 0);
58   LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule, File,
59                                              42, NULL, 0);
60 
61   LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
62   LLVMMetadataRef GlobalClassValueExpr =
63       LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
64   LLVMDIBuilderCreateGlobalVariableExpression(
65       DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,
66       GlobalClassValueExpr, NULL, 0);
67 
68   LLVMMetadataRef Int64Ty =
69       LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);
70   LLVMMetadataRef Int64TypeDef =
71       LLVMDIBuilderCreateTypedef(DIB, Int64Ty, "int64_t", 7, File, 42, File, 0);
72 
73   LLVMMetadataRef GlobalVarValueExpr =
74       LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
75   LLVMDIBuilderCreateGlobalVariableExpression(
76       DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,
77       GlobalVarValueExpr, NULL, 0);
78 
79   LLVMMetadataRef NameSpace =
80       LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);
81 
82   LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};
83   LLVMMetadataRef StructDbgTy =
84     LLVMDIBuilderCreateStructType(DIB, NameSpace, "MyStruct",
85     8, File, 0, 192, 0, 0, NULL, StructDbgElts, 3,
86     LLVMDWARFSourceLanguageC, NULL, "MyStruct", 8);
87 
88   LLVMMetadataRef StructDbgPtrTy =
89     LLVMDIBuilderCreatePointerType(DIB, StructDbgTy, 192, 0, 0, "", 0);
90 
91   LLVMAddNamedMetadataOperand(M, "FooType",
92     LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));
93 
94 
95   LLVMTypeRef FooParamTys[] = {
96     LLVMInt64Type(),
97     LLVMInt64Type(),
98     LLVMVectorType(LLVMInt64Type(), 10),
99   };
100   LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 3, 0);
101   LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy);
102   LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry");
103 
104   LLVMMetadataRef Subscripts[] = {
105     LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),
106   };
107   LLVMMetadataRef VectorTy =
108     LLVMDIBuilderCreateVectorType(DIB, 64 * 10, 0,
109                                   Int64Ty, Subscripts, 1);
110 
111 
112   LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy};
113   LLVMMetadataRef FunctionTy =
114     LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, 3, 0);
115 
116   LLVMMetadataRef ReplaceableFunctionMetadata =
117     LLVMDIBuilderCreateReplaceableCompositeType(DIB, 0x15, "foo", 3,
118                                                 File, File, 42,
119                                                 0, 0, 0,
120                                                 LLVMDIFlagFwdDecl,
121                                                 "", 0);
122 
123   LLVMMetadataRef FooParamLocation =
124     LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0,
125                                      ReplaceableFunctionMetadata, NULL);
126   LLVMMetadataRef FunctionMetadata =
127     LLVMDIBuilderCreateFunction(DIB, File, "foo", 3, "foo", 3,
128                                 File, 42, FunctionTy, true, true,
129                                 42, 0, false);
130   LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);
131 
132   LLVMMetadataRef FooParamExpression =
133     LLVMDIBuilderCreateExpression(DIB, NULL, 0);
134   LLVMMetadataRef FooParamVar1 =
135     LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,
136                                          42, Int64Ty, true, 0);
137   LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false),
138                                   FooParamVar1, FooParamExpression,
139                                   FooParamLocation, FooEntryBlock);
140   LLVMMetadataRef FooParamVar2 =
141     LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,
142                                          42, Int64Ty, true, 0);
143   LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false),
144                                   FooParamVar2, FooParamExpression,
145                                   FooParamLocation, FooEntryBlock);
146   LLVMMetadataRef FooParamVar3 =
147     LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "c", 1, 3, File,
148                                          42, VectorTy, true, 0);
149   LLVMDIBuilderInsertDeclareAtEnd(DIB, LLVMConstInt(LLVMInt64Type(), 0, false),
150                                   FooParamVar3, FooParamExpression,
151                                   FooParamLocation, FooEntryBlock);
152 
153   LLVMSetSubprogram(FooFunction, FunctionMetadata);
154 
155   LLVMMetadataRef FooLexicalBlock =
156     LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);
157 
158   LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(FooFunction, "vars");
159   LLVMMetadataRef FooVarsLocation =
160     LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 43, 0,
161                                      FunctionMetadata, NULL);
162   LLVMMetadataRef FooVar1 =
163     LLVMDIBuilderCreateAutoVariable(DIB, FooLexicalBlock, "d", 1, File,
164                                     43, Int64Ty, true, 0, 0);
165   LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);
166   LLVMMetadataRef FooVarValueExpr =
167     LLVMDIBuilderCreateConstantValueExpression(DIB, 0);
168 
169   LLVMDIBuilderInsertDbgValueAtEnd(DIB, FooVal1, FooVar1, FooVarValueExpr,
170                                    FooVarsLocation, FooVarBlock);
171 
172   LLVMMetadataRef MacroFile =
173       LLVMDIBuilderCreateTempMacroFile(DIB, NULL, 0, File);
174   LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
175                            "SIMPLE_DEFINE", 13, NULL, 0);
176   LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,
177                            "VALUE_DEFINE", 12, "1", 1);
178 
179   LLVMMetadataRef EnumeratorTestA =
180       LLVMDIBuilderCreateEnumerator(DIB, "Test_A", strlen("Test_A"), 0, true);
181   LLVMMetadataRef EnumeratorTestB =
182       LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_B"), 1, true);
183   LLVMMetadataRef EnumeratorTestC =
184       LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_C"), 2, true);
185   LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB,
186                                        EnumeratorTestC};
187   LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType(
188       DIB, NameSpace, "EnumTest", strlen("EnumTest"), File, 0, 64, 0,
189       EnumeratorsTest, 3, Int64Ty);
190   LLVMAddNamedMetadataOperand(
191       M, "EnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), EnumTest));
192 
193   LLVMDIBuilderFinalize(DIB);
194 
195   char *MStr = LLVMPrintModuleToString(M);
196   puts(MStr);
197   LLVMDisposeMessage(MStr);
198 
199   LLVMDisposeDIBuilder(DIB);
200   LLVMDisposeModule(M);
201 
202   return 0;
203 }
204