[llvm-c] Add bindings for DbgRecord (#166383)

In the LLVM-C library, there is currently no way to get information about a
DbgRecord - which is the new way to attach debug information to llvm
instructions.

We can only iterate on debug records with LLVMGetFirstDbgRecord/
LLVMGetLastDbgRecord/LLVMGetNextDbgRecord, but there is no way to read
information.

This PR adds utility functions to read DbgRecord information.
This commit is contained in:
Maxime Arthaud 2025-11-12 15:36:56 +01:00 committed by GitHub
parent f6cf44ac2d
commit 448146d647
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 106 additions and 0 deletions

View File

@ -531,6 +531,13 @@ enum {
*/
typedef unsigned LLVMGEPNoWrapFlags;
typedef enum {
LLVMDbgRecordLabel,
LLVMDbgRecordDeclare,
LLVMDbgRecordValue,
LLVMDbgRecordAssign,
} LLVMDbgRecordKind;
/**
* @}
*/
@ -3896,6 +3903,37 @@ LLVM_C_ABI LLVMDbgRecordRef LLVMGetNextDbgRecord(LLVMDbgRecordRef DbgRecord);
LLVM_C_ABI LLVMDbgRecordRef
LLVMGetPreviousDbgRecord(LLVMDbgRecordRef DbgRecord);
/**
* Get the debug location attached to the debug record.
*
* @see llvm::DbgRecord::getDebugLoc()
*/
LLVMMetadataRef LLVMDbgRecordGetDebugLoc(LLVMDbgRecordRef Rec);
LLVMDbgRecordKind LLVMDbgRecordGetKind(LLVMDbgRecordRef Rec);
/**
* Get the value of the DbgVariableRecord.
*
* @see llvm::DbgVariableRecord::getValue()
*/
LLVMValueRef LLVMDbgVariableRecordGetValue(LLVMDbgRecordRef Rec,
unsigned OpIdx);
/**
* Get the debug info variable of the DbgVariableRecord.
*
* @see llvm::DbgVariableRecord::getVariable()
*/
LLVMMetadataRef LLVMDbgVariableRecordGetVariable(LLVMDbgRecordRef Rec);
/**
* Get the debug info expression of the DbgVariableRecord.
*
* @see llvm::DbgVariableRecord::getExpression()
*/
LLVMMetadataRef LLVMDbgVariableRecordGetExpression(LLVMDbgRecordRef Rec);
/**
* @defgroup LLVMCCoreValueInstructionCall Call Sites and Invocations
*

View File

@ -3036,6 +3036,37 @@ LLVMDbgRecordRef LLVMGetPreviousDbgRecord(LLVMDbgRecordRef Rec) {
return wrap(&*--I);
}
LLVMMetadataRef LLVMDbgRecordGetDebugLoc(LLVMDbgRecordRef Rec) {
return wrap(unwrap<DbgRecord>(Rec)->getDebugLoc().getAsMDNode());
}
LLVMDbgRecordKind LLVMDbgRecordGetKind(LLVMDbgRecordRef Rec) {
DbgRecord *Record = unwrap<DbgRecord>(Rec);
if (isa<DbgLabelRecord>(Record))
return LLVMDbgRecordLabel;
DbgVariableRecord *VariableRecord = dyn_cast<DbgVariableRecord>(Record);
assert(VariableRecord && "unexpected record");
if (VariableRecord->isDbgDeclare())
return LLVMDbgRecordDeclare;
if (VariableRecord->isDbgValue())
return LLVMDbgRecordValue;
assert(VariableRecord->isDbgAssign() && "unexpected record");
return LLVMDbgRecordAssign;
}
LLVMValueRef LLVMDbgVariableRecordGetValue(LLVMDbgRecordRef Rec,
unsigned OpIdx) {
return wrap(unwrap<DbgVariableRecord>(Rec)->getValue(OpIdx));
}
LLVMMetadataRef LLVMDbgVariableRecordGetVariable(LLVMDbgRecordRef Rec) {
return wrap(unwrap<DbgVariableRecord>(Rec)->getRawVariable());
}
LLVMMetadataRef LLVMDbgVariableRecordGetExpression(LLVMDbgRecordRef Rec) {
return wrap(unwrap<DbgVariableRecord>(Rec)->getRawExpression());
}
unsigned LLVMGetNumArgOperands(LLVMValueRef Instr) {
if (FuncletPadInst *FPI = dyn_cast<FuncletPadInst>(unwrap(Instr))) {
return FPI->arg_size();

View File

@ -364,6 +364,43 @@ int llvm_test_dibuilder(void) {
assert(AddDbgRecordUnderTheRange == NULL);
(void)AddDbgRecordUnderTheRange;
// Test that we can read the first debug record.
LLVMMetadataRef AddDbgRecordFirstDebugLoc =
LLVMDbgRecordGetDebugLoc(AddDbgRecordFirst);
(void)AddDbgRecordFirstDebugLoc;
assert(LLVMDILocationGetLine(AddDbgRecordFirstDebugLoc) == 43);
assert(LLVMDbgRecordGetKind(AddDbgRecordFirst) == LLVMDbgRecordValue);
LLVMValueRef AddDbgRecordFirstValue =
LLVMDbgVariableRecordGetValue(AddDbgRecordFirst, 0);
(void)AddDbgRecordFirstValue;
assert(LLVMGetValueKind(AddDbgRecordFirstValue) == LLVMConstantIntValueKind);
assert(LLVMConstIntGetZExtValue(AddDbgRecordFirstValue) == 0);
LLVMMetadataRef AddDbgRecordFirstVariable =
LLVMDbgVariableRecordGetVariable(AddDbgRecordFirst);
(void)AddDbgRecordFirstVariable;
assert(LLVMGetMetadataKind(AddDbgRecordFirstVariable) ==
LLVMDILocalVariableMetadataKind);
// TODO: For now, there is no way to get the name.
LLVMMetadataRef AddDbgRecordFirstVariableScope =
LLVMDIVariableGetScope(AddDbgRecordFirstVariable);
(void)AddDbgRecordFirstVariableScope;
assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableScope) ==
LLVMDILexicalBlockMetadataKind);
LLVMMetadataRef AddDbgRecordFirstVariableFile =
LLVMDIScopeGetFile(AddDbgRecordFirstVariableScope);
(void)AddDbgRecordFirstVariableFile;
assert(LLVMGetMetadataKind(AddDbgRecordFirstVariableFile) ==
LLVMDIFileMetadataKind);
unsigned FileLen = 0;
assert(strcmp(LLVMDIFileGetFilename(AddDbgRecordFirstVariableFile, &FileLen),
"debuginfo.c") == 0);
(void)FileLen;
LLVMMetadataRef AddDbgRecordFirstExpr =
LLVMDbgVariableRecordGetExpression(AddDbgRecordFirst);
assert(LLVMGetMetadataKind(AddDbgRecordFirstExpr) ==
LLVMDIExpressionMetadataKind);
(void)AddDbgRecordFirstExpr;
char *MStr = LLVMPrintModuleToString(M);
puts(MStr);
LLVMDisposeMessage(MStr);