Add thin shims to C interface to provide access to DebugLoc info for
Instructions, GlobalVariables and Functions.
Details
- Reviewers
whitequark deadalnix echristo compnerd
Diff Detail
- Repository
- rL LLVM
- Build Status
Buildable 23667 Build 23666: arc lint + arc unit
Event Timeline
Why are there three sets of functions that all operate on LLVMValueRef? Can't we make it a single set of functions?
All new C API functions that return strings must accept an unsigned *Length parameter.
Since this is a rather nontrivial addition to the C API, I think you should split this into a C patch which I'd like to get a second opinion on, and then a separate OCaml patch.
I don't know if this is the idiomatic way to do dynamic dispatch in C, feedback very welcome.
I put these functions after the Metadata ones, but there might be a better place.
@whitequark, did you have someone in mind to look at these LLVM-C changes, or should I do some git blaming?
lib/IR/Core.cpp | ||
---|---|---|
1194 | I think that unwrap(Val) should be possible to be hoisted rather than done in each case. | |
1195 | Can't you hoist the unwrap here into the conditional? if (const auto *I = unwrap<Instruction>(Val)) | |
1196 | Please mark the Length parameter as _Nonnull, add an assert, or add a check for Length being non-null here. | |
1208 | I think that this is better with an early return: if (GVEs.size() == 0) { *Length = 0; return nullptr; } StringRef S = GVEs[0]->getVariable()->getDirectory(); *Length = S.size(); return S.data(); | |
1218 | Similar with an early return. | |
1220 | This is going to get "optimized" away in NDEBUG builds. If you hoist the S out of the cases, and sink the Length assignment and return, you at least get predictable behaviour. | |
1251 | Similar behavioural changes as above. | |
1266 | Similar behavioural changes. | |
1269–1272 | Why not: if (const auto *I = unwrap<Instruction>(Val)) if (const auto &L = I->getDebugLoc()) return L->getColumn(); return 0; |
lib/IR/Core.cpp | ||
---|---|---|
1202 | getVariable can return nullptr |
Suggested changes to LLVMGetDebugLocDirectory and LLVMGetDebugLocColumn, will update LLVMGetDebugLocFilename and LLVMGetDebugLocLine when LLVMGetDebugLocDirectory settles
lib/IR/Core.cpp | ||
---|---|---|
1194 | Can further hoisting be done now? | |
1196 | I added an assert above instead of _Nonnull since this is expected to be called from outside, where an attribute is less likely to be checkable. | |
1220 | Do you expect the current version to be so "optimized"? (I'm not positive I grokked what you had in mind with 'sink the Length assignment and return'.) |
lib/IR/Core.cpp | ||
---|---|---|
1194 | Not sure I understand the comment about _Nonnull not being able to check-able. | |
1201 | The use of the goto is unnecessary. Just do: if (GVEs.Size()) if (const DIGlobalVariable *DGV = GVEs[0]->getVariable()) S = DGV->getDirectory(); | |
1208 | The goto is unnecesary. Just do: if (const DISubprogram *DSP = F->getSubprogram()) S = DSP->getDirectory(); | |
1220 | Yes, it isn't unheard of for builds to be done without asserts enabled, so that is a valid concern. | |
1247 | I think that this can be rewritten similar to the function above. | |
1262 | I think that it makes sense to use the same pattern with the conditional assignments. |
lib/IR/Core.cpp | ||
---|---|---|
1257 | GVEs[0]->getVariable() can return nullptr. |
Rely on default initialization of StringRef, and use conditional assignment instead of early return.
lib/IR/Core.cpp | ||
---|---|---|
1194 | This is an entry point that gets called from other language bindings via their foreign function interfaces, which are unlikely to check _Nonnull, or even be able to "see" it since they are essentially written against the ABI. |
lib/IR/Core.cpp | ||
---|---|---|
1194 | The _Nonnull is a hint to the compiler that the value is non-null. When building that against a header that declares it, the compiler should ensure that the value being passed is non-null. The problem is that the assertion can be compiled out (-DNDEBUG). Maybe change this to a if (!Length) return nullptr? | |
1208 | Add a return nullptr. The assertion can be compiled out. | |
1215 | Same as above, either annotate with _Nonnull or change this to an early return. | |
1229 | Same as above, add a return nullptr. | |
1236 | Please change this to unsigned to match the return type of DebugLoc::getLine. | |
1249 | Please add a return -1 here since the assert can be compiled out. | |
1255 | Please change this to an unsigned to match the return type of DebugLoc::getColumn. |
This seems reasonable to me. @whitequark, are you okay with them too? To @whitequark's original point, I think that the dispatching the type based on a query is pretty cool (you can do an enumeration + union output), but, I think API-wise, this is safer and easier to work with, not to mention also simplifies the implementation.
Thanks for your help and patience! This has certainly improved a lot from the first version I submitted.
Would one of you mind committing this?
I think that unwrap(Val) should be possible to be hoisted rather than done in each case.