brintos

brintos / llvm-project-archived public Read only

0
0
Text · 21.7 KiB · 677722f Raw
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