Add accessors for the file, directory, source file name (curiously, an Optional value?), of a DIFile.
This is intended to replace the LLVMValueRef-based accessors used in D52239
Differential D60489
[LLVM-C] Add DIFile Field Accesssors CodaFi on Apr 9 2019, 3:31 PM. Authored by
Details Add accessors for the file, directory, source file name (curiously, an Optional value?), of a DIFile. This is intended to replace the LLVMValueRef-based accessors used in D52239
Diff Detail
Event TimelineComment Actions @jberdine Are these bindings missing anything for your current use-case? I want to make sure you're covered before I deprecate them. Comment Actions Retarget from DIScope to DIFile since we can retrieve the file object for a scope now. Comment Actions @CodaFi thanks! For Instructions, I have modified my client to use these functions and tested. For reference, the callers look like: CAMLprim value llvm_instr_get_debug_loc_filename(LLVMValueRef Instr) { CAMLparam0(); CAMLlocal2(Option, String); LLVMMetadataRef Loc = LLVMInstructionGetDebugLoc(Instr); if (!Loc) CAMLreturn(Val_int(0)); LLVMMetadataRef Scope = LLVMDILocationGetScope(Loc); if (!Scope) CAMLreturn(Val_int(0)); LLVMMetadataRef File = LLVMDIScopeGetFile(Scope); if (!File) CAMLreturn(Val_int(0)); unsigned Length; const char *Chars; if ((Chars = LLVMDIFileGetFilename(File, &Length))) { String = caml_alloc_string(Length); memcpy(String_val(String), Chars, Length); Option = caml_alloc_small(1, 0); Store_field(Option, 0, String); CAMLreturn(Option); } CAMLreturn(Val_int(0)); } So for instructions, it seems to work well to use LLVMInstructionGetDebugLoc and then LLVMDILocationGetLine, LLVMDILocationGetColumn, LLVMDILocationGetScope and this diff's functions. But so far I have not found analogues of LLVMInstructionGetDebugLoc for GlobalVariables and Functions. To be concrete, the function extracting the line number I'm using is: unsigned LLVMGetDebugLocLine(LLVMValueRef Val) { unsigned L = 0; if (const auto *I = dyn_cast<Instruction>(unwrap(Val))) { if (const auto &DL = I->getDebugLoc()) { L = DL->getLine(); } } else if (const auto *GV = dyn_cast<GlobalVariable>(unwrap(Val))) { SmallVector<DIGlobalVariableExpression *, 1> GVEs; GV->getDebugInfo(GVEs); if (GVEs.size()) if (const DIGlobalVariable *DGV = GVEs[0]->getVariable()) L = DGV->getLine(); } else if (const auto *F = dyn_cast<Function>(unwrap(Val))) { if (const DISubprogram *DSP = F->getSubprogram()) L = DSP->getLine(); } else { assert(0 && "Expected Instruction, GlobalVariable or Function"); return -1; } return L; } Am I overlooking something, or is exposing more needed to cover what the above is doing on GlobalVariables and Functions?
Comment Actions A DISubprogram is a kind of DIScope so you can use LLVMDIScopeGetFile and the rest of the accessors to poke at their metadata. For Global Variables, the idea should be to add corresponding accessors for the scope, file, name, source, and directory since these nodes do not store DILocations. It seems like the latter is pressing, so I'll make a patch for it in a bit. Comment Actions Modulo the names seemingly left over from copy-paste, this looks good to me and is working in my tests. |