Add LLVMGlobalAddDebugInfo to Core.cpp (#148747)

This change allows globals to have multiple metadata attached. The
GlobalSetMetadata function only allows only one and is clobbered if
more metadata is attempted to be added. The addDebugInfo
function calls addMetadata. This is needed because some languages have
global structs containing lots of compiler-generated globals.
This commit is contained in:
peter mckinna 2025-08-14 22:59:39 +10:00 committed by GitHub
parent 1633e0ba8b
commit 002362bbd8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 68 additions and 0 deletions

View File

@ -2694,6 +2694,14 @@ LLVM_C_ABI void LLVMSetAlignment(LLVMValueRef V, unsigned Bytes);
LLVM_C_ABI void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind, LLVM_C_ABI void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind,
LLVMMetadataRef MD); LLVMMetadataRef MD);
/**
* Adds a metadata attachment.
*
* @see llvm::GlobalObject::addMetadata()
*/
LLVM_C_ABI void LLVMGlobalAddMetadata(LLVMValueRef Global, unsigned Kind,
LLVMMetadataRef MD);
/** /**
* Erases a metadata attachment of the given kind if it exists. * Erases a metadata attachment of the given kind if it exists.
* *
@ -2708,6 +2716,14 @@ LLVM_C_ABI void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind);
*/ */
LLVM_C_ABI void LLVMGlobalClearMetadata(LLVMValueRef Global); LLVM_C_ABI void LLVMGlobalClearMetadata(LLVMValueRef Global);
/**
* Add debuginfo metadata to this global.
*
* @see llvm::GlobalVariable::addDebugInfo()
*/
LLVM_C_ABI void LLVMGlobalAddDebugInfo(LLVMValueRef Global,
LLVMMetadataRef GVE);
/** /**
* Retrieves an array of metadata entries representing the metadata attached to * Retrieves an array of metadata entries representing the metadata attached to
* this value. The caller is responsible for freeing this array by calling * this value. The caller is responsible for freeing this array by calling

View File

@ -2186,6 +2186,11 @@ void LLVMGlobalSetMetadata(LLVMValueRef Global, unsigned Kind,
unwrap<GlobalObject>(Global)->setMetadata(Kind, unwrap<MDNode>(MD)); unwrap<GlobalObject>(Global)->setMetadata(Kind, unwrap<MDNode>(MD));
} }
void LLVMGlobalAddMetadata(LLVMValueRef Global, unsigned Kind,
LLVMMetadataRef MD) {
unwrap<GlobalObject>(Global)->addMetadata(Kind, *unwrap<MDNode>(MD));
}
void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind) { void LLVMGlobalEraseMetadata(LLVMValueRef Global, unsigned Kind) {
unwrap<GlobalObject>(Global)->eraseMetadata(Kind); unwrap<GlobalObject>(Global)->eraseMetadata(Kind);
} }
@ -2194,6 +2199,11 @@ void LLVMGlobalClearMetadata(LLVMValueRef Global) {
unwrap<GlobalObject>(Global)->clearMetadata(); unwrap<GlobalObject>(Global)->clearMetadata();
} }
void LLVMGlobalAddDebugInfo(LLVMValueRef Global, LLVMMetadataRef GVE) {
unwrap<GlobalVariable>(Global)->addDebugInfo(
unwrap<DIGlobalVariableExpression>(GVE));
}
/*--.. Operations on global variables ......................................--*/ /*--.. Operations on global variables ......................................--*/
LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) { LLVMValueRef LLVMAddGlobal(LLVMModuleRef M, LLVMTypeRef Ty, const char *Name) {

View File

@ -0,0 +1,2 @@
; RUN: llvm-c-test --add-globaldebuginfo < /dev/null
; This used to trigger an assertion

View File

@ -416,3 +416,40 @@ int llvm_di_type_get_name(void) {
return 0; return 0;
} }
int llvm_add_globaldebuginfo(void) {
const char *Filename = "debuginfo.c";
LLVMModuleRef M = LLVMModuleCreateWithName(Filename);
LLVMDIBuilderRef Builder = LLVMCreateDIBuilder(M);
LLVMMetadataRef File =
LLVMDIBuilderCreateFile(Builder, Filename, strlen(Filename), ".", 1);
LLVMMetadataRef GlobalVarValueExpr =
LLVMDIBuilderCreateConstantValueExpression(Builder, 0);
LLVMMetadataRef Int64Ty =
LLVMDIBuilderCreateBasicType(Builder, "Int64", 5, 64, 0, LLVMDIFlagZero);
LLVMMetadataRef Int64TypeDef = LLVMDIBuilderCreateTypedef(
Builder, Int64Ty, "int64_t", 7, File, 42, File, 0);
LLVMMetadataRef GVE = LLVMDIBuilderCreateGlobalVariableExpression(
Builder, File, "global", 6, "", 0, File, 1, Int64TypeDef, true,
GlobalVarValueExpr, NULL, 0);
LLVMTypeRef RecType =
LLVMStructCreateNamed(LLVMGetModuleContext(M), "struct");
LLVMValueRef Global = LLVMAddGlobal(M, RecType, "global");
LLVMGlobalAddDebugInfo(Global, GVE);
// use AddMetadata to add twice
int kindId = LLVMGetMDKindID("dbg", 3);
LLVMGlobalAddMetadata(Global, kindId, GVE);
size_t numEntries;
LLVMValueMetadataEntry *ME = LLVMGlobalCopyAllMetadata(Global, &numEntries);
assert(ME != NULL);
assert(numEntries == 2);
LLVMDisposeDIBuilder(Builder);
LLVMDisposeModule(M);
return 0;
}

View File

@ -45,6 +45,7 @@ int llvm_add_named_metadata_operand(void);
int llvm_set_metadata(void); int llvm_set_metadata(void);
int llvm_replace_md_operand(void); int llvm_replace_md_operand(void);
int llvm_is_a_value_as_metadata(void); int llvm_is_a_value_as_metadata(void);
int llvm_add_globaldebuginfo(void);
// object.c // object.c
int llvm_object_list_sections(void); int llvm_object_list_sections(void);

View File

@ -101,6 +101,8 @@ int main(int argc, char **argv) {
return llvm_replace_md_operand(); return llvm_replace_md_operand();
} else if (argc == 2 && !strcmp(argv[1], "--is-a-value-as-metadata")) { } else if (argc == 2 && !strcmp(argv[1], "--is-a-value-as-metadata")) {
return llvm_is_a_value_as_metadata(); return llvm_is_a_value_as_metadata();
} else if (argc == 2 && !strcmp(argv[1], "--add-globaldebuginfo")) {
return llvm_add_globaldebuginfo();
} else if (argc == 2 && !strcmp(argv[1], "--test-function-attributes")) { } else if (argc == 2 && !strcmp(argv[1], "--test-function-attributes")) {
return llvm_test_function_attributes(); return llvm_test_function_attributes();
} else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) { } else if (argc == 2 && !strcmp(argv[1], "--test-callsite-attributes")) {