mirror of
https://github.com/ziglang/zig.git
synced 2025-12-20 05:03:06 +00:00
parseh handles typedef void better
and introduce c_long_double type
This commit is contained in:
parent
c77637d172
commit
1053172854
@ -205,6 +205,7 @@ c_long long for ABI compatibility with C
|
|||||||
c_ulong unsigned long for ABI compatibility with C
|
c_ulong unsigned long for ABI compatibility with C
|
||||||
c_longlong long long for ABI compatibility with C
|
c_longlong long long for ABI compatibility with C
|
||||||
c_ulonglong unsigned long long for ABI compatibility with C
|
c_ulonglong unsigned long long for ABI compatibility with C
|
||||||
|
c_long_double long double for ABI compatibility with C
|
||||||
```
|
```
|
||||||
|
|
||||||
### Boolean Type
|
### Boolean Type
|
||||||
|
|||||||
@ -17,3 +17,5 @@ for each target.
|
|||||||
|
|
||||||
Make sure that parseh sends the correct command line parameters to libclang for
|
Make sure that parseh sends the correct command line parameters to libclang for
|
||||||
the given target.
|
the given target.
|
||||||
|
|
||||||
|
Make sure that `c_long_double` codegens the correct floating point value.
|
||||||
|
|||||||
@ -1023,6 +1023,7 @@ struct CodeGen {
|
|||||||
TypeTableEntry *entry_bool;
|
TypeTableEntry *entry_bool;
|
||||||
TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64]
|
TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64]
|
||||||
TypeTableEntry *entry_c_int[8];
|
TypeTableEntry *entry_c_int[8];
|
||||||
|
TypeTableEntry *entry_c_long_double;
|
||||||
TypeTableEntry *entry_u8;
|
TypeTableEntry *entry_u8;
|
||||||
TypeTableEntry *entry_u16;
|
TypeTableEntry *entry_u16;
|
||||||
TypeTableEntry *entry_u32;
|
TypeTableEntry *entry_u32;
|
||||||
|
|||||||
@ -2918,6 +2918,18 @@ static void define_builtin_types(CodeGen *g) {
|
|||||||
g->builtin_types.entry_f64 = entry;
|
g->builtin_types.entry_f64 = entry;
|
||||||
g->primitive_type_table.put(&entry->name, entry);
|
g->primitive_type_table.put(&entry->name, entry);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
|
||||||
|
entry->type_ref = LLVMX86FP80Type();
|
||||||
|
buf_init_from_str(&entry->name, "c_long_double");
|
||||||
|
entry->size_in_bits = 128;
|
||||||
|
entry->align_in_bits = 128;
|
||||||
|
entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
|
||||||
|
80, entry->align_in_bits,
|
||||||
|
LLVMZigEncoding_DW_ATE_float());
|
||||||
|
g->builtin_types.entry_c_long_double = entry;
|
||||||
|
g->primitive_type_table.put(&entry->name, entry);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
|
TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
|
||||||
entry->type_ref = LLVMVoidType();
|
entry->type_ref = LLVMVoidType();
|
||||||
|
|||||||
@ -234,6 +234,19 @@ static TypeTableEntry *get_c_void_type(Context *c) {
|
|||||||
return c->c_void_type;
|
return c->c_void_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) {
|
||||||
|
if (!c->c_void_type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (type_entry->id == TypeTableEntryIdTypeDecl) {
|
||||||
|
if (type_entry == c->c_void_type) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
type_entry = type_entry->data.type_decl.child_type;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,
|
static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,
|
||||||
HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
|
HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
|
||||||
{
|
{
|
||||||
@ -243,7 +256,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
|
|||||||
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
|
const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
|
||||||
switch (builtin_ty->getKind()) {
|
switch (builtin_ty->getKind()) {
|
||||||
case BuiltinType::Void:
|
case BuiltinType::Void:
|
||||||
return c->codegen->builtin_types.entry_void;
|
return get_c_void_type(c);
|
||||||
case BuiltinType::Bool:
|
case BuiltinType::Bool:
|
||||||
return c->codegen->builtin_types.entry_bool;
|
return c->codegen->builtin_types.entry_bool;
|
||||||
case BuiltinType::Char_U:
|
case BuiltinType::Char_U:
|
||||||
@ -273,6 +286,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
|
|||||||
case BuiltinType::Double:
|
case BuiltinType::Double:
|
||||||
return c->codegen->builtin_types.entry_f64;
|
return c->codegen->builtin_types.entry_f64;
|
||||||
case BuiltinType::LongDouble:
|
case BuiltinType::LongDouble:
|
||||||
|
return c->codegen->builtin_types.entry_c_long_double;
|
||||||
case BuiltinType::WChar_U:
|
case BuiltinType::WChar_U:
|
||||||
case BuiltinType::Char16:
|
case BuiltinType::Char16:
|
||||||
case BuiltinType::Char32:
|
case BuiltinType::Char32:
|
||||||
@ -322,10 +336,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
|
|||||||
}
|
}
|
||||||
bool is_const = child_qt.isConstQualified();
|
bool is_const = child_qt.isConstQualified();
|
||||||
|
|
||||||
if (child_type->id == TypeTableEntryIdVoid) {
|
|
||||||
child_type = get_c_void_type(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);
|
TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);
|
||||||
return get_maybe_type(c->codegen, non_null_pointer_type);
|
return get_maybe_type(c->codegen, non_null_pointer_type);
|
||||||
}
|
}
|
||||||
@ -421,8 +431,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
|
|||||||
} else {
|
} else {
|
||||||
fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);
|
fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);
|
||||||
if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) {
|
if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) {
|
||||||
|
emit_warning(c, decl, "unresolved function proto return type");
|
||||||
return c->codegen->builtin_types.entry_invalid;
|
return c->codegen->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
// convert c_void to actual void (only for return type)
|
||||||
|
if (is_c_void_type(c, fn_type_id.return_type)) {
|
||||||
|
fn_type_id.return_type = c->codegen->builtin_types.entry_void;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn_type_id.param_info = allocate<FnTypeParamInfo>(fn_type_id.param_count);
|
fn_type_id.param_info = allocate<FnTypeParamInfo>(fn_type_id.param_count);
|
||||||
@ -431,6 +446,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
|
|||||||
TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);
|
TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);
|
||||||
|
|
||||||
if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) {
|
if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) {
|
||||||
|
emit_warning(c, decl, "unresolved function proto parameter type");
|
||||||
return c->codegen->builtin_types.entry_invalid;
|
return c->codegen->builtin_types.entry_invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,6 +482,10 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
|
|||||||
{
|
{
|
||||||
const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
|
const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
|
||||||
TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl);
|
TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl);
|
||||||
|
if (child_type->id == TypeTableEntryIdInvalid) {
|
||||||
|
emit_warning(c, decl, "unresolved array element type");
|
||||||
|
return child_type;
|
||||||
|
}
|
||||||
uint64_t size = const_arr_ty->getSize().getLimitedValue();
|
uint64_t size = const_arr_ty->getSize().getLimitedValue();
|
||||||
return get_array_type(c->codegen, child_type, size);
|
return get_array_type(c->codegen, child_type, size);
|
||||||
}
|
}
|
||||||
@ -601,6 +621,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
|
|||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);
|
TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);
|
||||||
|
if (child_type->id == TypeTableEntryIdInvalid) {
|
||||||
|
emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type);
|
TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type);
|
||||||
add_typedef_node(c, decl_type);
|
add_typedef_node(c, decl_type);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1903,9 +1903,10 @@ int foo(char a, unsigned char b, signed char c);
|
|||||||
int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
|
int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
|
||||||
void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
|
void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
|
||||||
void baz(int8_t a, int16_t b, int32_t c, int64_t d);
|
void baz(int8_t a, int16_t b, int32_t c, int64_t d);
|
||||||
)SOURCE", 1, R"OUTPUT(pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;
|
)SOURCE", 3,
|
||||||
pub extern fn bar(a: u8, b: u16, c: u32, d: u64);
|
"pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;",
|
||||||
pub extern fn baz(a: i8, b: i16, c: i32, d: i64);)OUTPUT");
|
"pub extern fn bar(a: u8, b: u16, c: u32, d: u64);",
|
||||||
|
"pub extern fn baz(a: i8, b: i16, c: i32, d: i64);");
|
||||||
|
|
||||||
add_parseh_case("noreturn attribute", R"SOURCE(
|
add_parseh_case("noreturn attribute", R"SOURCE(
|
||||||
void foo(void) __attribute__((noreturn));
|
void foo(void) __attribute__((noreturn));
|
||||||
@ -1953,7 +1954,7 @@ enum Bar {
|
|||||||
BarB,
|
BarB,
|
||||||
};
|
};
|
||||||
void func(struct Foo *a, enum Bar **b);
|
void func(struct Foo *a, enum Bar **b);
|
||||||
)SOURCE", 2, R"OUTPUT(export struct struct_Foo {
|
)SOURCE", 3, R"OUTPUT(export struct struct_Foo {
|
||||||
x: c_int,
|
x: c_int,
|
||||||
y: c_int,
|
y: c_int,
|
||||||
}
|
}
|
||||||
@ -1962,8 +1963,8 @@ export enum enum_Bar {
|
|||||||
B,
|
B,
|
||||||
}
|
}
|
||||||
pub const BarA = enum_Bar.A;
|
pub const BarA = enum_Bar.A;
|
||||||
pub const BarB = enum_Bar.B;
|
pub const BarB = enum_Bar.B;)OUTPUT",
|
||||||
pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);)OUTPUT",
|
"pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);",
|
||||||
R"OUTPUT(pub const Foo = struct_Foo;
|
R"OUTPUT(pub const Foo = struct_Foo;
|
||||||
pub const Bar = enum_Bar;)OUTPUT");
|
pub const Bar = enum_Bar;)OUTPUT");
|
||||||
|
|
||||||
@ -2038,6 +2039,15 @@ struct Bar {
|
|||||||
R"SOURCE(export struct struct_Foo {
|
R"SOURCE(export struct struct_Foo {
|
||||||
next: ?&struct_Bar,
|
next: ?&struct_Bar,
|
||||||
})SOURCE");
|
})SOURCE");
|
||||||
|
|
||||||
|
|
||||||
|
add_parseh_case("typedef void", R"SOURCE(
|
||||||
|
typedef void Foo;
|
||||||
|
Foo fun(Foo *a);
|
||||||
|
)SOURCE", 3,
|
||||||
|
"pub type c_void = u8;",
|
||||||
|
"pub type Foo = c_void;",
|
||||||
|
"pub extern fn fun(a: ?&Foo);");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_compiler_invocation(TestCase *test_case) {
|
static void print_compiler_invocation(TestCase *test_case) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user