[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