Getting SMLoc from debug metadata

Hi,

I’m trying to create something like an LLVM pass fairly low in my compiler (a variant of swift).

I have an llvm::Function and llvm::Instruction where I want to emit diagnostics, using swift’s built in diagnostics system. That means I think I need an SMLoc.

I’ve used getDebugLoc().get(); to get the DILocation and can getLine(), getColumn() etc. from there to get the source location as a filename, line and column, which seems accurate enough.

I’m trying to figure out how to then create an SMLoc from that. The SMLoc class only seems to take a pointer in the constructor, which I don’t understand.

Sorry I couldn’t figure this out by googling!

Carl

Hi,

To my best understanding, you want to emit diagnostic that shows the line, column, and the input source code (in your case the swift-alike language) whenever you encounter an error while processing the LLVM IR inside the middle-end. I’m afraid this is difficult to fit into SMLoc / SourceMgr’s original design.

SMLoc is just a pointer into a buffer, which contains the source code, maintained by llvm::SourceMgr, that’s why you cannot print out full diagnostic string without the help of SourceMgr. Thus if you want to leverage SMLoc / SourceMgr, the buffer needs to carry the source code of your input language. However, LLVM’s compilation pipeline does not assume the input source code to be available inside the middle-end. The frontend and the middle-end are two separated entities communicated only by the IR.
So unless you load your input code into SourceMgr inside the middle-end, there is no way to use SMLoc for diagnosing the input code. But then I guess another (much more difficult) question will be: How do you map from high-level code to low level LLVM IR (after the input code is loaded into SourceMgr)?

The debug info you mentioned _might_ be a way, but currently there is no way to use the DebugInfo infrastructure with SMLoc.

And just a FYI, SMLoc is primarily used in emitting diagnostic info while parsing textual LLVM IR (e.g. Pop an error when there is an ill-form LLVM IR syntax)

-Min

Cool.

Thanks for the information. That makes sense.

In my case, the “llvm pass” isn’t really a middle end pass. I moved it slightly higher up the call stack, so it’s being done within front end code that still has things like `swift::ASTContext`, which has the full source code available in buffers. There’s a class called `swift::DiagnosticsEngine` that has all the things I require, if I put together a bit of plumbing.

I can get an llvm::SourceMgr that has all the source files loaded into it.

I feel like if I go through the buffers in that, looking for a buffer that has an identifier matching the filename I get from llvm::DILocation, then use some functions to get an SMLoc from the line and column (again from DILocation), I should be able to get something I can use?

Carl

p.s. Swift actually uses wrappers around both llvm::SourceMgr and llvm::SMLoc, which are called swift::SourceManager and swift::SourceLoc, I think!