diff --git a/llvm/include/llvm-c/DebugInfo.h b/llvm/include/llvm-c/DebugInfo.h --- a/llvm/include/llvm-c/DebugInfo.h +++ b/llvm/include/llvm-c/DebugInfo.h @@ -1149,6 +1149,12 @@ unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit, LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits); + +/** + * Get the dwarf::Tag of a DINode + */ +uint16_t LLVMGetDINodeTag(LLVMMetadataRef MD); + /** * Retrieves the \c DIVariable associated with this global variable expression. * \param GVE The global variable expression. diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp --- a/llvm/lib/IR/DebugInfo.cpp +++ b/llvm/lib/IR/DebugInfo.cpp @@ -1508,6 +1508,10 @@ return wrap(unwrap(Builder)->createArtificialType(unwrapDI(Type))); } +uint16_t LLVMGetDINodeTag(LLVMMetadataRef MD) { + return unwrapDI(MD)->getTag(); +} + const char *LLVMDITypeGetName(LLVMMetadataRef DType, size_t *Length) { StringRef Str = unwrap(DType)->getName(); *Length = Str.size(); diff --git a/llvm/test/Bindings/llvm-c/get-md-tag.ll b/llvm/test/Bindings/llvm-c/get-md-tag.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Bindings/llvm-c/get-md-tag.ll @@ -0,0 +1,2 @@ +; RUN: llvm-c-test --get-di-tag < /dev/null +; This used to trigger an assertion diff --git a/llvm/tools/llvm-c-test/debuginfo.c b/llvm/tools/llvm-c-test/debuginfo.c --- a/llvm/tools/llvm-c-test/debuginfo.c +++ b/llvm/tools/llvm-c-test/debuginfo.c @@ -12,10 +12,10 @@ \*===----------------------------------------------------------------------===*/ #include "llvm-c-test.h" -#include "llvm-c/Core.h" #include "llvm-c/DebugInfo.h" #include #include +#include static LLVMMetadataRef declare_objc_class(LLVMDIBuilderRef DIB, LLVMMetadataRef File) { @@ -201,3 +201,29 @@ return 0; } + +int llvm_get_di_tag(void) { + LLVMModuleRef m = LLVMModuleCreateWithName("Mod"); + LLVMContextRef context = LLVMGetModuleContext(m); + + LLVMMetadataRef metas[] = {LLVMMDStringInContext2(context, "foo", 3)}; + LLVMMetadataRef md = LLVMMDNodeInContext2(context, metas, 1); + uint16_t tag0 = LLVMGetDINodeTag(md); + + assert(tag0 == 0); + + const char *filename = "metadata.c"; + LLVMDIBuilderRef builder = LLVMCreateDIBuilder(m); + LLVMMetadataRef file = + LLVMDIBuilderCreateFile(builder, filename, strlen(filename), ".", 1); + LLVMMetadataRef decl = LLVMDIBuilderCreateStructType( + builder, file, "TestClass", 9, file, 42, 64, 0, + LLVMDIFlagObjcClassComplete, NULL, NULL, 0, 0, NULL, NULL, 0); + uint16_t tag1 = LLVMGetDINodeTag(decl); + + assert(tag1 == 0x13); + + LLVMDisposeModule(m); + + return 0; +} diff --git a/llvm/tools/llvm-c-test/llvm-c-test.h b/llvm/tools/llvm-c-test/llvm-c-test.h --- a/llvm/tools/llvm-c-test/llvm-c-test.h +++ b/llvm/tools/llvm-c-test/llvm-c-test.h @@ -37,6 +37,7 @@ // debuginfo.c int llvm_test_dibuilder(void); +int llvm_get_di_tag(void); // metadata.c int llvm_add_named_metadata_operand(void); diff --git a/llvm/tools/llvm-c-test/main.c b/llvm/tools/llvm-c-test/main.c --- a/llvm/tools/llvm-c-test/main.c +++ b/llvm/tools/llvm-c-test/main.c @@ -44,6 +44,8 @@ fprintf(stderr, " Read lines of triple, hex ascii machine code from stdin " "- print disassembly\n\n"); fprintf(stderr, " * --calc\n"); + fprintf(stderr, " * --get-di-tag\n"); + fprintf(stderr, " Run test for getting MDNode dwarf tag\n"); fprintf(stderr, " * --replace-md-operand\n"); fprintf(stderr, " Run test for replacing MDNode operands\n"); fprintf(stderr, " * --is-a-value-as-metadata\n"); @@ -96,6 +98,8 @@ return llvm_add_named_metadata_operand(); } else if (argc == 2 && !strcmp(argv[1], "--set-metadata")) { return llvm_set_metadata(); + } else if (argc == 2 && !strcmp(argv[1], "--get-di-tag")) { + return llvm_get_di_tag(); } else if (argc == 2 && !strcmp(argv[1], "--replace-md-operand")) { return llvm_replace_md_operand(); } else if (argc == 2 && !strcmp(argv[1], "--is-a-value-as-metadata")) {