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
23static LLVMMetadataRef
24declare_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
34int 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
319int 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
348int 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