506 lines · c
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 LLVMMetadataRef24declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) {25 LLVMMetadataRef Decl = LLVMDIBuilderCreateStructType(DIB, File, "TestClass", 9, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);26 LLVMMetadataRef SuperDecl = LLVMDIBuilderCreateStructType(DIB, File, "TestSuperClass", 14, File, 42, 64, 0, LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);27 LLVMDIBuilderCreateInheritance(DIB, Decl, SuperDecl, 0, 0, 0);28 LLVMMetadataRef TestProperty =29 LLVMDIBuilderCreateObjCProperty(DIB, "test", 4, File, 42, "getTest", 7, "setTest", 7, 0x20 /*copy*/ | 0x40 /*nonatomic*/, SuperDecl);30 LLVMDIBuilderCreateObjCIVar(DIB, "_test", 5, File, 42, 64, 0, 64, LLVMDIFlagPublic, SuperDecl, TestProperty);31 return Decl;32}33 34int llvm_test_dibuilder(void) {35 const char *Filename = "debuginfo.c";36 LLVMModuleRef M = LLVMModuleCreateWithName(Filename);37 38 LLVMSetIsNewDbgInfoFormat(M, true);39 assert(LLVMIsNewDbgInfoFormat(M));40 41 LLVMDIBuilderRef DIB = LLVMCreateDIBuilder(M);42 43 LLVMMetadataRef File = LLVMDIBuilderCreateFile(DIB, Filename,44 strlen(Filename), ".", 1);45 46 LLVMMetadataRef FileCS = LLVMDIBuilderCreateFileWithChecksum(47 DIB, Filename, strlen(Filename), ".", 1, CSK_MD5, "1234", 4, "source", 6);48 49 LLVMMetadataRef CompileUnit = LLVMDIBuilderCreateCompileUnit(50 DIB, LLVMDWARFSourceLanguageC, File, "llvm-c-test", 11, 0, NULL, 0, 0,51 NULL, 0, LLVMDWARFEmissionFull, 0, 0, 0, "/", 1, "", 0);52 53 LLVMMetadataRef Module =54 LLVMDIBuilderCreateModule(DIB, CompileUnit,55 "llvm-c-test", 11,56 "", 0,57 "/test/include/llvm-c-test.h", 27,58 "", 0);59 60 LLVMMetadataRef OtherModule =61 LLVMDIBuilderCreateModule(DIB, CompileUnit,62 "llvm-c-test-import", 18,63 "", 0,64 "/test/include/llvm-c-test-import.h", 34,65 "", 0);66 LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule(67 DIB, Module, OtherModule, FileCS, 42, NULL, 0);68 LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule, File,69 42, NULL, 0);70 71 LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);72 LLVMMetadataRef GlobalClassValueExpr =73 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);74 LLVMDIBuilderCreateGlobalVariableExpression(75 DIB, Module, "globalClass", 11, "", 0, File, 1, ClassTy, true,76 GlobalClassValueExpr, NULL, 0);77 78 LLVMMetadataRef Int64Ty =79 LLVMDIBuilderCreateBasicType(DIB, "Int64", 5, 64, 0, LLVMDIFlagZero);80 LLVMMetadataRef Int64TypeDef =81 LLVMDIBuilderCreateTypedef(DIB, Int64Ty, "int64_t", 7, File, 42, File, 0);82 83 LLVMMetadataRef GlobalVarValueExpr =84 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);85 LLVMDIBuilderCreateGlobalVariableExpression(86 DIB, Module, "global", 6, "", 0, File, 1, Int64TypeDef, true,87 GlobalVarValueExpr, NULL, 0);88 89 LLVMMetadataRef NameSpace =90 LLVMDIBuilderCreateNameSpace(DIB, Module, "NameSpace", 9, false);91 92 LLVMMetadataRef StructDbgElts[] = {Int64Ty, Int64Ty, Int64Ty};93 LLVMMetadataRef StructDbgTy =94 LLVMDIBuilderCreateStructType(DIB, NameSpace, "MyStruct",95 8, File, 0, 192, 0, 0, NULL, StructDbgElts, 3,96 LLVMDWARFSourceLanguageC, NULL, "MyStruct", 8);97 98 LLVMMetadataRef StructDbgPtrTy =99 LLVMDIBuilderCreatePointerType(DIB, StructDbgTy, 192, 0, 0, "", 0);100 101 LLVMAddNamedMetadataOperand(M, "FooType",102 LLVMMetadataAsValue(LLVMGetModuleContext(M), StructDbgPtrTy));103 104 105 LLVMTypeRef FooParamTys[] = {106 LLVMInt64Type(),107 LLVMInt64Type(),108 LLVMVectorType(LLVMInt64Type(), 10),109 };110 LLVMTypeRef FooFuncTy = LLVMFunctionType(LLVMInt64Type(), FooParamTys, 3, 0);111 LLVMValueRef FooFunction = LLVMAddFunction(M, "foo", FooFuncTy);112 LLVMBasicBlockRef FooEntryBlock = LLVMAppendBasicBlock(FooFunction, "entry");113 114 LLVMMetadataRef Subscripts[] = {115 LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),116 };117 LLVMMetadataRef VectorTy =118 LLVMDIBuilderCreateVectorType(DIB, 64 * 10, 0,119 Int64Ty, Subscripts, 1);120 121 122 LLVMMetadataRef ParamTypes[] = {Int64Ty, Int64Ty, VectorTy};123 LLVMMetadataRef FunctionTy =124 LLVMDIBuilderCreateSubroutineType(DIB, File, ParamTypes, 3, 0);125 126 LLVMMetadataRef ReplaceableFunctionMetadata =127 LLVMDIBuilderCreateReplaceableCompositeType(DIB, 0x15, "foo", 3,128 File, File, 42,129 0, 0, 0,130 LLVMDIFlagFwdDecl,131 "", 0);132 133 LLVMMetadataRef FooParamLocation =134 LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 42, 0,135 ReplaceableFunctionMetadata, NULL);136 LLVMMetadataRef FunctionMetadata = LLVMDIBuilderCreateFunction(137 DIB, File, "foo", 3, "foo", 3, File, 42, NULL, true, true, 42, 0, false);138 LLVMMetadataReplaceAllUsesWith(ReplaceableFunctionMetadata, FunctionMetadata);139 140 LLVMDISubprogramReplaceType(FunctionMetadata, FunctionTy);141 142 LLVMMetadataRef FooParamExpression =143 LLVMDIBuilderCreateExpression(DIB, NULL, 0);144 LLVMMetadataRef FooParamVar1 =145 LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "a", 1, 1, File,146 42, Int64Ty, true, 0);147 148 LLVMDIBuilderInsertDeclareRecordAtEnd(149 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar1,150 FooParamExpression, FooParamLocation, FooEntryBlock);151 152 LLVMMetadataRef FooParamVar2 =153 LLVMDIBuilderCreateParameterVariable(DIB, FunctionMetadata, "b", 1, 2, File,154 42, Int64Ty, true, 0);155 156 LLVMDIBuilderInsertDeclareRecordAtEnd(157 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar2,158 FooParamExpression, FooParamLocation, FooEntryBlock);159 160 LLVMMetadataRef FooParamVar3 = LLVMDIBuilderCreateParameterVariable(161 DIB, FunctionMetadata, "c", 1, 3, File, 42, VectorTy, true, 0);162 163 LLVMDIBuilderInsertDeclareRecordAtEnd(164 DIB, LLVMConstInt(LLVMInt64Type(), 0, false), FooParamVar3,165 FooParamExpression, FooParamLocation, FooEntryBlock);166 167 LLVMSetSubprogram(FooFunction, FunctionMetadata);168 169 LLVMMetadataRef FooLabel1 = LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,170 "label1", 6, File, 42, false);171 LLVMDIBuilderInsertLabelAtEnd(DIB, FooLabel1, FooParamLocation,172 FooEntryBlock);173 174 LLVMMetadataRef FooLexicalBlock =175 LLVMDIBuilderCreateLexicalBlock(DIB, FunctionMetadata, File, 42, 0);176 177 LLVMBasicBlockRef FooVarBlock = LLVMAppendBasicBlock(FooFunction, "vars");178 LLVMMetadataRef FooVarsLocation =179 LLVMDIBuilderCreateDebugLocation(LLVMGetGlobalContext(), 43, 0,180 FunctionMetadata, NULL);181 LLVMMetadataRef FooVar1 =182 LLVMDIBuilderCreateAutoVariable(DIB, FooLexicalBlock, "d", 1, File,183 43, Int64Ty, true, 0, 0);184 LLVMValueRef FooVal1 = LLVMConstInt(LLVMInt64Type(), 0, false);185 LLVMMetadataRef FooVarValueExpr1 =186 LLVMDIBuilderCreateConstantValueExpression(DIB, 0);187 188 LLVMDIBuilderInsertDbgValueRecordAtEnd(189 DIB, FooVal1, FooVar1, FooVarValueExpr1, FooVarsLocation, FooVarBlock);190 191 LLVMMetadataRef FooVar2 = LLVMDIBuilderCreateAutoVariable(192 DIB, FooLexicalBlock, "e", 1, File, 44, Int64Ty, true, 0, 0);193 LLVMValueRef FooVal2 = LLVMConstInt(LLVMInt64Type(), 1, false);194 LLVMMetadataRef FooVarValueExpr2 =195 LLVMDIBuilderCreateConstantValueExpression(DIB, 1);196 197 LLVMDIBuilderInsertDbgValueRecordAtEnd(198 DIB, FooVal2, FooVar2, FooVarValueExpr2, FooVarsLocation, FooVarBlock);199 200 LLVMMetadataRef MacroFile =201 LLVMDIBuilderCreateTempMacroFile(DIB, NULL, 0, File);202 LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,203 "SIMPLE_DEFINE", 13, NULL, 0);204 LLVMDIBuilderCreateMacro(DIB, MacroFile, 0, LLVMDWARFMacinfoRecordTypeDefine,205 "VALUE_DEFINE", 12, "1", 1);206 207 LLVMMetadataRef EnumeratorTestA =208 LLVMDIBuilderCreateEnumerator(DIB, "Test_A", strlen("Test_A"), 0, true);209 LLVMMetadataRef EnumeratorTestB =210 LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_B"), 1, true);211 LLVMMetadataRef EnumeratorTestC =212 LLVMDIBuilderCreateEnumerator(DIB, "Test_B", strlen("Test_C"), 2, true);213 LLVMMetadataRef EnumeratorsTest[] = {EnumeratorTestA, EnumeratorTestB,214 EnumeratorTestC};215 LLVMMetadataRef EnumTest = LLVMDIBuilderCreateEnumerationType(216 DIB, NameSpace, "EnumTest", strlen("EnumTest"), File, 0, 64, 0,217 EnumeratorsTest, 3, Int64Ty);218 LLVMAddNamedMetadataOperand(219 M, "EnumTest", LLVMMetadataAsValue(LLVMGetModuleContext(M), EnumTest));220 221 LLVMMetadataRef UInt128Ty = LLVMDIBuilderCreateBasicType(222 DIB, "UInt128", strlen("UInt128"), 128, 0, LLVMDIFlagZero);223 const uint64_t WordsTestD[] = {0x098a224000000000ull, 0x4b3b4ca85a86c47aull};224 const uint64_t WordsTestE[] = {0xFFFFFFFFFFFFFFFFull, 0xFFFFFFFFFFFFFFFFull};225 226 LLVMMetadataRef LargeEnumeratorTestD =227 LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision(228 DIB, "Test_D", strlen("Test_D"), 128, WordsTestD, false);229 LLVMMetadataRef LargeEnumeratorTestE =230 LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision(231 DIB, "Test_E", strlen("Test_E"), 128, WordsTestE, false);232 LLVMMetadataRef LargeEnumeratorsTest[] = {LargeEnumeratorTestD,233 LargeEnumeratorTestE};234 LLVMMetadataRef LargeEnumTest = LLVMDIBuilderCreateEnumerationType(235 DIB, NameSpace, "LargeEnumTest", strlen("LargeEnumTest"), File, 0, 128, 0,236 LargeEnumeratorsTest, 2, UInt128Ty);237 LLVMAddNamedMetadataOperand(238 M, "LargeEnumTest",239 LLVMMetadataAsValue(LLVMGetModuleContext(M), LargeEnumTest));240 241 LLVMValueRef FooVal3 = LLVMConstInt(LLVMInt64Type(), 8, false);242 LLVMValueRef FooVal4 = LLVMConstInt(LLVMInt64Type(), 4, false);243 LLVMMetadataRef lo = LLVMValueAsMetadata(FooVal1);244 LLVMMetadataRef hi = LLVMValueAsMetadata(FooVal2);245 LLVMMetadataRef strd = LLVMValueAsMetadata(FooVal3);246 LLVMMetadataRef bias = LLVMValueAsMetadata(FooVal4);247 LLVMMetadataRef SubrangeMetadataTy = LLVMDIBuilderCreateSubrangeType(248 DIB, File, "foo", 3, 42, File, 64, 0, 0, Int64Ty, lo, hi, strd, bias);249 LLVMAddNamedMetadataOperand(250 M, "SubrangeType",251 LLVMMetadataAsValue(LLVMGetModuleContext(M), SubrangeMetadataTy));252 253 LLVMMetadataRef SetMetadataTy1 = LLVMDIBuilderCreateSetType(254 DIB, File, "enumset", 7, File, 42, 64, 0, EnumTest);255 LLVMMetadataRef SetMetadataTy2 = LLVMDIBuilderCreateSetType(256 DIB, File, "subrangeset", 11, File, 42, 64, 0, SubrangeMetadataTy);257 LLVMAddNamedMetadataOperand(258 M, "SetType1",259 LLVMMetadataAsValue(LLVMGetModuleContext(M), SetMetadataTy1));260 LLVMAddNamedMetadataOperand(261 M, "SetType2",262 LLVMMetadataAsValue(LLVMGetModuleContext(M), SetMetadataTy2));263 264 LLVMMetadataRef DynSubscripts[] = {265 LLVMDIBuilderGetOrCreateSubrange(DIB, 0, 10),266 };267 LLVMMetadataRef Loc = LLVMDIBuilderCreateExpression(DIB, NULL, 0);268 LLVMMetadataRef Rank = LLVMDIBuilderCreateExpression(DIB, NULL, 0);269 LLVMMetadataRef DynamicArrayMetadataTy = LLVMDIBuilderCreateDynamicArrayType(270 DIB, File, "foo", 3, 42, File, 64 * 10, 0, Int64Ty, DynSubscripts, 1, Loc,271 FooVar1, NULL, Rank, NULL);272 LLVMAddNamedMetadataOperand(273 M, "DynType",274 LLVMMetadataAsValue(LLVMGetModuleContext(M), DynamicArrayMetadataTy));275 276 LLVMMetadataRef StructPTy = LLVMDIBuilderCreateForwardDecl(277 DIB, 2 /*DW_TAG_class_type*/, "Class1", 5, NameSpace, File, 0, 0, 192, 0,278 "FooClass", 8);279 280 LLVMMetadataRef Int32Ty =281 LLVMDIBuilderCreateBasicType(DIB, "Int32", 5, 32, 0, LLVMDIFlagZero);282 LLVMMetadataRef StructElts[] = {Int64Ty, Int64Ty, Int32Ty};283 LLVMMetadataRef ClassArr = LLVMDIBuilderGetOrCreateArray(DIB, StructElts, 3);284 LLVMReplaceArrays(DIB, &StructPTy, &ClassArr, 1);285 LLVMAddNamedMetadataOperand(286 M, "ClassType", LLVMMetadataAsValue(LLVMGetModuleContext(M), StructPTy));287 288 // Using the new debug format, debug records get attached to instructions.289 // Insert a `br` and `ret` now to absorb the debug records which are290 // currently "trailing", meaning that they're associated with a block291 // but no particular instruction, which is only valid as a transient state.292 LLVMContextRef Ctx = LLVMGetModuleContext(M);293 LLVMBuilderRef Builder = LLVMCreateBuilderInContext(Ctx);294 LLVMPositionBuilderAtEnd(Builder, FooEntryBlock);295 // Build `br label %vars` in entry.296 LLVMBuildBr(Builder, FooVarBlock);297 298 // Build another br for the sake of testing labels.299 LLVMMetadataRef FooLabel2 = LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,300 "label2", 6, File, 42, false);301 LLVMDIBuilderInsertLabelBefore(DIB, FooLabel2, FooParamLocation,302 LLVMBuildBr(Builder, FooVarBlock));303 // label3 will be emitted, but label4 won't be emitted304 // because label3 is AlwaysPreserve and label4 is not.305 LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,306 "label3", 6, File, 42, true);307 LLVMDIBuilderCreateLabel(DIB, FunctionMetadata,308 "label4", 6, File, 42, false);309 LLVMDIBuilderFinalize(DIB);310 311 // Build `ret i64 0` in vars.312 LLVMPositionBuilderAtEnd(Builder, FooVarBlock);313 LLVMTypeRef I64 = LLVMInt64TypeInContext(Ctx);314 LLVMValueRef Zero = LLVMConstInt(I64, 0, false);315 LLVMValueRef Ret = LLVMBuildRet(Builder, Zero);316 317 // Insert a `phi` before the `ret`. In the new debug info mode we need to318 // be careful to insert before debug records too, else the debug records319 // will come before the `phi` (and be absorbed onto it) which is an invalid320 // state.321 LLVMValueRef InsertPos = LLVMGetFirstInstruction(FooVarBlock);322 LLVMPositionBuilderBeforeInstrAndDbgRecords(Builder, InsertPos);323 LLVMValueRef Phi1 = LLVMBuildPhi(Builder, I64, "p1");324 LLVMAddIncoming(Phi1, &Zero, &FooEntryBlock, 1);325 326 // Do the same again using the other position-setting function.327 LLVMPositionBuilderBeforeDbgRecords(Builder, FooVarBlock, InsertPos);328 LLVMValueRef Phi2 = LLVMBuildPhi(Builder, I64, "p2");329 LLVMAddIncoming(Phi2, &Zero, &FooEntryBlock, 1);330 331 // Test that LLVMGetFirstDbgRecord and LLVMGetLastDbgRecord return NULL for332 // instructions without debug info.333 LLVMDbgRecordRef Phi1FirstDbgRecord = LLVMGetFirstDbgRecord(Phi1);334 (void)Phi1FirstDbgRecord;335 assert(Phi1FirstDbgRecord == NULL);336 LLVMDbgRecordRef Phi1LastDbgRecord = LLVMGetLastDbgRecord(Phi1);337 (void)Phi1LastDbgRecord;338 assert(Phi1LastDbgRecord == NULL);339 340 // Insert a non-phi before the `ret` but not before the debug records to341 // test that works as expected.342 LLVMPositionBuilder(Builder, FooVarBlock, Ret);343 LLVMValueRef Add = LLVMBuildAdd(Builder, Phi1, Phi2, "a");344 345 // Iterate over debug records in the add instruction. There should be two.346 LLVMDbgRecordRef AddDbgRecordFirst = LLVMGetFirstDbgRecord(Add);347 assert(AddDbgRecordFirst != NULL);348 LLVMDbgRecordRef AddDbgRecordSecond = LLVMGetNextDbgRecord(AddDbgRecordFirst);349 assert(AddDbgRecordSecond != NULL);350 LLVMDbgRecordRef AddDbgRecordLast = LLVMGetLastDbgRecord(Add);351 assert(AddDbgRecordLast != NULL);352 (void)AddDbgRecordLast;353 assert(AddDbgRecordSecond == AddDbgRecordLast);354 LLVMDbgRecordRef AddDbgRecordOverTheRange =355 LLVMGetNextDbgRecord(AddDbgRecordSecond);356 assert(AddDbgRecordOverTheRange == NULL);357 (void)AddDbgRecordOverTheRange;358 LLVMDbgRecordRef AddDbgRecordFirstPrev =359 LLVMGetPreviousDbgRecord(AddDbgRecordSecond);360 assert(AddDbgRecordFirstPrev != NULL);361 assert(AddDbgRecordFirst == AddDbgRecordFirstPrev);362 LLVMDbgRecordRef AddDbgRecordUnderTheRange =363 LLVMGetPreviousDbgRecord(AddDbgRecordFirstPrev);364 assert(AddDbgRecordUnderTheRange == NULL);365 (void)AddDbgRecordUnderTheRange;366 367 // Test that we can read the first debug record.368 LLVMMetadataRef AddDbgRecordFirstDebugLoc =369 LLVMDbgRecordGetDebugLoc(AddDbgRecordFirst);370 (void)AddDbgRecordFirstDebugLoc;371 assert(LLVMDILocationGetLine(AddDbgRecordFirstDebugLoc) == 43);372 assert(LLVMDbgRecordGetKind(AddDbgRecordFirst) == LLVMDbgRecordValue);373 LLVMValueRef AddDbgRecordFirstValue =374 LLVMDbgVariableRecordGetValue(AddDbgRecordFirst, 0);375 (void)AddDbgRecordFirstValue;376 assert(LLVMGetValueKind(AddDbgRecordFirstValue) == LLVMConstantIntValueKind);377 assert(LLVMConstIntGetZExtValue(AddDbgRecordFirstValue) == 0);378 LLVMMetadataRef AddDbgRecordFirstVariable =379 LLVMDbgVariableRecordGetVariable(AddDbgRecordFirst);380 (void)AddDbgRecordFirstVariable;381 assert(LLVMGetMetadataKind(AddDbgRecordFirstVariable) ==382 LLVMDILocalVariableMetadataKind);383 // TODO: For now, there is no way to get the name.384 LLVMMetadataRef AddDbgRecordFirstVariableScope =385 LLVMDIVariableGetScope(AddDbgRecordFirstVariable);386 (void)AddDbgRecordFirstVariableScope;387 assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableScope) ==388 LLVMDILexicalBlockMetadataKind);389 LLVMMetadataRef AddDbgRecordFirstVariableFile =390 LLVMDIScopeGetFile(AddDbgRecordFirstVariableScope);391 (void)AddDbgRecordFirstVariableFile;392 assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableFile) ==393 LLVMDIFileMetadataKind);394 unsigned FileLen = 0;395 assert(strcmp(LLVMDIFileGetFilename(AddDbgRecordFirstVariableFile, &FileLen),396 "debuginfo.c") == 0);397 (void)FileLen;398 LLVMMetadataRef AddDbgRecordFirstExpr =399 LLVMDbgVariableRecordGetExpression(AddDbgRecordFirst);400 assert(LLVMGetMetadataKind(AddDbgRecordFirstExpr) ==401 LLVMDIExpressionMetadataKind);402 (void)AddDbgRecordFirstExpr;403 404 char *MStr = LLVMPrintModuleToString(M);405 puts(MStr);406 LLVMDisposeMessage(MStr);407 408 LLVMDisposeBuilder(Builder);409 LLVMDisposeDIBuilder(DIB);410 LLVMDisposeModule(M);411 412 return 0;413}414 415int llvm_get_di_tag(void) {416 LLVMModuleRef M = LLVMModuleCreateWithName("Mod");417 LLVMContextRef Context = LLVMGetModuleContext(M);418 419 const char String[] = "foo";420 LLVMMetadataRef StringMD =421 LLVMMDStringInContext2(Context, String, strlen(String));422 LLVMMetadataRef NodeMD = LLVMMDNodeInContext2(Context, &StringMD, 1);423 assert(LLVMGetDINodeTag(NodeMD) == 0);424 (void)NodeMD;425 426 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);427 const char Filename[] = "metadata.c";428 const char Directory[] = ".";429 LLVMMetadataRef File = LLVMDIBuilderCreateFile(430 Builder, Filename, strlen(Filename), Directory, strlen(Directory));431 const char Name[] = "TestClass";432 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(433 Builder, File, Name, strlen(Name), File, 42, 64, 0,434 LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);435 assert(LLVMGetDINodeTag(Struct) == 0x13);436 (void)Struct;437 438 LLVMDisposeDIBuilder(Builder);439 LLVMDisposeModule(M);440 441 return 0;442}443 444int llvm_di_type_get_name(void) {445 LLVMModuleRef M = LLVMModuleCreateWithName("Mod");446 447 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);448 const char Filename[] = "metadata.c";449 const char Directory[] = ".";450 LLVMMetadataRef File = LLVMDIBuilderCreateFile(451 Builder, Filename, strlen(Filename), Directory, strlen(Directory));452 const char Name[] = "TestClass";453 LLVMMetadataRef Struct = LLVMDIBuilderCreateStructType(454 Builder, File, Name, strlen(Name), File, 42, 64, 0,455 LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0);456 457 size_t Len;458 const char *TypeName = LLVMDITypeGetName(Struct, &Len);459 assert(Len == strlen(Name));460 assert(strncmp(TypeName, Name, Len) == 0);461 (void)TypeName;462 463 LLVMDisposeDIBuilder(Builder);464 LLVMDisposeModule(M);465 466 return 0;467}468 469int llvm_add_globaldebuginfo(void) {470 const char *Filename = "debuginfo.c";471 LLVMModuleRef M = LLVMModuleCreateWithName(Filename);472 LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);473 LLVMMetadataRef File =474 LLVMDIBuilderCreateFile(Builder, Filename, strlen(Filename), ".", 1);475 476 LLVMMetadataRef GlobalVarValueExpr =477 LLVMDIBuilderCreateConstantValueExpression(Builder, 0);478 LLVMMetadataRef Int64Ty =479 LLVMDIBuilderCreateBasicType(Builder, "Int64", 5, 64, 0, LLVMDIFlagZero);480 LLVMMetadataRef Int64TypeDef = LLVMDIBuilderCreateTypedef(481 Builder, Int64Ty, "int64_t", 7, File, 42, File, 0);482 483 LLVMMetadataRef GVE = LLVMDIBuilderCreateGlobalVariableExpression(484 Builder, File, "global", 6, "", 0, File, 1, Int64TypeDef, true,485 GlobalVarValueExpr, NULL, 0);486 487 LLVMTypeRef RecType =488 LLVMStructCreateNamed(LLVMGetModuleContext(M), "struct");489 LLVMValueRef Global = LLVMAddGlobal(M, RecType, "global");490 491 LLVMGlobalAddDebugInfo(Global, GVE);492 // use AddMetadata to add twice493 int kindId = LLVMGetMDKindID("dbg", 3);494 LLVMGlobalAddMetadata(Global, kindId, GVE);495 size_t numEntries;496 LLVMValueMetadataEntry *ME = LLVMGlobalCopyAllMetadata(Global, &numEntries);497 assert(ME != NULL);498 assert(numEntries == 2);499 500 LLVMDisposeValueMetadataEntries(ME);501 LLVMDisposeDIBuilder(Builder);502 LLVMDisposeModule(M);503 504 return 0;505}506