authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-31 15:44:02-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-31 15:44:02-07:00
log105317285402befe75289c20c4b12fccbe94aa08
treeac322be01d56666d135e1e3c41b0b4e76eb9723b
parentc77637d1720bc80f97c21214596cec9ffc617d12

parseh handles typedef void better

and introduce c_long_double type

6 files changed, 61 insertions(+), 11 deletions(-)

doc/langref.md+1
...@@ -205,6 +205,7 @@ c_long long for ABI compatibility with C...@@ -205,6 +205,7 @@ c_long long for ABI compatibility with C
205c_ulong unsigned long for ABI compatibility with C205c_ulong unsigned long for ABI compatibility with C
206c_longlong long long for ABI compatibility with C206c_longlong long long for ABI compatibility with C
207c_ulonglong unsigned long long for ABI compatibility with C207c_ulonglong unsigned long long for ABI compatibility with C
208c_long_double long double for ABI compatibility with C
208```209```
209210
210### Boolean Type211### Boolean Type
doc/targets.md+2
...@@ -17,3 +17,5 @@ for each target....@@ -17,3 +17,5 @@ for each target.
1717
18Make sure that parseh sends the correct command line parameters to libclang for18Make sure that parseh sends the correct command line parameters to libclang for
19the given target.19the given target.
20
21Make sure that `c_long_double` codegens the correct floating point value.
src/all_types.hpp+1
...@@ -1023,6 +1023,7 @@ struct CodeGen {...@@ -1023,6 +1023,7 @@ struct CodeGen {
1023 TypeTableEntry *entry_bool;1023 TypeTableEntry *entry_bool;
1024 TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64]1024 TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64]
1025 TypeTableEntry *entry_c_int[8];1025 TypeTableEntry *entry_c_int[8];
1026 TypeTableEntry *entry_c_long_double;
1026 TypeTableEntry *entry_u8;1027 TypeTableEntry *entry_u8;
1027 TypeTableEntry *entry_u16;1028 TypeTableEntry *entry_u16;
1028 TypeTableEntry *entry_u32;1029 TypeTableEntry *entry_u32;
src/codegen.cpp+12
...@@ -2918,6 +2918,18 @@ static void define_builtin_types(CodeGen *g) {...@@ -2918,6 +2918,18 @@ static void define_builtin_types(CodeGen *g) {
2918 g->builtin_types.entry_f64 = entry;2918 g->builtin_types.entry_f64 = entry;
2919 g->primitive_type_table.put(&entry->name, entry);2919 g->primitive_type_table.put(&entry->name, entry);
2920 }2920 }
2921 {
2922 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdFloat);
2923 entry->type_ref = LLVMX86FP80Type();
2924 buf_init_from_str(&entry->name, "c_long_double");
2925 entry->size_in_bits = 128;
2926 entry->align_in_bits = 128;
2927 entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name),
2928 80, entry->align_in_bits,
2929 LLVMZigEncoding_DW_ATE_float());
2930 g->builtin_types.entry_c_long_double = entry;
2931 g->primitive_type_table.put(&entry->name, entry);
2932 }
2921 {2933 {
2922 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);2934 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
2923 entry->type_ref = LLVMVoidType();2935 entry->type_ref = LLVMVoidType();
src/parseh.cpp+29-5
...@@ -234,6 +234,19 @@ static TypeTableEntry *get_c_void_type(Context *c) {...@@ -234,6 +234,19 @@ static TypeTableEntry *get_c_void_type(Context *c) {
234 return c->c_void_type;234 return c->c_void_type;
235}235}
236236
237static bool is_c_void_type(Context *c, TypeTableEntry *type_entry) {
238 if (!c->c_void_type) {
239 return false;
240 }
241 while (type_entry->id == TypeTableEntryIdTypeDecl) {
242 if (type_entry == c->c_void_type) {
243 return true;
244 }
245 type_entry = type_entry->data.type_decl.child_type;
246 }
247 return false;
248}
249
237static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,250static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,
238 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)251 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
239{252{
...@@ -243,7 +256,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const...@@ -243,7 +256,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
243 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);256 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
244 switch (builtin_ty->getKind()) {257 switch (builtin_ty->getKind()) {
245 case BuiltinType::Void:258 case BuiltinType::Void:
246 return c->codegen->builtin_types.entry_void;259 return get_c_void_type(c);
247 case BuiltinType::Bool:260 case BuiltinType::Bool:
248 return c->codegen->builtin_types.entry_bool;261 return c->codegen->builtin_types.entry_bool;
249 case BuiltinType::Char_U:262 case BuiltinType::Char_U:
...@@ -273,6 +286,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const...@@ -273,6 +286,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
273 case BuiltinType::Double:286 case BuiltinType::Double:
274 return c->codegen->builtin_types.entry_f64;287 return c->codegen->builtin_types.entry_f64;
275 case BuiltinType::LongDouble:288 case BuiltinType::LongDouble:
289 return c->codegen->builtin_types.entry_c_long_double;
276 case BuiltinType::WChar_U:290 case BuiltinType::WChar_U:
277 case BuiltinType::Char16:291 case BuiltinType::Char16:
278 case BuiltinType::Char32:292 case BuiltinType::Char32:
...@@ -322,10 +336,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const...@@ -322,10 +336,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
322 }336 }
323 bool is_const = child_qt.isConstQualified();337 bool is_const = child_qt.isConstQualified();
324338
325 if (child_type->id == TypeTableEntryIdVoid) {
326 child_type = get_c_void_type(c);
327 }
328
329 TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);339 TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);
330 return get_maybe_type(c->codegen, non_null_pointer_type);340 return get_maybe_type(c->codegen, non_null_pointer_type);
331 }341 }
...@@ -421,8 +431,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const...@@ -421,8 +431,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
421 } else {431 } else {
422 fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);432 fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);
423 if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) {433 if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) {
434 emit_warning(c, decl, "unresolved function proto return type");
424 return c->codegen->builtin_types.entry_invalid;435 return c->codegen->builtin_types.entry_invalid;
425 }436 }
437 // convert c_void to actual void (only for return type)
438 if (is_c_void_type(c, fn_type_id.return_type)) {
439 fn_type_id.return_type = c->codegen->builtin_types.entry_void;
440 }
426 }441 }
427442
428 fn_type_id.param_info = allocate<FnTypeParamInfo>(fn_type_id.param_count);443 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...@@ -431,6 +446,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
431 TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);446 TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);
432447
433 if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) {448 if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) {
449 emit_warning(c, decl, "unresolved function proto parameter type");
434 return c->codegen->builtin_types.entry_invalid;450 return c->codegen->builtin_types.entry_invalid;
435 }451 }
436452
...@@ -466,6 +482,10 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const...@@ -466,6 +482,10 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
466 {482 {
467 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);483 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
468 TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl);484 TypeTableEntry *child_type = resolve_qual_type(c, const_arr_ty->getElementType(), decl);
485 if (child_type->id == TypeTableEntryIdInvalid) {
486 emit_warning(c, decl, "unresolved array element type");
487 return child_type;
488 }
469 uint64_t size = const_arr_ty->getSize().getLimitedValue();489 uint64_t size = const_arr_ty->getSize().getLimitedValue();
470 return get_array_type(c->codegen, child_type, size);490 return get_array_type(c->codegen, child_type, size);
471 }491 }
...@@ -601,6 +621,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)...@@ -601,6 +621,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
601 // TODO621 // TODO
602622
603 TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);623 TypeTableEntry *child_type = resolve_qual_type(c, child_qt, typedef_decl);
624 if (child_type->id == TypeTableEntryIdInvalid) {
625 emit_warning(c, typedef_decl, "typedef %s - unresolved child type", buf_ptr(type_name));
626 return;
627 }
604 TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type);628 TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type);
605 add_typedef_node(c, decl_type);629 add_typedef_node(c, decl_type);
606}630}
test/run_tests.cpp+16-6
...@@ -1903,9 +1903,10 @@ int foo(char a, unsigned char b, signed char c);...@@ -1903,9 +1903,10 @@ int foo(char a, unsigned char b, signed char c);
1903int foo(char a, unsigned char b, signed char c); // test a duplicate prototype1903int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
1904void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);1904void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
1905void baz(int8_t a, int16_t b, int32_t c, int64_t d);1905void baz(int8_t a, int16_t b, int32_t c, int64_t d);
1906 )SOURCE", 1, R"OUTPUT(pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;1906 )SOURCE", 3,
1907pub extern fn bar(a: u8, b: u16, c: u32, d: u64);1907 "pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;",
1908pub extern fn baz(a: i8, b: i16, c: i32, d: i64);)OUTPUT");1908 "pub extern fn bar(a: u8, b: u16, c: u32, d: u64);",
1909 "pub extern fn baz(a: i8, b: i16, c: i32, d: i64);");
19091910
1910 add_parseh_case("noreturn attribute", R"SOURCE(1911 add_parseh_case("noreturn attribute", R"SOURCE(
1911void foo(void) __attribute__((noreturn));1912void foo(void) __attribute__((noreturn));
...@@ -1953,7 +1954,7 @@ enum Bar {...@@ -1953,7 +1954,7 @@ enum Bar {
1953 BarB,1954 BarB,
1954};1955};
1955void func(struct Foo *a, enum Bar **b);1956void func(struct Foo *a, enum Bar **b);
1956 )SOURCE", 2, R"OUTPUT(export struct struct_Foo {1957 )SOURCE", 3, R"OUTPUT(export struct struct_Foo {
1957 x: c_int,1958 x: c_int,
1958 y: c_int,1959 y: c_int,
1959}1960}
...@@ -1962,8 +1963,8 @@ export enum enum_Bar {...@@ -1962,8 +1963,8 @@ export enum enum_Bar {
1962 B,1963 B,
1963}1964}
1964pub const BarA = enum_Bar.A;1965pub const BarA = enum_Bar.A;
1965pub const BarB = enum_Bar.B;1966pub const BarB = enum_Bar.B;)OUTPUT",
1966pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);)OUTPUT",1967 "pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);",
1967 R"OUTPUT(pub const Foo = struct_Foo;1968 R"OUTPUT(pub const Foo = struct_Foo;
1968pub const Bar = enum_Bar;)OUTPUT");1969pub const Bar = enum_Bar;)OUTPUT");
19691970
...@@ -2038,6 +2039,15 @@ struct Bar {...@@ -2038,6 +2039,15 @@ struct Bar {
2038 R"SOURCE(export struct struct_Foo {2039 R"SOURCE(export struct struct_Foo {
2039 next: ?&struct_Bar,2040 next: ?&struct_Bar,
2040})SOURCE");2041})SOURCE");
2042
2043
2044 add_parseh_case("typedef void", R"SOURCE(
2045typedef void Foo;
2046Foo fun(Foo *a);
2047 )SOURCE", 3,
2048 "pub type c_void = u8;",
2049 "pub type Foo = c_void;",
2050 "pub extern fn fun(a: ?&Foo);");
2041}2051}
20422052
2043static void print_compiler_invocation(TestCase *test_case) {2053static void print_compiler_invocation(TestCase *test_case) {