authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 11:54:34-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-28 11:54:34-07:00
logf1c5d3d3a1ffd479acecd32bbd0496824316c6a6
treefb591620102897312e116c3af62dc4cefcc4ab93
parent474340a0031c9b3c8ce0d97c2cc36d5327c4e304

add parseh tests


4 files changed, 148 insertions(+), 28 deletions(-)

doc/targets.md+3
...@@ -14,3 +14,6 @@ Update the C integer types to be the correct size for the target....@@ -14,3 +14,6 @@ Update the C integer types to be the correct size for the target.
1414
15Add the conditional compilation code for the page size global. It is hardcoded15Add the conditional compilation code for the page size global. It is hardcoded
16for each target.16for each target.
17
18Make sure that parseh sends the correct command line parameters to libclang for
19the given target.
src/ast_render.cpp+1-1
...@@ -672,7 +672,7 @@ static void render_node(AstRender *ar, AstNode *node) {...@@ -672,7 +672,7 @@ static void render_node(AstRender *ar, AstNode *node) {
672 }672 }
673673
674 ar->indent -= ar->indent_size;674 ar->indent -= ar->indent_size;
675 fprintf(ar->f, "}\n");675 fprintf(ar->f, "}");
676 break;676 break;
677 }677 }
678 case NodeTypeStructField:678 case NodeTypeStructField:
src/parseh.cpp+44-1
...@@ -397,6 +397,9 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -397,6 +397,9 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
397 if (!enum_def) {397 if (!enum_def) {
398 // this is a type that we can point to but that's it, same as `struct Foo;`.398 // this is a type that we can point to but that's it, same as `struct Foo;`.
399 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));399 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
400 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),
401 create_symbol_node(c, buf_ptr(type_name)));
402 c->aliases.append(alias_node);
400 return;403 return;
401 }404 }
402405
...@@ -404,7 +407,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -404,7 +407,7 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
404 buf_init_from_buf(&node->data.struct_decl.name, type_name);407 buf_init_from_buf(&node->data.struct_decl.name, type_name);
405408
406 node->data.struct_decl.kind = ContainerKindEnum;409 node->data.struct_decl.kind = ContainerKindEnum;
407 node->data.struct_decl.visib_mod = c->visib_mod;410 node->data.struct_decl.visib_mod = VisibModExport;
408 node->data.struct_decl.directives = create_empty_directives(c);411 node->data.struct_decl.directives = create_empty_directives(c);
409412
410 ZigList<AstNode *> var_decls = {0};413 ZigList<AstNode *> var_decls = {0};
...@@ -465,6 +468,43 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {...@@ -465,6 +468,43 @@ static void visit_enum_decl(Context *c, const EnumDecl *enum_decl) {
465468
466}469}
467470
471static void visit_record_decl(Context *c, const RecordDecl *record_decl) {
472 Buf bare_name = BUF_INIT;
473 buf_init_from_str(&bare_name, decl_name(record_decl));
474
475 Buf *type_name = buf_alloc();
476 buf_appendf(type_name, "struct_%s", buf_ptr(&bare_name));
477
478 if (c->type_table.maybe_get(type_name)) {
479 // we've already seen it
480 return;
481 }
482
483 RecordDecl *record_def = record_decl->getDefinition();
484 if (!record_def) {
485 // this is a type that we can point to but that's it, such as `struct Foo;`.
486 add_typedef_node(c, type_name, create_symbol_node(c, "u8"));
487 AstNode *alias_node = create_var_decl_node(c, buf_ptr(&bare_name),
488 create_symbol_node(c, buf_ptr(type_name)));
489 c->aliases.append(alias_node);
490 return;
491 }
492
493 emit_warning(c, record_decl, "skipping record %s, TODO", buf_ptr(&bare_name));
494
495 /*
496 AstNode *node = create_node(c, NodeTypeStructDecl);
497 buf_init_from_buf(&node->data.struct_decl.name, type_name);
498
499 node->data.struct_decl.kind = ContainerKindStruct;
500 node->data.struct_decl.visib_mod = VisibModExport;
501 node->data.struct_decl.directives = create_empty_directives(c);
502
503 normalize_parent_ptrs(node);
504 c->root->data.root.top_level_decls.append(node);
505 */
506}
507
468static bool decl_visitor(void *context, const Decl *decl) {508static bool decl_visitor(void *context, const Decl *decl) {
469 Context *c = (Context*)context;509 Context *c = (Context*)context;
470510
...@@ -478,6 +518,9 @@ static bool decl_visitor(void *context, const Decl *decl) {...@@ -478,6 +518,9 @@ static bool decl_visitor(void *context, const Decl *decl) {
478 case Decl::Enum:518 case Decl::Enum:
479 visit_enum_decl(c, static_cast<const EnumDecl *>(decl));519 visit_enum_decl(c, static_cast<const EnumDecl *>(decl));
480 break;520 break;
521 case Decl::Record:
522 visit_record_decl(c, static_cast<const RecordDecl *>(decl));
523 break;
481 default:524 default:
482 emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName());525 emit_warning(c, decl, "ignoring %s decl\n", decl->getDeclKindName());
483 }526 }
test/run_tests.cpp+100-26
...@@ -24,10 +24,12 @@ struct TestCase {...@@ -24,10 +24,12 @@ struct TestCase {
24 ZigList<const char *> compile_errors;24 ZigList<const char *> compile_errors;
25 ZigList<const char *> compiler_args;25 ZigList<const char *> compiler_args;
26 ZigList<const char *> program_args;26 ZigList<const char *> program_args;
27 bool is_parseh;
27};28};
2829
29static ZigList<TestCase*> test_cases = {0};30static ZigList<TestCase*> test_cases = {0};
30static const char *tmp_source_path = ".tmp_source.zig";31static const char *tmp_source_path = ".tmp_source.zig";
32static const char *tmp_h_path = ".tmp_header.h";
31static const char *tmp_exe_path = "./.tmp_exe";33static const char *tmp_exe_path = "./.tmp_exe";
32static const char *zig_exe = "./zig";34static const char *zig_exe = "./zig";
3335
...@@ -94,6 +96,24 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source...@@ -94,6 +96,24 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source
94 return test_case;96 return test_case;
95}97}
9698
99static TestCase *add_parseh_case(const char *case_name, const char *source, const char *output) {
100 TestCase *test_case = allocate<TestCase>(1);
101 test_case->case_name = case_name;
102 test_case->output = output;
103 test_case->is_parseh = true;
104
105 test_case->source_files.resize(1);
106 test_case->source_files.at(0).relative_path = tmp_h_path;
107 test_case->source_files.at(0).source_code = source;
108
109 test_case->compiler_args.append("parseh");
110 test_case->compiler_args.append(tmp_h_path);
111 test_case->compiler_args.append("--c-import-warnings");
112
113 test_cases.append(test_case);
114 return test_case;
115}
116
97static void add_compiling_test_cases(void) {117static void add_compiling_test_cases(void) {
98 add_simple_case("hello world with libc", R"SOURCE(118 add_simple_case("hello world with libc", R"SOURCE(
99#link("c")119#link("c")
...@@ -1771,6 +1791,39 @@ const x = 2 == 2.0;...@@ -1771,6 +1791,39 @@ const x = 2 == 2.0;
17711791
1772}1792}
17731793
1794//////////////////////////////////////////////////////////////////////////////
1795
1796static void add_parseh_test_cases(void) {
1797 add_parseh_case("simple data types", R"SOURCE(
1798#include <stdint.h>
1799int foo(char a, unsigned char b, signed char c);
1800void bar(uint8_t a, uint16_t b, uint32_t c, uint64_t d);
1801void baz(int8_t a, int16_t b, int32_t c, int64_t d);
1802 )SOURCE", R"OUTPUT(pub extern fn foo(a: u8, b: u8, c: i8) -> c_int;
1803pub extern fn bar(a: u8, b: u16, c: u32, d: u64);
1804pub extern fn baz(a: i8, b: i16, c: i32, d: i64);)OUTPUT");
1805
1806 add_parseh_case("noreturn attribute", R"SOURCE(
1807void foo(void) __attribute__((noreturn));
1808 )SOURCE", R"OUTPUT(pub extern fn foo() -> unreachable;)OUTPUT");
1809
1810 add_parseh_case("enums", R"SOURCE(
1811enum Foo {
1812 FooA,
1813 FooB,
1814 Foo1,
1815};
1816 )SOURCE", R"OUTPUT(export enum enum_Foo {
1817 A,
1818 B,
1819 _1,
1820}
1821pub const FooA = enum_Foo.A;
1822pub const FooB = enum_Foo.B;
1823pub const Foo1 = enum_Foo._1;
1824pub const Foo = enum_Foo;)OUTPUT");
1825}
1826
1774static void print_compiler_invocation(TestCase *test_case) {1827static void print_compiler_invocation(TestCase *test_case) {
1775 printf("%s", zig_exe);1828 printf("%s", zig_exe);
1776 for (int i = 0; i < test_case->compiler_args.length; i += 1) {1829 for (int i = 0; i < test_case->compiler_args.length; i += 1) {
...@@ -1822,36 +1875,55 @@ static void run_test(TestCase *test_case) {...@@ -1822,36 +1875,55 @@ static void run_test(TestCase *test_case) {
1822 exit(1);1875 exit(1);
1823 }1876 }
18241877
1825 Buf program_stderr = BUF_INIT;1878 if (test_case->is_parseh) {
1826 Buf program_stdout = BUF_INIT;1879 if (buf_len(&zig_stderr) > 0) {
1827 os_exec_process(tmp_exe_path, test_case->program_args, &return_code, &program_stderr, &program_stdout);1880 printf("\nparseh emitted warnings:\n");
1881 print_compiler_invocation(test_case);
1882 printf("%s\n", buf_ptr(&zig_stderr));
1883 exit(1);
1884 }
18281885
1829 if (return_code != 0) {1886 if (!strstr(buf_ptr(&zig_stdout), test_case->output)) {
1830 printf("\nProgram exited with return code %d:\n", return_code);1887 printf("\n");
1831 print_compiler_invocation(test_case);1888 printf("========= Expected this output: =========\n");
1832 printf("%s", tmp_exe_path);1889 printf("%s\n", test_case->output);
1833 for (int i = 0; i < test_case->program_args.length; i += 1) {1890 printf("================================================\n");
1834 printf(" %s", test_case->program_args.at(i));1891 print_compiler_invocation(test_case);
1892 printf("%s\n", buf_ptr(&zig_stdout));
1893 exit(1);
1835 }1894 }
1836 printf("\n");1895 } else {
1837 printf("%s\n", buf_ptr(&program_stderr));1896 Buf program_stderr = BUF_INIT;
1838 exit(1);1897 Buf program_stdout = BUF_INIT;
1839 }1898 os_exec_process(tmp_exe_path, test_case->program_args, &return_code, &program_stderr, &program_stdout);
18401899
1841 if (!buf_eql_str(&program_stdout, test_case->output)) {1900 if (return_code != 0) {
1842 printf("\n");1901 printf("\nProgram exited with return code %d:\n", return_code);
1843 print_compiler_invocation(test_case);1902 print_compiler_invocation(test_case);
1844 printf("%s", tmp_exe_path);1903 printf("%s", tmp_exe_path);
1845 for (int i = 0; i < test_case->program_args.length; i += 1) {1904 for (int i = 0; i < test_case->program_args.length; i += 1) {
1846 printf(" %s", test_case->program_args.at(i));1905 printf(" %s", test_case->program_args.at(i));
1906 }
1907 printf("\n");
1908 printf("%s\n", buf_ptr(&program_stderr));
1909 exit(1);
1910 }
1911
1912 if (!buf_eql_str(&program_stdout, test_case->output)) {
1913 printf("\n");
1914 print_compiler_invocation(test_case);
1915 printf("%s", tmp_exe_path);
1916 for (int i = 0; i < test_case->program_args.length; i += 1) {
1917 printf(" %s", test_case->program_args.at(i));
1918 }
1919 printf("\n");
1920 printf("==== Test failed. Expected output: ====\n");
1921 printf("%s\n", test_case->output);
1922 printf("========= Actual output: ==============\n");
1923 printf("%s\n", buf_ptr(&program_stdout));
1924 printf("=======================================\n");
1925 exit(1);
1847 }1926 }
1848 printf("\n");
1849 printf("==== Test failed. Expected output: ====\n");
1850 printf("%s\n", test_case->output);
1851 printf("========= Actual output: ==============\n");
1852 printf("%s\n", buf_ptr(&program_stdout));
1853 printf("=======================================\n");
1854 exit(1);
1855 }1927 }
18561928
1857 for (int i = 0; i < test_case->source_files.length; i += 1) {1929 for (int i = 0; i < test_case->source_files.length; i += 1) {
...@@ -1881,6 +1953,7 @@ static void run_all_tests(bool reverse) {...@@ -1881,6 +1953,7 @@ static void run_all_tests(bool reverse) {
18811953
1882static void cleanup(void) {1954static void cleanup(void) {
1883 remove(tmp_source_path);1955 remove(tmp_source_path);
1956 remove(tmp_h_path);
1884 remove(tmp_exe_path);1957 remove(tmp_exe_path);
1885}1958}
18861959
...@@ -1900,6 +1973,7 @@ int main(int argc, char **argv) {...@@ -1900,6 +1973,7 @@ int main(int argc, char **argv) {
1900 }1973 }
1901 add_compiling_test_cases();1974 add_compiling_test_cases();
1902 add_compile_failure_test_cases();1975 add_compile_failure_test_cases();
1976 add_parseh_test_cases();
1903 run_all_tests(reverse);1977 run_all_tests(reverse);
1904 cleanup();1978 cleanup();
1905}1979}