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/DebugInfo.h" |
15 | #include "llvm-c-test.h" |
16 | #include "llvm-c/Core.h" |
17 | #include "llvm-c/Types.h" |
18 | |
19 | #include <assert.h> |
20 | #include <stdio.h> |
21 | #include <string.h> |
22 | |
23 | static LLVMMetadataRef |
24 | declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) { |
25 | 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); |
26 | 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); |
27 | LLVMDIBuilderCreateInheritance(Builder: DIB, Ty: Decl, BaseTy: SuperDecl, BaseOffset: 0, VBPtrOffset: 0, Flags: 0); |
28 | LLVMMetadataRef TestProperty = |
29 | 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); |
30 | LLVMDIBuilderCreateObjCIVar(Builder: DIB, Name: "_test" , NameLen: 5, File, LineNo: 42, SizeInBits: 64, AlignInBits: 0, OffsetInBits: 64, Flags: LLVMDIFlagPublic, Ty: SuperDecl, PropertyNode: TestProperty); |
31 | return Decl; |
32 | } |
33 | |
34 | int llvm_test_dibuilder(void) { |
35 | const char *Filename = "debuginfo.c" ; |
36 | LLVMModuleRef M = LLVMModuleCreateWithName(ModuleID: Filename); |
37 | |
38 | LLVMSetIsNewDbgInfoFormat(M, true); |
39 | assert(LLVMIsNewDbgInfoFormat(M)); |
40 | |
41 | LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M); |
42 | |
43 | LLVMMetadataRef File = LLVMDIBuilderCreateFile(Builder: DIB, Filename, |
44 | FilenameLen: strlen(s: Filename), Directory: "." , DirectoryLen: 1); |
45 | |
46 | LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit( |
47 | Builder: DIB, Lang: LLVMDWARFSourceLanguageC, FileRef: File, Producer: "llvm-c-test" , ProducerLen: 11, isOptimized: 0, NULL, FlagsLen: 0, RuntimeVer: 0, |
48 | NULL, SplitNameLen: 0, Kind: LLVMDWARFEmissionFull, DWOId: 0, SplitDebugInlining: 0, DebugInfoForProfiling: 0, SysRoot: "/" , SysRootLen: 1, SDK: "" , SDKLen: 0); |
49 | |
50 | LLVMMetadataRef Module = |
51 | LLVMDIBuilderCreateModule(Builder: DIB, ParentScope: CompileUnit, |
52 | Name: "llvm-c-test" , NameLen: 11, |
53 | ConfigMacros: "" , ConfigMacrosLen: 0, |
54 | IncludePath: "/test/include/llvm-c-test.h" , IncludePathLen: 27, |
55 | APINotesFile: "" , APINotesFileLen: 0); |
56 | |
57 | LLVMMetadataRef OtherModule = |
58 | LLVMDIBuilderCreateModule(Builder: DIB, ParentScope: CompileUnit, |
59 | Name: "llvm-c-test-import" , NameLen: 18, |
60 | ConfigMacros: "" , ConfigMacrosLen: 0, |
61 | IncludePath: "/test/include/llvm-c-test-import.h" , IncludePathLen: 34, |
62 | APINotesFile: "" , APINotesFileLen: 0); |
63 | LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule( |
64 | Builder: DIB, Scope: Module, M: OtherModule, File, Line: 42, NULL, NumElements: 0); |
65 | LLVMDIBuilderCreateImportedModuleFromAlias(Builder: DIB, Scope: Module, ImportedEntity: ImportedModule, File, |
66 | Line: 42, NULL, NumElements: 0); |
67 | |
68 | LLVMMetadataRef ClassTy = declare_objc_class(DIB, File); |
69 | LLVMMetadataRef GlobalClassValueExpr = |
70 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0); |
71 | LLVMDIBuilderCreateGlobalVariableExpression( |
72 | Builder: DIB, Scope: Module, Name: "globalClass" , NameLen: 11, Linkage: "" , LinkLen: 0, File, LineNo: 1, Ty: ClassTy, true, |
73 | Expr: GlobalClassValueExpr, NULL, AlignInBits: 0); |
74 | |
75 | LLVMMetadataRef Int64Ty = |
76 | LLVMDIBuilderCreateBasicType(Builder: DIB, Name: "Int64" , NameLen: 5, SizeInBits: 64, Encoding: 0, Flags: LLVMDIFlagZero); |
77 | LLVMMetadataRef Int64TypeDef = |
78 | LLVMDIBuilderCreateTypedef(Builder: DIB, Type: Int64Ty, Name: "int64_t" , NameLen: 7, File, LineNo: 42, Scope: File, AlignInBits: 0); |
79 | |
80 | LLVMMetadataRef GlobalVarValueExpr = |
81 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0); |
82 | LLVMDIBuilderCreateGlobalVariableExpression( |
83 | Builder: DIB, Scope: Module, Name: "global" , NameLen: 6, Linkage: "" , LinkLen: 0, File, LineNo: 1, Ty: Int64TypeDef, true, |
84 | Expr: GlobalVarValueExpr, NULL, AlignInBits: 0); |
85 | |
86 | LLVMMetadataRef NameSpace = |
87 | LLVMDIBuilderCreateNameSpace(Builder: DIB, ParentScope: Module, Name: "NameSpace" , NameLen: 9, false); |
88 | |
89 | LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty}; |
90 | LLVMMetadataRef StructDbgTy = |
91 | LLVMDIBuilderCreateStructType(Builder: DIB, Scope: NameSpace, Name: "MyStruct" , |
92 | NameLen: 8, File, LineNumber: 0, SizeInBits: 192, AlignInBits: 0, Flags: 0, NULL, Elements: StructDbgElts, NumElements: 3, |
93 | RunTimeLang: LLVMDWARFSourceLanguageC, NULL, UniqueId: "MyStruct" , UniqueIdLen: 8); |
94 | |
95 | LLVMMetadataRef StructDbgPtrTy = |
96 | LLVMDIBuilderCreatePointerType(Builder: DIB, PointeeTy: StructDbgTy, SizeInBits: 192, AlignInBits: 0, AddressSpace: 0, Name: "" , NameLen: 0); |
97 | |
98 | LLVMAddNamedMetadataOperand(M, Name: "FooType" , |
99 | Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: StructDbgPtrTy)); |
100 | |
101 | |
102 | LLVMTypeRef FooParamTys[] = { |
103 | LLVMInt64Type(), |
104 | LLVMInt64Type(), |
105 | LLVMVectorType(ElementType: LLVMInt64Type(), ElementCount: 10), |
106 | }; |
107 | LLVMTypeRef FooFuncTy = LLVMFunctionType(ReturnType: LLVMInt64Type(), ParamTypes: FooParamTys, ParamCount: 3, IsVarArg: 0); |
108 | LLVMValueRef FooFunction = LLVMAddFunction(M, Name: "foo" , FunctionTy: FooFuncTy); |
109 | LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(Fn: FooFunction, Name: "entry" ); |
110 | |
111 | LLVMMetadataRef Subscripts[] = { |
112 | LLVMDIBuilderGetOrCreateSubrange(Builder: DIB, LowerBound: 0, Count: 10), |
113 | }; |
114 | LLVMMetadataRef VectorTy = |
115 | LLVMDIBuilderCreateVectorType(Builder: DIB, Size: 64 * 10, AlignInBits: 0, |
116 | Ty: Int64Ty, Subscripts, NumSubscripts: 1); |
117 | |
118 | |
119 | LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy}; |
120 | LLVMMetadataRef FunctionTy = |
121 | LLVMDIBuilderCreateSubroutineType(Builder: DIB, File, ParameterTypes: ParamTypes, NumParameterTypes: 3, Flags: 0); |
122 | |
123 | LLVMMetadataRef ReplaceableFunctionMetadata = |
124 | LLVMDIBuilderCreateReplaceableCompositeType(Builder: DIB, Tag: 0x15, Name: "foo" , NameLen: 3, |
125 | Scope: File, File, Line: 42, |
126 | RuntimeLang: 0, SizeInBits: 0, AlignInBits: 0, |
127 | Flags: LLVMDIFlagFwdDecl, |
128 | UniqueIdentifier: "" , UniqueIdentifierLen: 0); |
129 | |
130 | LLVMMetadataRef FooParamLocation = |
131 | LLVMDIBuilderCreateDebugLocation(Ctx: LLVMGetGlobalContext(), Line: 42, Column: 0, |
132 | Scope: ReplaceableFunctionMetadata, NULL); |
133 | LLVMMetadataRef FunctionMetadata = LLVMDIBuilderCreateFunction( |
134 | Builder: DIB, Scope: File, Name: "foo" , NameLen: 3, LinkageName: "foo" , LinkageNameLen: 3, File, LineNo: 42, NULL, true, true, ScopeLine: 42, Flags: 0, false); |
135 | LLVMMetadataReplaceAllUsesWith(TempTargetMetadata: ReplaceableFunctionMetadata, Replacement: FunctionMetadata); |
136 | |
137 | LLVMDISubprogramReplaceType(Subprogram: FunctionMetadata, SubroutineType: FunctionTy); |
138 | |
139 | LLVMMetadataRef FooParamExpression = |
140 | LLVMDIBuilderCreateExpression(Builder: DIB, NULL, Length: 0); |
141 | LLVMMetadataRef FooParamVar1 = |
142 | LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "a" , NameLen: 1, ArgNo: 1, File, |
143 | LineNo: 42, Ty: Int64Ty, true, Flags: 0); |
144 | |
145 | LLVMDIBuilderInsertDeclareRecordAtEnd( |
146 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar1, |
147 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
148 | |
149 | LLVMMetadataRef FooParamVar2 = |
150 | LLVMDIBuilderCreateParameterVariable(Builder: DIB, Scope: FunctionMetadata, Name: "b" , NameLen: 1, ArgNo: 2, File, |
151 | LineNo: 42, Ty: Int64Ty, true, Flags: 0); |
152 | |
153 | LLVMDIBuilderInsertDeclareRecordAtEnd( |
154 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar2, |
155 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
156 | |
157 | LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable( |
158 | Builder: DIB, Scope: FunctionMetadata, Name: "c" , NameLen: 1, ArgNo: 3, File, LineNo: 42, Ty: VectorTy, true, Flags: 0); |
159 | |
160 | LLVMDIBuilderInsertDeclareRecordAtEnd( |
161 | Builder: DIB, Storage: LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false), VarInfo: FooParamVar3, |
162 | Expr: FooParamExpression, DebugLoc: FooParamLocation, Block: FooEntryBlock); |
163 | |
164 | LLVMSetSubprogram(Func: FooFunction, SP: FunctionMetadata); |
165 | |
166 | LLVMMetadataRef FooLabel1 = LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata, |
167 | Name: "label1" , NameLen: 6, File, LineNo: 42, false); |
168 | LLVMDIBuilderInsertLabelAtEnd(Builder: DIB, LabelInfo: FooLabel1, Location: FooParamLocation, |
169 | InsertAtEnd: FooEntryBlock); |
170 | |
171 | LLVMMetadataRef FooLexicalBlock = |
172 | LLVMDIBuilderCreateLexicalBlock(Builder: DIB, Scope: FunctionMetadata, File, Line: 42, Column: 0); |
173 | |
174 | LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(Fn: FooFunction, Name: "vars" ); |
175 | LLVMMetadataRef FooVarsLocation = |
176 | LLVMDIBuilderCreateDebugLocation(Ctx: LLVMGetGlobalContext(), Line: 43, Column: 0, |
177 | Scope: FunctionMetadata, NULL); |
178 | LLVMMetadataRef FooVar1 = |
179 | LLVMDIBuilderCreateAutoVariable(Builder: DIB, Scope: FooLexicalBlock, Name: "d" , NameLen: 1, File, |
180 | LineNo: 43, Ty: Int64Ty, true, Flags: 0, AlignInBits: 0); |
181 | LLVMValueRef FooVal1 = LLVMConstInt(IntTy: LLVMInt64Type(), N: 0, false); |
182 | LLVMMetadataRef FooVarValueExpr1 = |
183 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 0); |
184 | |
185 | LLVMDIBuilderInsertDbgValueRecordAtEnd( |
186 | Builder: DIB, Val: FooVal1, VarInfo: FooVar1, Expr: FooVarValueExpr1, DebugLoc: FooVarsLocation, Block: FooVarBlock); |
187 | |
188 | LLVMMetadataRef FooVar2 = LLVMDIBuilderCreateAutoVariable( |
189 | Builder: DIB, Scope: FooLexicalBlock, Name: "e" , NameLen: 1, File, LineNo: 44, Ty: Int64Ty, true, Flags: 0, AlignInBits: 0); |
190 | LLVMValueRef FooVal2 = LLVMConstInt(IntTy: LLVMInt64Type(), N: 1, false); |
191 | LLVMMetadataRef FooVarValueExpr2 = |
192 | LLVMDIBuilderCreateConstantValueExpression(Builder: DIB, Value: 1); |
193 | |
194 | LLVMDIBuilderInsertDbgValueRecordAtEnd( |
195 | Builder: DIB, Val: FooVal2, VarInfo: FooVar2, Expr: FooVarValueExpr2, DebugLoc: FooVarsLocation, Block: FooVarBlock); |
196 | |
197 | LLVMMetadataRef MacroFile = |
198 | LLVMDIBuilderCreateTempMacroFile(Builder: DIB, NULL, Line: 0, File); |
199 | LLVMDIBuilderCreateMacro(Builder: DIB, ParentMacroFile: MacroFile, Line: 0, RecordType: LLVMDWARFMacinfoRecordTypeDefine, |
200 | Name: "SIMPLE_DEFINE" , NameLen: 13, NULL, ValueLen: 0); |
201 | LLVMDIBuilderCreateMacro(Builder: DIB, ParentMacroFile: MacroFile, Line: 0, RecordType: LLVMDWARFMacinfoRecordTypeDefine, |
202 | Name: "VALUE_DEFINE" , NameLen: 12, Value: "1" , ValueLen: 1); |
203 | |
204 | LLVMMetadataRef EnumeratorTestA = |
205 | LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_A" , NameLen: strlen(s: "Test_A" ), Value: 0, true); |
206 | LLVMMetadataRef EnumeratorTestB = |
207 | LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_B" , NameLen: strlen(s: "Test_B" ), Value: 1, true); |
208 | LLVMMetadataRef EnumeratorTestC = |
209 | LLVMDIBuilderCreateEnumerator(Builder: DIB, Name: "Test_B" , NameLen: strlen(s: "Test_C" ), Value: 2, true); |
210 | LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB, |
211 | EnumeratorTestC}; |
212 | LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType( |
213 | Builder: DIB, Scope: NameSpace, Name: "EnumTest" , NameLen: strlen(s: "EnumTest" ), File, LineNumber: 0, SizeInBits: 64, AlignInBits: 0, |
214 | Elements: EnumeratorsTest, NumElements: 3, ClassTy: Int64Ty); |
215 | LLVMAddNamedMetadataOperand( |
216 | M, Name: "EnumTest" , Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: EnumTest)); |
217 | |
218 | LLVMMetadataRef UInt128Ty = LLVMDIBuilderCreateBasicType( |
219 | Builder: DIB, Name: "UInt128" , NameLen: strlen(s: "UInt128" ), SizeInBits: 128, Encoding: 0, Flags: LLVMDIFlagZero); |
220 | const uint64_t WordsTestD[] = {0x098a224000000000ull, 0x4b3b4ca85a86c47aull}; |
221 | const uint64_t WordsTestE[] = {0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull}; |
222 | |
223 | LLVMMetadataRef LargeEnumeratorTestD = |
224 | LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision( |
225 | Builder: DIB, Name: "Test_D" , NameLen: strlen(s: "Test_D" ), SizeInBits: 128, Words: WordsTestD, false); |
226 | LLVMMetadataRef LargeEnumeratorTestE = |
227 | LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision( |
228 | Builder: DIB, Name: "Test_E" , NameLen: strlen(s: "Test_E" ), SizeInBits: 128, Words: WordsTestE, false); |
229 | LLVMMetadataRef LargeEnumeratorsTest[] = {LargeEnumeratorTestD, |
230 | LargeEnumeratorTestE}; |
231 | LLVMMetadataRef LargeEnumTest = LLVMDIBuilderCreateEnumerationType( |
232 | Builder: DIB, Scope: NameSpace, Name: "LargeEnumTest" , NameLen: strlen(s: "LargeEnumTest" ), File, LineNumber: 0, SizeInBits: 128, AlignInBits: 0, |
233 | Elements: LargeEnumeratorsTest, NumElements: 2, ClassTy: UInt128Ty); |
234 | LLVMAddNamedMetadataOperand( |
235 | M, Name: "LargeEnumTest" , |
236 | Val: LLVMMetadataAsValue(C: LLVMGetModuleContext(M), MD: LargeEnumTest)); |
237 | |
238 | // Using the new debug format, debug records get attached to instructions. |
239 | // Insert a `br` and `ret` now to absorb the debug records which are |
240 | // currently "trailing", meaning that they're associated with a block |
241 | // but no particular instruction, which is only valid as a transient state. |
242 | LLVMContextRef Ctx = LLVMGetModuleContext(M); |
243 | LLVMBuilderRef Builder = LLVMCreateBuilderInContext(C: Ctx); |
244 | LLVMPositionBuilderAtEnd(Builder, Block: FooEntryBlock); |
245 | // Build `br label %vars` in entry. |
246 | LLVMBuildBr(Builder, Dest: FooVarBlock); |
247 | |
248 | // Build another br for the sake of testing labels. |
249 | LLVMMetadataRef FooLabel2 = LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata, |
250 | Name: "label2" , NameLen: 6, File, LineNo: 42, false); |
251 | LLVMDIBuilderInsertLabelBefore(Builder: DIB, LabelInfo: FooLabel2, Location: FooParamLocation, |
252 | InsertBefore: LLVMBuildBr(Builder, Dest: FooVarBlock)); |
253 | // label3 will be emitted, but label4 won't be emitted |
254 | // because label3 is AlwaysPreserve and label4 is not. |
255 | LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata, |
256 | Name: "label3" , NameLen: 6, File, LineNo: 42, true); |
257 | LLVMDIBuilderCreateLabel(Builder: DIB, Context: FunctionMetadata, |
258 | Name: "label4" , NameLen: 6, File, LineNo: 42, false); |
259 | LLVMDIBuilderFinalize(Builder: DIB); |
260 | |
261 | // Build `ret i64 0` in vars. |
262 | LLVMPositionBuilderAtEnd(Builder, Block: FooVarBlock); |
263 | LLVMTypeRef I64 = LLVMInt64TypeInContext(C: Ctx); |
264 | LLVMValueRef Zero = LLVMConstInt(IntTy: I64, N: 0, false); |
265 | LLVMValueRef Ret = LLVMBuildRet(Builder, V: Zero); |
266 | |
267 | // Insert a `phi` before the `ret`. In the new debug info mode we need to |
268 | // be careful to insert before debug records too, else the debug records |
269 | // will come before the `phi` (and be absorbed onto it) which is an invalid |
270 | // state. |
271 | LLVMValueRef InsertPos = LLVMGetFirstInstruction(BB: FooVarBlock); |
272 | LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, Instr: InsertPos); |
273 | LLVMValueRef Phi1 = LLVMBuildPhi(Builder, Ty: I64, Name: "p1" ); |
274 | LLVMAddIncoming(PhiNode: Phi1, IncomingValues: &Zero, IncomingBlocks: &FooEntryBlock, Count: 1); |
275 | |
276 | // Do the same again using the other position-setting function. |
277 | LLVMPositionBuilderBeforeDbgRecords(Builder, Block: FooVarBlock, Inst: InsertPos); |
278 | LLVMValueRef Phi2 = LLVMBuildPhi(Builder, Ty: I64, Name: "p2" ); |
279 | LLVMAddIncoming(PhiNode: Phi2, IncomingValues: &Zero, IncomingBlocks: &FooEntryBlock, Count: 1); |
280 | |
281 | // Insert a non-phi before the `ret` but not before the debug records to |
282 | // test that works as expected. |
283 | LLVMPositionBuilder(Builder, Block: FooVarBlock, Instr: Ret); |
284 | LLVMValueRef Add = LLVMBuildAdd(Builder, LHS: Phi1, RHS: Phi2, Name: "a" ); |
285 | |
286 | // Iterate over debug records in the add instruction. There should be two. |
287 | LLVMDbgRecordRef AddDbgRecordFirst = LLVMGetFirstDbgRecord(Inst: Add); |
288 | assert(AddDbgRecordFirst != NULL); |
289 | LLVMDbgRecordRef AddDbgRecordSecond = LLVMGetNextDbgRecord(DbgRecord: AddDbgRecordFirst); |
290 | assert(AddDbgRecordSecond != NULL); |
291 | LLVMDbgRecordRef AddDbgRecordLast = LLVMGetLastDbgRecord(Inst: Add); |
292 | assert(AddDbgRecordLast != NULL); |
293 | (void)AddDbgRecordLast; |
294 | assert(AddDbgRecordSecond == AddDbgRecordLast); |
295 | LLVMDbgRecordRef AddDbgRecordOverTheRange = |
296 | LLVMGetNextDbgRecord(DbgRecord: AddDbgRecordSecond); |
297 | assert(AddDbgRecordOverTheRange == NULL); |
298 | (void)AddDbgRecordOverTheRange; |
299 | LLVMDbgRecordRef AddDbgRecordFirstPrev = |
300 | LLVMGetPreviousDbgRecord(DbgRecord: AddDbgRecordSecond); |
301 | assert(AddDbgRecordFirstPrev != NULL); |
302 | assert(AddDbgRecordFirst == AddDbgRecordFirstPrev); |
303 | LLVMDbgRecordRef AddDbgRecordUnderTheRange = |
304 | LLVMGetPreviousDbgRecord(DbgRecord: AddDbgRecordFirstPrev); |
305 | assert(AddDbgRecordUnderTheRange == NULL); |
306 | (void)AddDbgRecordUnderTheRange; |
307 | |
308 | char *MStr = LLVMPrintModuleToString(M); |
309 | puts(s: MStr); |
310 | LLVMDisposeMessage(Message: MStr); |
311 | |
312 | LLVMDisposeBuilder(Builder); |
313 | LLVMDisposeDIBuilder(Builder: DIB); |
314 | LLVMDisposeModule(M); |
315 | |
316 | return 0; |
317 | } |
318 | |
319 | int llvm_get_di_tag(void) { |
320 | LLVMModuleRef M = LLVMModuleCreateWithName(ModuleID: "Mod" ); |
321 | LLVMContextRef Context = LLVMGetModuleContext(M); |
322 | |
323 | const char String[] = "foo" ; |
324 | LLVMMetadataRef StringMD = |
325 | LLVMMDStringInContext2(C: Context, Str: String, SLen: strlen(s: String)); |
326 | LLVMMetadataRef NodeMD = LLVMMDNodeInContext2(C: Context, MDs: &StringMD, Count: 1); |
327 | assert(LLVMGetDINodeTag(NodeMD) == 0); |
328 | (void)NodeMD; |
329 | |
330 | LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M); |
331 | const char Filename[] = "metadata.c" ; |
332 | const char Directory[] = "." ; |
333 | LLVMMetadataRef File = LLVMDIBuilderCreateFile( |
334 | Builder, Filename, FilenameLen: strlen(s: Filename), Directory, DirectoryLen: strlen(s: Directory)); |
335 | const char Name[] = "TestClass" ; |
336 | LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType( |
337 | Builder, Scope: File, Name, NameLen: strlen(s: Name), File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, |
338 | Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0); |
339 | assert(LLVMGetDINodeTag(Struct) == 0x13); |
340 | (void)Struct; |
341 | |
342 | LLVMDisposeDIBuilder(Builder); |
343 | LLVMDisposeModule(M); |
344 | |
345 | return 0; |
346 | } |
347 | |
348 | int llvm_di_type_get_name(void) { |
349 | LLVMModuleRef M = LLVMModuleCreateWithName(ModuleID: "Mod" ); |
350 | |
351 | LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M); |
352 | const char Filename[] = "metadata.c" ; |
353 | const char Directory[] = "." ; |
354 | LLVMMetadataRef File = LLVMDIBuilderCreateFile( |
355 | Builder, Filename, FilenameLen: strlen(s: Filename), Directory, DirectoryLen: strlen(s: Directory)); |
356 | const char Name[] = "TestClass" ; |
357 | LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType( |
358 | Builder, Scope: File, Name, NameLen: strlen(s: Name), File, LineNumber: 42, SizeInBits: 64, AlignInBits: 0, |
359 | Flags: LLVMDIFlagObjcClassComplete, NULL, NULL, NumElements: 0, RunTimeLang: 0, NULL, NULL, UniqueIdLen: 0); |
360 | |
361 | size_t Len; |
362 | const char *TypeName = LLVMDITypeGetName(DType: Struct, Length: &Len); |
363 | assert(Len == strlen(Name)); |
364 | assert(strncmp(TypeName, Name, Len) == 0); |
365 | (void)TypeName; |
366 | |
367 | LLVMDisposeDIBuilder(Builder); |
368 | LLVMDisposeModule(M); |
369 | |
370 | return 0; |
371 | } |
372 | |