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
205205c_ulong unsigned long for ABI compatibility with C
206206c_longlong long long for ABI compatibility with C
207207c_ulonglong unsigned long long for ABI compatibility with C
208c_long_double long double for ABI compatibility with C
208209```
209210
210211### Boolean Type
doc/targets.md+2
......@@ -17,3 +17,5 @@ for each target.
1717
1818Make sure that parseh sends the correct command line parameters to libclang for
1919the 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 {
10231023 TypeTableEntry *entry_bool;
10241024 TypeTableEntry *entry_int[2][4]; // [signed,unsigned][8,16,32,64]
10251025 TypeTableEntry *entry_c_int[8];
1026 TypeTableEntry *entry_c_long_double;
10261027 TypeTableEntry *entry_u8;
10271028 TypeTableEntry *entry_u16;
10281029 TypeTableEntry *entry_u32;
src/codegen.cpp+12
......@@ -2918,6 +2918,18 @@ static void define_builtin_types(CodeGen *g) {
29182918 g->builtin_types.entry_f64 = entry;
29192919 g->primitive_type_table.put(&entry->name, entry);
29202920 }
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 }
29212933 {
29222934 TypeTableEntry *entry = new_type_table_entry(TypeTableEntryIdVoid);
29232935 entry->type_ref = LLVMVoidType();
src/parseh.cpp+29-5
......@@ -234,6 +234,19 @@ static TypeTableEntry *get_c_void_type(Context *c) {
234234 return c->c_void_type;
235235}
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
237250static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const Decl *decl,
238251 HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> *type_table)
239252{
......@@ -243,7 +256,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
243256 const BuiltinType *builtin_ty = static_cast<const BuiltinType*>(ty);
244257 switch (builtin_ty->getKind()) {
245258 case BuiltinType::Void:
246 return c->codegen->builtin_types.entry_void;
259 return get_c_void_type(c);
247260 case BuiltinType::Bool:
248261 return c->codegen->builtin_types.entry_bool;
249262 case BuiltinType::Char_U:
......@@ -273,6 +286,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
273286 case BuiltinType::Double:
274287 return c->codegen->builtin_types.entry_f64;
275288 case BuiltinType::LongDouble:
289 return c->codegen->builtin_types.entry_c_long_double;
276290 case BuiltinType::WChar_U:
277291 case BuiltinType::Char16:
278292 case BuiltinType::Char32:
......@@ -322,10 +336,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
322336 }
323337 bool is_const = child_qt.isConstQualified();
324338
325 if (child_type->id == TypeTableEntryIdVoid) {
326 child_type = get_c_void_type(c);
327 }
328
329339 TypeTableEntry *non_null_pointer_type = get_pointer_to_type(c->codegen, child_type, is_const);
330340 return get_maybe_type(c->codegen, non_null_pointer_type);
331341 }
......@@ -421,8 +431,13 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
421431 } else {
422432 fn_type_id.return_type = resolve_qual_type(c, fn_proto_ty->getReturnType(), decl);
423433 if (get_underlying_type(fn_type_id.return_type)->id == TypeTableEntryIdInvalid) {
434 emit_warning(c, decl, "unresolved function proto return type");
424435 return c->codegen->builtin_types.entry_invalid;
425436 }
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 }
426441 }
427442
428443 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
431446 TypeTableEntry *param_type = resolve_qual_type(c, qt, decl);
432447
433448 if (get_underlying_type(param_type)->id == TypeTableEntryIdInvalid) {
449 emit_warning(c, decl, "unresolved function proto parameter type");
434450 return c->codegen->builtin_types.entry_invalid;
435451 }
436452
......@@ -466,6 +482,10 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
466482 {
467483 const ConstantArrayType *const_arr_ty = static_cast<const ConstantArrayType *>(ty);
468484 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 }
469489 uint64_t size = const_arr_ty->getSize().getLimitedValue();
470490 return get_array_type(c->codegen, child_type, size);
471491 }
......@@ -601,6 +621,10 @@ static void visit_typedef_decl(Context *c, const TypedefNameDecl *typedef_decl)
601621 // TODO
602622
603623 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 }
604628 TypeTableEntry *decl_type = get_typedecl_type(c->codegen, buf_ptr(type_name), child_type);
605629 add_typedef_node(c, decl_type);
606630}
test/run_tests.cpp+16-6
......@@ -1903,9 +1903,10 @@ int foo(char a, unsigned char b, signed char c);
19031903int foo(char a, unsigned char b, signed char c); // test a duplicate prototype
19041904void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
19051905void 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;
1907pub extern fn bar(a: u8, b: u16, c: u32, d: u64);
1908pub extern fn baz(a: i8, b: i16, c: i32, d: i64);)OUTPUT");
1906 )SOURCE", 3,
1907 "pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;",
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
19101911 add_parseh_case("noreturn attribute", R"SOURCE(
19111912void foo(void) __attribute__((noreturn));
......@@ -1953,7 +1954,7 @@ enum Bar {
19531954 BarB,
19541955};
19551956void 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 {
19571958 x: c_int,
19581959 y: c_int,
19591960}
......@@ -1962,8 +1963,8 @@ export enum enum_Bar {
19621963 B,
19631964}
19641965pub const BarA = enum_Bar.A;
1965pub const BarB = enum_Bar.B;
1966pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);)OUTPUT",
1966pub const BarB = enum_Bar.B;)OUTPUT",
1967 "pub extern fn func(a: ?&struct_Foo, b: ?&?&enum_Bar);",
19671968 R"OUTPUT(pub const Foo = struct_Foo;
19681969pub const Bar = enum_Bar;)OUTPUT");
19691970
......@@ -2038,6 +2039,15 @@ struct Bar {
20382039 R"SOURCE(export struct struct_Foo {
20392040 next: ?&struct_Bar,
20402041})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);");
20412051}
20422052
20432053static void print_compiler_invocation(TestCase *test_case) {