Page MenuHomePhabricator

[LLVM-C] Add DIFile Field Accesssors

Authored by CodaFi on Apr 9 2019, 3:31 PM.



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 Timeline

CodaFi created this revision.Apr 9 2019, 3:31 PM
Herald added a project: Restricted Project. · View Herald TranscriptApr 9 2019, 3:31 PM
CodaFi added a comment.Apr 9 2019, 3:32 PM

@jberdine Are these bindings missing anything for your current use-case? I want to make sure you're covered before I deprecate them.

This revision is now accepted and ready to land.Apr 9 2019, 3:37 PM
CodaFi updated this revision to Diff 194415.Apr 9 2019, 4:00 PM
CodaFi retitled this revision from [LLVM-C] Add DIScope Field Accesssors to [LLVM-C] Add DIFile Field Accesssors.
CodaFi edited the summary of this revision. (Show Details)

Retarget from DIScope to DIFile since we can retrieve the file object for a scope now.

@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) {
  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);

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;
    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?

464 ↗(On Diff #194415)

s/Scope/File ?

473 ↗(On Diff #194415)

s/Scope/File ?

482 ↗(On Diff #194415)

s/Scope/File ?

913 ↗(On Diff #194415)

Dir ?

919 ↗(On Diff #194415)

Dir ?

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.

jberdine accepted this revision.Apr 16 2019, 1:33 PM

Modulo the names seemingly left over from copy-paste, this looks good to me and is working in my tests.

CodaFi updated this revision to Diff 195466.Apr 16 2019, 2:48 PM
CodaFi marked 5 inline comments as done.

@jberdine Any further comments?

No, looks good, thanks!

This revision was automatically updated to reflect the committed changes.