[LLVMdev] [un]wrapping llvm:DITypeRef
Rodney M. Bates
rodney_bates at lcwb.coop
Mon Jul 27 13:05:00 PDT 2015
On 07/27/2015 10:59 AM, Rodney M. Bates wrote:
>
>
> On 07/25/2015 08:57 PM, Andrew Wilkins wrote:
>> On Sun, 26 Jul 2015 at 06:48 Rodney M. Bates <rodney_bates at lcwb.coop <mailto:rodney_bates at lcwb.coop>> wrote:
>>
>> In trying to write a C binding for DIBuilder of llvm 3.6.1, I can't see a way to unwrap
>> llvm::DITypeRef, declared in include/llvm/IR/DebugInfo.h. This is a class with one
>> data member, a pointer to Metadata.
>>
>> If I try to make my C type a struct with one pointer, I can't cast it to DITypeRef.
>> If I try to go inside the classes and use the pointer, I can cast, but can't construct
>> a DITypeRef when unwrapping, as both its pointer field 'Val' and the constructor are
>> private.
>>
>>
>> I don't know if I'm understanding the problem exactly, so I'll just point you to what the Go bindings are doing.
>>
>> First, define wrap/unwrap for llvm::Metadata (of which DIType is a descendant):
>> http://llvm.org/klaus/llvm/blob/master/bindings/go/llvm/IRBindings.h#L-63
>>
>> Then use wrapped llvm::Metadata in the C API:
>> http://llvm.org/klaus/llvm/blob/master/bindings/go/llvm/DIBuilderBindings.h
>>
>> (You could have DIType-specific wrap/unwrap too, using the same method.)
>>
>
> My problem is not DIType, it's DITypeRef. This was added sometime after 3.4.2 and
> by 3.6.1. It is used, e.g. for formal parameter Ty of DIBuilder::createLocalVariable.
> These Go bindings apparently have not been updated to 3.6.1, as they give DIType in
> such places.
>
> However, in looking more carefully at DIType, with the intention of being able to better
> explain why DITypeRef gives me a problem that DIType does not, I find the way I need
> to construct a DITypeRef is actually declared in DIType:
>
>
> class DIType : public DIScope {
> ...
> public:
> ...
> operator DITypeRef () const {
> ^^^^^^^^^^^^^^^^^^
> assert(isType() &&
> "constructing DITypeRef from an MDNode that is not a type");
> return DITypeRef(&*getRef());
> }
>
> This, through a series of specializations, befriendings, etc., is able to
> get to the private constructor of DITypeRef.
>
> This should help solve my problem, once I figure out how to construct a
> properly equivalent DIType.
>
I was mistaken. This does not solve my problem. The implicit conversion
operator DITypeRef converts from a DIType, which can contain only an MDNode*,
but I need to construct a DITypeRef, which can contain a Metadata*. The
constructor I need is here:
template <typename T> class DIRef {
template <typename DescTy>
friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
friend DIScopeRef DIScope::getContext() const;
friend DIScopeRef DIScope::getRef() const;
friend class DIType;
/// \brief Val can be either a MDNode or a MDString.
///
/// In the latter, MDString specifies the type identifier.
const Metadata *Val;
explicit DIRef(const Metadata *V);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
but it is private. I am trying very hard to avoid in-llvm-tree modifications
(we've been down that path with a gcc-derived back end.) Do I have any alternative?
Would the project accept making this constructor public?
> Thanks.
>
>> HTH,
>> Andrew
>
--
Rodney Bates
rodney.m.bates at acm.org
More information about the llvm-dev
mailing list