enums
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user