# Wrapping typedef enum with Clang.jl

**URL:** <https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425>\
**Category:** General Usage\
**Tags:** interoperability, c, clang\
**Created:** [November 12, 2018, 8:17am UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425 "2018-11-12T08:17:48Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 12, 2018, 8:17am UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/1 "2018-11-12T08:17:48Z")

</div>

If I try to wrap the following header:

```nohighlight
typedef enum _foo {
  BAR,
  BAZ
} foo;

```

using the following Clang.jl script:

```julia
using Clang.wrap_c

const context = wrap_c.init(
    headers = [joinpath(@ __DIR__ , "header.h")],
    common_file = joinpath(@ __DIR__ , "wrapper.jl"),
    clang_diagnostics = true,
)

run(context)

```

I get the following wrapper:

```julia
# begin enum _foo
const _foo = UInt32
const BAR = 0 |> UInt32
const BAZ = 1 |> UInt32
# end enum _foo

const foo = Cvoid

```

I was expecting that the typedef name `const foo = UInt32`. Functions generated as part of this wrapper which should return an integer will instead return `nothing`.

Do I need to configure the wrapping process differently, or is there a problem processing typedefs?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [November 12, 2018, 10:33am UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/2 "2018-11-12T10:33:09Z")

</div>

looks like a bug, it was supposed to be `const foo = _foo`, but I cannot reproduce it in this PR [https://github.com/ihnorton/Clang.jl/pull/210](https://github.com/ihnorton/Clang.jl/pull/210) :

```julia
ctx = DefaultContext()
trans_unit = parse_header!(ctx, "typedef.h")
top = getcursor(trans_unit)
func1 = search(top, "foo")[1]
wrap!(ctx, func1)
ctx.common_buffer[:foo].items[] # -> const foo = _foo

```

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 12, 2018, 12:03pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/3 "2018-11-12T12:03:56Z")

</div>

Thank you @Gnimuc, I have opened issue [#213](https://github.com/ihnorton/Clang.jl/issues/213) to track.

Are there any significant changes that I will need to make to my wrapper script (which is obviously more complicated that the MWE above) in order to use your branch?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [November 12, 2018, 12:18pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/4 "2018-11-12T12:18:17Z")

</div>

the wrapper script should be compatible, you could refer to [this script](https://github.com/ihnorton/Clang.jl/blob/2987d46de032a853de9baf82fb99d6c7cf084f3a/gen/generator.jl). and you may need to include `CEnum.jl` and `ctypes.jl` in your wrapper like [this](https://github.com/ihnorton/Clang.jl/blob/2987d46de032a853de9baf82fb99d6c7cf084f3a/src/LibClang.jl). I’m still adding the tests and tweaking the code, hopefully, I can finish this in a couple of hours.

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [November 12, 2018, 2:46pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/5 "2018-11-12T14:46:25Z")

</div>

@samuelpowell almost done, you could test it now. I’ll add docs in the next few days, but feel free to ping me if things go south.

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 12, 2018, 3:34pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/6 "2018-11-12T15:34:43Z")

</div>

The MWE reports:

```julia
ERROR: LoadError: type WrapContext has no field InternalOptions
Stacktrace:
 [1] getproperty(::Any, ::Symbol) at ./sysimg.jl:18
 [2] run(::WrapContext) at /home/spowell/.julia/dev/Clang/src/compat.jl:92
 [3] top-level scope at none:0
 [4] include at ./boot.jl:317 [inlined]
 [5] include_relative(::Module, ::String) at ./loading.jl:1044
 [6] include(::Module, ::String) at ./sysimg.jl:29
 [7] include(::String) at ./client.jl:392
 [8] top-level scope at none:0
in expression starting at /home/spowell/spinjl/headerwrap.jl:9

```

My larger file seems to undergo a lot of processing but then fails with the same message. ~~Any ideas?~~ See below for fix.

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 12, 2018, 3:40pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/7 "2018-11-12T15:40:18Z")

</div>

I’m guessing line 92 of `compat.jl` should read:

```julia
    ctx.options["is_struct_mutable"] = wc.options.ismutable

```

[PR here](https://github.com/Gnimuc/Clang.jl/pull/2)

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 12, 2018, 3:54pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/8 "2018-11-12T15:54:47Z")

</div>

With the above change I’m getting some good looking output, will try and test it shortly.

Note that I was previously using a cursor filter which checked for an input type of `Clang.cindex.FunctionDecl` in order to restrict the wrapping to specific function names. This is no longer available, but after removing the filter all together the output seems sane (previously it was wrapping a load of standard C functions).

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 12, 2018, 5:13pm UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/9 "2018-11-12T17:13:03Z")

</div>

@Gnimuc there appears to be a problem with enumeriations taking negative values. For example, if you wrap the modified MWE:

```nohighlight
typedef enum _foo {
  BAR,
  BAZ=-9
} foo;

```

Then after (after including CEnum and the wrapper)

```julia
julia> foo(-9)
Error showing value of type _foo:
ERROR: Invalid enum: 4294967287, name not found
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] enum_name at /home/spowell/spinjl/CEnum.jl:44 [inlined]
 [3] show(::IOContext{REPL.Terminals.TTYTerminal}, ::_foo) at /home/spowell/spinjl/CEnum.jl:47
 [4] show(::IOContext{REPL.Terminals.TTYTerminal}, ::MIME{Symbol("text/plain")}, ::_foo) at ./sysimg.jl:194
 [5] display(::REPL.REPLDisplay, ::MIME{Symbol("text/plain")}, ::Any) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:131
 [6] display(::REPL.REPLDisplay, ::Any) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.0/REPL/src/REPL.jl:135
 [7] display(::Any) at ./multimedia.jl:287
 [8] #invokelatest#1 at ./essentials.jl:697 [inlined]
 [9] invokelatest at ./essentials.jl:696 [inlined]

```

(truncated)

I can hack this to work by changing the equality function in `CEnum.jl` to cast to a signed integer, but I don’t know the code well enough to determine if that is a good idea or not!

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [November 13, 2018, 1:40am UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/10 "2018-11-13T01:40:20Z")

</div>

~~were you looking for `wc.cursor_wrapped`?~~

you could use `using Clang.LibClang; kind(cursor) == CXCursor_FunctionDecl` to determine whether a cursor is a `Clang.cindex.FunctionDecl`. now, using Clang.jl is just like directly using libclang, so you could always refer to libclang’s documentation for help: [clang: libclang: C Interface to Clang](https://clang.llvm.org/doxygen/group__CINDEX.html#ggaaccc432245b4cd9f2d470913f9ef0013a97a968184f82f31b5054384d151d18ea)

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [November 13, 2018, 5:14am UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/11 "2018-11-13T05:14:08Z")

</div>

with this commit, CEnum should support for any integer types in Base.

[https://github.com/ihnorton/Clang.jl/pull/210/commits/60f2657a3b331d321549f4fc94f0b94de5e6942c](https://github.com/ihnorton/Clang.jl/pull/210/commits/60f2657a3b331d321549f4fc94f0b94de5e6942c)

---

<div class="post-metadata">

**Author:** ![samuelpowell](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/samuelpowell/32/248_2.png) [@samuelpowell](https://discourse.julialang.org/u/samuelpowell)\
**Post date:** [November 13, 2018, 8:17am UTC](https://discourse.julialang.org/t/wrapping-typedef-enum-with-clang-jl/17425/12 "2018-11-13T08:17:52Z")

</div>

And indeed it does! Your branch now works without any problems on my wrapper (and produces sane output). Thanks so much for your help on this. I hope having a bit of testing in the wild was worthwhile!
