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/DebugInfo.h" |
16 | |
17 | #include <assert.h> |
18 | #include <stdio.h> |
19 | #include <string.h> |
20 | |
21 | static LLVMMetadataRef |
22 | declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) { |
23 | 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); |
24 | 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); |
25 | LLVMDIBuilderCreateInheritance(Builder: DIB, Ty: Decl, BaseTy: SuperDecl, BaseOffset: 0, VBPtrOffset: 0, Flags: 0); |
26 | LLVMMetadataRef TestProperty = |
27 | 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); |
28 | LLVMDIBuilderCreateObjCIVar(Builder: DIB, Name: "_test" , NameLen: 5, File, LineNo: 42, SizeInBits: 64, AlignInBits: 0, OffsetInBits: 64, Flags: LLVMDIFlagPublic, Ty: SuperDecl, PropertyNode: TestProperty); |
29 | return Decl; |
30 | } |
31 | |
32 | int llvm_test_dibuilder(bool NewDebugInfoFormat) { |
33 | const char *Filename = "debuginfo.c" ; |
34 | LLVMModuleRef M = LLVMModuleCreateWithName(ModuleID: Filename); |
35 | LLVMSetIsNewDbgInfoFormat(M, UseNewFormat: NewDebugInfoFormat); |
36 | LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M); |
37 | |
38 | LLVMMetadataRef File = LLVMDIBuilderCreateFile(Builder: DIB, Filename, |
39 | FilenameLen: strlen(s: Filename), Directory: "." , DirectoryLen: 1); |
40 | |
41 | LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit( |
42 | Builder: DIB, Lang: LLVMDWARFSourceLanguageC, FileRef: File, Producer: "llvm-c-test" , ProducerLen: 11, isOptimized: 0, NULL, FlagsLen: 0, RuntimeVer: 0, |
43 | NULL, SplitNameLen: 0, Kind: LLVMDWARFEmissionFull, DWOId: 0, SplitDebugInlining: 0, DebugInfoForProfiling: 0, SysRoot: "/" , SysRootLen: 1, SDK: "" , SDKLen: 0); |
44 | |
45 | LLVMMetadataRef Module = |
46 | LLVMDIBuilderCreateModule(Builder: DIB, ParentScope: CompileUnit, |
47 | Name: "llvm-c-test" , NameLen: 11, |
48 | ConfigMacros: "" , ConfigMacrosLen: 0, |
49 | IncludePath: "/test/include/llvm-c-test.h" , IncludePathLen: 27, |
50 | APINotesFile: "" , APINotesFileLen: 0); |
51 | |
52 | LLVMMetadataRef OtherModule = |
53 | LLVMDIBuilderCreateModule(Builder: DIB, ParentScope: CompileUnit, |
54 | Name: "llvm-c-test-import" , NameLen: 18, |
55 | ConfigMacros: "" , ConfigMacrosLen: 0, |
56 | IncludePath: "/test/include/llvm-c-test-import.h" , IncludePathLen: 34, |
57 | APINotesFile: "" , APINotesFileLen: 0); |
58 | LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule( |
59 | Builder: DIB, Scope: Module, M: OtherModule, File, Line: 42, NULL, NumElements: 0); |
60 | LLVMDIBuilderCreateImportedModuleFromAlias(Builder: DIB, Scope: Module, ImportedEntity: ImportedModule, File, |
61 | Line: 42, NULL, NumElements: 0); |
62 | |
63 | LLVMMetadataRef ClassTy = declare_objc_class(DIB, File); |
64 | LLVMMetadataRef GlobalClassValueExpr = |
65 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0); |
66 | LLVMDIBuilderCreateGlobalVariableExpression( |
67 | Builder: DIB, Scope: Module, Name: "globalClass" , NameLen: 11, Linkage: "" , LinkLen: 0, File, LineNo: 1, Ty: ClassTy, true, |
68 | Expr: GlobalClassValueExpr, NULL, AlignInBits: 0); |
69 | |
70 | LLVMMetadataRef Int64Ty = |
71 | LLVMDIBuilderCreateBasicType(Builder: DIB, Name: "Int64" , NameLen: 5, SizeInBits: 64, Encoding: 0, Flags: LLVMDIFlagZero); |
72 | LLVMMetadataRef Int64TypeDef = |
73 | LLVMDIBuilderCreateTypedef(Builder: DIB, Type: Int64Ty, Name: "int64_t" , NameLen: 7, File, LineNo: 42, Scope: File, AlignInBits: 0); |
74 | |
75 | LLVMMetadataRef GlobalVarValueExpr = |
76 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0); |
77 | LLVMDIBuilderCreateGlobalVariableExpression( |
78 | Builder: DIB, Scope: Module, Name: "global" , NameLen: 6, Linkage: "" , LinkLen: 0, File, LineNo: 1, Ty: Int64TypeDef, true, |
79 | Expr: GlobalVarValueExpr, NULL, AlignInBits: 0); |
80 | |
81 | LLVMMetadataRef NameSpace = |
82 | LLVMDIBuilderCreateNameSpace(Builder: DIB, ParentScope: Module, Name: "NameSpace" , NameLen: 9, false); |
83 | |
84 | LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty}; |
85 | LLVMMetadataRef StructDbgTy = |
86 | LLVMDIBuilderCreateStructType(Builder: DIB, Scope: NameSpace, Name: "MyStruct" , |
87 | NameLen: 8, File, LineNumber: 0, SizeInBits: 192, AlignInBits: 0, Flags: 0, NULL, Elements: StructDbgElts, NumElements: 3, |
88 | RunTimeLang: LLVMDWARFSourceLanguageC, NULL, UniqueId: "MyStruct" , UniqueIdLen: 8); |
89 | |
90 | LLVMMetadataRef StructDbgPtrTy = |
91 | LLVMDIBuilderCreatePointerType(Builder: DIB, PointeeTy: StructDbgTy, SizeInBits: 192, AlignInBits: 0, AddressSpace: 0, Name: "" , NameLen: 0); |
92 | |
93 | LLVMAddNamedMetadataOperand(M, Name: "FooType" , |
94 | Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: StructDbgPtrTy)); |
95 | |
96 | |
97 | LLVMTypeRef FooParamTys[] = { |
98 | LLVMInt64Type(), |
99 | LLVMInt64Type(), |
100 | LLVMVectorType(ElementType: LLVMInt64Type(), ElementCount: 10), |
101 | }; |
102 | LLVMTypeRef FooFuncTy = LLVMFunctionType(ReturnType: LLVMInt64Type(), ParamTypes: FooParamTys, ParamCount: 3, IsVarArg: 0); |
103 | LLVMValueRef FooFunction = LLVMAddFunction(M, Name: "foo" , FunctionTy: FooFuncTy); |
104 | LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(Fn: FooFunction, Name: "entry" ); |
105 | |
106 | LLVMMetadataRef Subscripts[] = { |
107 | LLVMDIBuilderGetOrCreateSubrange(Builder: DIB, LowerBound: 0, Count: 10), |
108 | }; |
109 | LLVMMetadataRef VectorTy = |
110 | LLVMDIBuilderCreateVectorType(Builder: DIB, Size: 64 * 10, AlignInBits: 0, |
111 | Ty: Int64Ty, Subscripts, NumSubscripts: 1); |
112 | |
113 | |
114 | LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy}; |
115 | LLVMMetadataRef FunctionTy = |
116 | LLVMDIBuilderCreateSubroutineType(Builder: DIB, File, ParameterTypes: ParamTypes, NumParameterTypes: 3, Flags: 0); |
117 | |
118 | LLVMMetadataRef ReplaceableFunctionMetadata = |
119 | LLVMDIBuilderCreateReplaceableCompositeType(Builder: DIB, Tag: 0x15, Name: "foo" , NameLen: 3, |
120 | Scope: File, File, Line: 42, |
121 | RuntimeLang: 0, SizeInBits: 0, AlignInBits: 0, |
122 | Flags: LLVMDIFlagFwdDecl, |
123 | UniqueIdentifier: "" , UniqueIdentifierLen: 0); |
124 | |
125 | LLVMMetadataRef FooParamLocation = |
126 | LLVMDIBuilderCreateDebugLocation(Ctx: LLVMGetGlobalContext(), Line: 42, Column: 0, |
127 | Scope: ReplaceableFunctionMetadata, NULL); |
128 | LLVMMetadataRef FunctionMetadata = |
129 | LLVMDIBuilderCreateFunction(Builder: DIB, Scope: File, Name: "foo" , NameLen: 3, LinkageName: "foo" , LinkageNameLen: 3, |
130 | File, LineNo: 42, Ty: FunctionTy, true, true, |
131 | ScopeLine: 42, Flags: 0, false); |
132 | LLVMMetadataReplaceAllUsesWith(TempTargetMetadata: ReplaceableFunctionMetadata, Replacement: FunctionMetadata); |
133 | |
134 | LLVMMetadataRef FooParamExpression = |
135 | LLVMDIBuilderCreateExpression(Builder: DIB, NULL, Length: 0); |
136 | LLVMMetadataRef FooParamVar1 = |
137 | LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "a" , NameLen: 1, ArgNo: 1, File, |
138 | LineNo: 42, Ty: Int64Ty, true, Flags: 0); |
139 | |
140 | if (LLVMIsNewDbgInfoFormat(M)) |
141 | LLVMDIBuilderInsertDeclareAtEnd( |
142 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar1, |
143 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
144 | else |
145 | LLVMDIBuilderInsertDeclareIntrinsicAtEnd( |
146 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar1, |
147 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
148 | LLVMMetadataRef FooParamVar2 = |
149 | LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "b" , NameLen: 1, ArgNo: 2, File, |
150 | LineNo: 42, Ty: Int64Ty, true, Flags: 0); |
151 | |
152 | if (LLVMIsNewDbgInfoFormat(M)) |
153 | LLVMDIBuilderInsertDeclareAtEnd( |
154 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar2, |
155 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
156 | else |
157 | LLVMDIBuilderInsertDeclareIntrinsicAtEnd( |
158 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar2, |
159 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
160 | |
161 | LLVMMetadataRef FooParamVar3 = |
162 | LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "c" , NameLen: 1, ArgNo: 3, File, |
163 | LineNo: 42, Ty: VectorTy, true, Flags: 0); |
164 | if (LLVMIsNewDbgInfoFormat(M)) |
165 | LLVMDIBuilderInsertDeclareAtEnd( |
166 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar3, |
167 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
168 | else |
169 | LLVMDIBuilderInsertDeclareIntrinsicAtEnd( |
170 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar3, |
171 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
172 | |
173 | LLVMSetSubprogram(Func: FooFunction, SP: FunctionMetadata); |
174 | |
175 | LLVMMetadataRef FooLexicalBlock = |
176 | LLVMDIBuilderCreateLexicalBlock(Builder: DIB, Scope: FunctionMetadata, File, Line: 42, Column: 0); |
177 | |
178 | LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(Fn: FooFunction, Name: "vars" ); |
179 | LLVMMetadataRef FooVarsLocation = |
180 | LLVMDIBuilderCreateDebugLocation(Ctx: LLVMGetGlobalContext(), Line: 43, Column: 0, |
181 | 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: LLVMInt64Type(), N: 0, false); |
186 | LLVMMetadataRef FooVarValueExpr = |
187 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0); |
188 | if (LLVMIsNewDbgInfoFormat(M)) |
189 | LLVMDIBuilderInsertDbgValueRecordAtEnd( |
190 | Builder: DIB, Val: FooVal1, VarInfo: FooVar1, Expr: FooVarValueExpr, DebugLoc: FooVarsLocation, Block: FooVarBlock); |
191 | else |
192 | LLVMDIBuilderInsertDbgValueIntrinsicAtEnd( |
193 | Builder: DIB, Val: FooVal1, VarInfo: FooVar1, Expr: FooVarValueExpr, DebugLoc: FooVarsLocation, Block: FooVarBlock); |
194 | |
195 | LLVMMetadataRef MacroFile = |
196 | LLVMDIBuilderCreateTempMacroFile(Builder: DIB, NULL, Line: 0, File); |
197 | LLVMDIBuilderCreateMacro(Builder: DIB, ParentMacroFile: MacroFile, Line: 0, RecordType: LLVMDWARFMacinfoRecordTypeDefine, |
198 | Name: "SIMPLE_DEFINE" , NameLen: 13, NULL, ValueLen: 0); |
199 | LLVMDIBuilderCreateMacro(Builder: DIB, ParentMacroFile: MacroFile, Line: 0, RecordType: LLVMDWARFMacinfoRecordTypeDefine, |
200 | Name: "VALUE_DEFINE" , NameLen: 12, Value: "1" , ValueLen: 1); |
201 | |
202 | LLVMMetadataRef EnumeratorTestA = |
203 | LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_A" , NameLen: strlen(s: "Test_A" ), Value: 0, true); |
204 | LLVMMetadataRef EnumeratorTestB = |
205 | LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_B" , NameLen: strlen(s: "Test_B" ), Value: 1, true); |
206 | LLVMMetadataRef EnumeratorTestC = |
207 | LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_B" , NameLen: strlen(s: "Test_C" ), Value: 2, true); |
208 | LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB, |
209 | EnumeratorTestC}; |
210 | LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType( |
211 | Builder: DIB, Scope: NameSpace, Name: "EnumTest" , NameLen: strlen(s: "EnumTest" ), File, LineNumber: 0, SizeInBits: 64, AlignInBits: 0, |
212 | Elements: EnumeratorsTest, NumElements: 3, ClassTy: Int64Ty); |
213 | LLVMAddNamedMetadataOperand( |
214 | M, Name: "EnumTest" , Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: EnumTest)); |
215 | |
216 | LLVMDIBuilderFinalize(Builder: DIB); |
217 | |
218 | char *MStr = LLVMPrintModuleToString(M); |
219 | puts(s: MStr); |
220 | LLVMDisposeMessage(Message: MStr); |
221 | |
222 | LLVMDisposeDIBuilder(Builder: DIB); |
223 | LLVMDisposeModule(M); |
224 | |
225 | return 0; |
226 | } |
227 | |
228 | int llvm_get_di_tag(void) { |
229 | LLVMModuleRef M = LLVMModuleCreateWithName(ModuleID: "Mod" ); |
230 | LLVMContextRef Context = LLVMGetModuleContext(M); |
231 | |
232 | const char String[] = "foo" ; |
233 | LLVMMetadataRef StringMD = |
234 | LLVMMDStringInContext2(C: Context, Str: String, SLen: strlen(s: String)); |
235 | LLVMMetadataRef NodeMD = LLVMMDNodeInContext2(C: Context, MDs: &StringMD, Count: 1); |
236 | assert(LLVMGetDINodeTag(NodeMD) == 0); |
237 | (void)NodeMD; |
238 | |
239 | LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M); |
240 | const char Filename[] = "metadata.c" ; |
241 | const char Directory[] = "." ; |
242 | LLVMMetadataRef File = LLVMDIBuilderCreateFile( |
243 | Builder, Filename, FilenameLen: strlen(s: Filename), Directory, DirectoryLen: strlen(s: Directory)); |
244 | const char Name[] = "TestClass" ; |
245 | LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType( |
246 | Builder, Scope: File, Name, NameLen: strlen(s: Name), File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, |
247 | Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0); |
248 | assert(LLVMGetDINodeTag(Struct) == 0x13); |
249 | (void)Struct; |
250 | |
251 | LLVMDisposeDIBuilder(Builder); |
252 | LLVMDisposeModule(M); |
253 | |
254 | return 0; |
255 | } |
256 | |
257 | int llvm_di_type_get_name(void) { |
258 | LLVMModuleRef M = LLVMModuleCreateWithName(ModuleID: "Mod" ); |
259 | |
260 | LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M); |
261 | const char Filename[] = "metadata.c" ; |
262 | const char Directory[] = "." ; |
263 | LLVMMetadataRef File = LLVMDIBuilderCreateFile( |
264 | Builder, Filename, FilenameLen: strlen(s: Filename), Directory, DirectoryLen: strlen(s: Directory)); |
265 | const char Name[] = "TestClass" ; |
266 | LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType( |
267 | Builder, Scope: File, Name, NameLen: strlen(s: Name), File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, |
268 | Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0); |
269 | |
270 | size_t Len; |
271 | const char *TypeName = LLVMDITypeGetName(DType: Struct, Length: &Len); |
272 | assert(Len == strlen(Name)); |
273 | assert(strncmp(TypeName, Name, Len) == 0); |
274 | (void)TypeName; |
275 | |
276 | LLVMDisposeDIBuilder(Builder); |
277 | LLVMDisposeModule(M); |
278 | |
279 | return 0; |
280 | } |
281 | |