This commit is contained in:
2026-06-23 17:22:41 +02:00
parent f16f352d1e
commit 2f68fc966a
16 changed files with 809 additions and 38 deletions
+68 -2
View File
@@ -81,6 +81,9 @@ Api :: struct {
get_type_spelling: proc "c"(CXType) -> CXString,
get_typedef_underlying_type: proc "c"(CXCursor) -> CXType,
get_type_declaration: proc "c"(CXType) -> CXCursor,
get_enum_decl_integer_type: proc "c"(CXCursor) -> CXType,
get_enum_constant_value: proc "c"(CXCursor) -> i64,
get_enum_constant_unsigned: proc "c"(CXCursor) -> u64,
get_canonical_type: proc "c"(CXType) -> CXType,
get_pointee_type: proc "c"(CXType) -> CXType,
get_array_element_type: proc "c"(CXType) -> CXType,
@@ -119,6 +122,7 @@ CXCursor_VarDecl :: i32(9)
CXCursor_TypedefDecl :: i32(20)
CXCursor_MacroDefinition :: i32(501)
CXCursor_FieldDecl :: i32(6)
CXCursor_EnumConstantDecl :: i32(7)
CXLinkage_External :: i32(4)
CXTLS_None :: i32(0)
@@ -201,6 +205,9 @@ load_api_from :: proc(path: string) -> (Api, bool) {
load_proc(&api, "clang_getTypeSpelling", &api.get_type_spelling) &&
load_proc(&api, "clang_getTypedefDeclUnderlyingType", &api.get_typedef_underlying_type) &&
load_proc(&api, "clang_getTypeDeclaration", &api.get_type_declaration) &&
load_proc(&api, "clang_getEnumDeclIntegerType", &api.get_enum_decl_integer_type) &&
load_proc(&api, "clang_getEnumConstantDeclValue", &api.get_enum_constant_value) &&
load_proc(&api, "clang_getEnumConstantDeclUnsignedValue", &api.get_enum_constant_unsigned) &&
load_proc(&api, "clang_getCanonicalType", &api.get_canonical_type) &&
load_proc(&api, "clang_getPointeeType", &api.get_pointee_type) &&
load_proc(&api, "clang_getArrayElementType", &api.get_array_element_type) &&
@@ -468,6 +475,10 @@ translate_type :: proc(ctx: ^Context, value: CXType, preferred_record_name := ""
record := add_record(ctx, declaration, preferred_record_name)
populate_record(ctx, record, declaration)
return add_type(ctx, Type{kind=.Record, child=INVALID_TYPE, record=record})
case CXType_Enum:
declaration := ctx.api.get_type_declaration(value)
backing := ctx.api.get_enum_decl_integer_type(declaration)
return translate_type(ctx, backing, preferred_record_name, depth+1)
case CXType_FunctionProto:
result := translate_type(ctx, ctx.api.get_result_type(value), "", depth+1)
if result == INVALID_TYPE {
@@ -508,7 +519,7 @@ translate_type :: proc(ctx: ^Context, value: CXType, preferred_record_name := ""
return INVALID_TYPE
}
return translate_type(ctx, canonical, preferred_record_name, depth+1)
case CXType_Enum, CXType_FunctionNoProto,
case CXType_FunctionNoProto,
CXType_IncompleteArray, CXType_VariableArray, CXType_DependentSizedArray:
return INVALID_TYPE
}
@@ -551,6 +562,49 @@ add_alias :: proc(ctx: ^Context, name: string, value: Type_Id, reason := "") {
})
}
enum_backing_unsigned :: proc(value: CXType) -> bool {
switch value.kind {
case CXType_Char_U, CXType_UChar, CXType_UShort, CXType_UInt, CXType_ULong, CXType_ULongLong:
return true
}
return false
}
Enum_Constant_Context :: struct {
ctx: ^Context,
backing: Type_Id,
unsigned: bool,
}
visit_enum_constant :: proc "c"(cursor, parent: CXCursor, client_data: rawptr) -> i32 {
context = runtime.default_context()
enum_ctx := (^Enum_Constant_Context)(client_data)
ctx := enum_ctx.ctx
if ctx.api.get_cursor_kind(cursor) != CXCursor_EnumConstantDecl {
return CXChildVisit_Continue
}
name := clone_cx_string(ctx.api, ctx.api.get_cursor_spelling(cursor), ctx.allocator)
defer delete(name, ctx.allocator)
if len(name) == 0 {
return CXChildVisit_Continue
}
value := Macro_Value{kind=.Integer, type=enum_ctx.backing}
if enum_ctx.unsigned {
value.integer = ctx.api.get_enum_constant_unsigned(cursor)
} else {
signed := ctx.api.get_enum_constant_value(cursor)
value.negative = signed < 0
value.integer = u64(-i128(signed)) if signed < 0 else u64(signed)
}
append(&ctx.result.macros, Macro_Constant{
name=fmt.aprintf("%s", name, allocator=ctx.allocator),
type=enum_ctx.backing,
value=value,
reason=fmt.aprintf("", allocator=ctx.allocator),
})
return CXChildVisit_Continue
}
is_macro_identifier :: proc(value: string) -> bool {
if len(value) == 0 {
return false
@@ -1367,7 +1421,19 @@ visit_cursor :: proc "c"(cursor, parent: CXCursor, client_data: rawptr) -> i32 {
add_alias(ctx, name, value)
}
case CXCursor_EnumDecl:
add_unsupported(ctx, name, "C enums are not supported")
backing_c := ctx.api.get_enum_decl_integer_type(cursor)
backing := translate_type(ctx, backing_c)
if backing == INVALID_TYPE {
add_unsupported(ctx, name, "C enum backing type is not supported")
break
}
add_alias(ctx, name, backing)
enum_ctx := Enum_Constant_Context{
ctx=ctx,
backing=backing,
unsigned=enum_backing_unsigned(backing_c),
}
_ = ctx.api.visit_children(cursor, visit_enum_constant, &enum_ctx)
case CXCursor_VarDecl:
if len(name) == 0 {
return CXChildVisit_Continue