JuliaInterop / Clang.jl

C binding generator and Julia interface to libclang
https://juliainterop.github.io/Clang.jl/
MIT License
219 stars 68 forks source link

Enumerations with a fixed underlying type, via typedef #404

Closed notinaboat closed 1 year ago

notinaboat commented 1 year ago

While generating wrappers on macOS I came across a problem where enumerations with a fixed underlying type are defined using a typedef-ed type.

e.g. in os/clock.h an enum is defined as uint32_t.

It looks like the Clang.jl code for enums deals with typed enums, but expects them to use built-in types (not typedef-ed types like uint32_t).

The following changes seem to fix the problem (but someone who knows the Clang.jl code better will probably have a more elegant fix).

diff --git a/src/cursor.jl b/src/cursor.jl
index 8630b64..ee47098 100644
--- a/src/cursor.jl
+++ b/src/cursor.jl
@@ -236,6 +236,13 @@ Return the integer value of an enum constant declaration.
 """
 function value(c::CLEnumConstantDecl)::Integer
     typeKind = kind(getCursorType(c))
+    if typeKind == CXType_Typedef
+        typeKind = getCursorType(c) |>
+                   getTypeDeclaration |>
+                   getTypedefDeclUnderlyingType |>
+                   getCanonicalType |>
+                   kind
+    end
     if typeKind == CXType_Int ||
         typeKind == CXType_Long ||
         typeKind == CXType_LongLong
diff --git a/src/generator/codegen.jl b/src/generator/codegen.jl
index 31d0fe8..8b6c2e5 100644
--- a/src/generator/codegen.jl
+++ b/src/generator/codegen.jl
@@ -639,7 +639,13 @@ const ENUM_SYMBOL2TYPE = Dict(

 function emit!(dag::ExprDAG, node::ExprNode{<:AbstractEnumNodeType}, options::Dict; args...)
     cursor = node.cursor
-    ty = translate(tojulia(getEnumDeclIntegerType(cursor)), options)
+    ty = getEnumDeclIntegerType(cursor)
+    if ty isa Clang.CLTypedef
+        ty = getTypeDeclaration(ty) |>
+             getTypedefDeclUnderlyingType |>
+             getCanonicalType
+    end
+    ty = translate(tojulia(ty), options)
     # there is no need to treat __attribute__ specially as we directly query the integer
     # type of the enum from Clang
     enum_type = ENUM_SYMBOL2TYPE[ty]
Gnimuc commented 1 year ago

Feel free to open a PR. I think your fix is good.