From: Matthias Braun Date: Fri, 25 Jul 2008 08:59:48 +0000 (+0000) Subject: support for libc builtins X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=14e576785476dd318701c177d97fd266f730eee2;p=cparser support for libc builtins [r20680] --- diff --git a/Makefile b/Makefile index 87b732d..acc6009 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ SOURCES := \ type_hash.c \ warning.c \ write_fluffy.c \ + write_caml.c \ driver/firm_cmdline.c \ driver/firm_timing.c \ driver/firm_codegen.c \ @@ -110,6 +111,10 @@ $(DIRS): @echo "===> MKDIR $@" $(Q)mkdir -p $@ +builtins.h: builtins/builtins.c + @echo '===> CREATE_BUILTINS $<' + $(Q)./create_builtins_h.sh > $@ + build/cpb/%.o: %.c build/cparser @echo '===> CPARSER $<' $(Q)./build/cparser $(CPPFLAGS) -std=c99 -Wall -g3 -c $< -o $@ diff --git a/builtins/builtins.c b/builtins/builtins.c new file mode 100644 index 0000000..6cab6aa --- /dev/null +++ b/builtins/builtins.c @@ -0,0 +1,36 @@ +static inline char *strchr(const char *s, int c) +{ + for ( ; *s != 0; ++s) { + if (*s == c) + return (char*) s; + } + return (char*) 0; +} + +static inline char *strrchr(const char *s, int c) +{ + const char *result = (const char*) 0; + + for ( ; *s != 0; ++s) { + if (*s == c) + result = s; + } + return (char*) result; +} + +static inline int strcmp(const char *s1, const char *s2) +{ + for( ; (*s1 | *s2) != 0; ++s1, ++s2) { + if(*s1 != *s2) + break; + } + return *s1 - *s2; +} + +static inline __SIZE_TYPE__ strlen(const char *s) +{ + __SIZE_TYPE__ result = 0; + for ( ; *s != 0; ++s) + result++; + return result; +} diff --git a/create_builtins_h.sh b/create_builtins_h.sh new file mode 100755 index 0000000..e9d86eb --- /dev/null +++ b/create_builtins_h.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +cat <<__EOF__ +/* WARNING: automatically generated file. Generated from builtins/builtins.c */ + +static const char builtins[] = +__EOF__ + +cat builtins/builtins.c | sed -e 's/^/\t\"/g' -e 's/$/\\n\"/g' + +cat << __EOF__ +; +__EOF__ diff --git a/driver/firm_opt.c b/driver/firm_opt.c index bacf110..261dbd2 100644 --- a/driver/firm_opt.c +++ b/driver/firm_opt.c @@ -1130,8 +1130,11 @@ void gen_firm_finish(FILE *out, const char *input_filename, int c_mode, int firm stat_dump_snapshot(input_filename, "noopt"); } - if (firm_opt.enabled) + if (firm_opt.enabled) { + do_firm_optimizations(input_filename, firm_const_exists); do_firm_optimizations(input_filename, firm_const_exists); + do_firm_optimizations(input_filename, firm_const_exists); + } if (firm_dump.gen_firm_asm) { timer_push(TV_FIRM_ASM); diff --git a/lexer.c b/lexer.c index faecfe3..fe51c2f 100644 --- a/lexer.c +++ b/lexer.c @@ -81,6 +81,11 @@ static inline void next_real_char(void) { assert(bufpos <= bufend); if (bufpos >= bufend) { + if (input == NULL) { + c = EOF; + return; + } + size_t s = fread(buf + MAX_PUTBACK, 1, sizeof(buf) - MAX_PUTBACK, input); if(s == 0) { @@ -1596,6 +1601,7 @@ newline_found: void init_lexer(void) { strset_init(&stringset); + symbol_L = symbol_table_insert("L"); } void lexer_open_stream(FILE *stream, const char *input_name) @@ -1604,7 +1610,6 @@ void lexer_open_stream(FILE *stream, const char *input_name) lexer_token.source_position.linenr = 0; lexer_token.source_position.input_name = input_name; - symbol_L = symbol_table_insert("L"); bufpos = NULL; bufend = NULL; @@ -1613,6 +1618,20 @@ void lexer_open_stream(FILE *stream, const char *input_name) c = '\n'; } +void lexer_open_buffer(const char *buffer, size_t len, const char *input_name) +{ + input = NULL; + lexer_token.source_position.linenr = 0; + lexer_token.source_position.input_name = input_name; + + bufpos = buffer; + bufend = buffer + len; + + /* place a virtual \n at the beginning so the lexer knows that we're + * at the beginning of a line */ + c = '\n'; +} + void exit_lexer(void) { strset_destroy(&stringset); diff --git a/lexer.h b/lexer.h index 587b19e..8adcdd9 100644 --- a/lexer.h +++ b/lexer.h @@ -34,6 +34,7 @@ void init_lexer(void); void exit_lexer(void); void lexer_open_stream(FILE *stream, const char *input_name); +void lexer_open_buffer(const char *buffer, size_t len, const char *input_name); string_t concat_strings( const string_t *s1, const string_t *s2); wide_string_t concat_string_wide_string(const string_t *s1, const wide_string_t *s2); diff --git a/main.c b/main.c index 9890beb..1add07c 100644 --- a/main.c +++ b/main.c @@ -75,11 +75,12 @@ #include "driver/firm_cmdline.h" #include "adt/error.h" #include "write_fluffy.h" +#include "write_caml.h" #include "revision.h" #include "warning.h" #ifndef PREPROCESSOR -#define PREPROCESSOR "cpp -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int -m32" +#define PREPROCESSOR "cpp -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int -D__SIZE_TYPE__=__SIZE_TYPE__ -m32" #endif #ifndef LINKER @@ -102,6 +103,9 @@ bool char_is_signed = true; /** true for strict language checking. */ bool strict_mode = false; +/** use builtins for some libc functions */ +bool use_builtins = false; + /* to switch on printing of implicit casts */ extern bool print_implicit_casts; @@ -173,10 +177,21 @@ static void get_output_name(char *buf, size_t buflen, const char *inputname, memcpy(buf+last_dot, newext, extlen); } +#include "builtins.h" + static translation_unit_t *do_parsing(FILE *const in, const char *const input_name) { + start_parsing(); + + if (use_builtins) { + lexer_open_buffer(builtins, sizeof(builtins)-1, ""); + parse(); + } + lexer_open_stream(in, input_name); - translation_unit_t *unit = parse(); + parse(); + + translation_unit_t *unit = finish_parsing(); return unit; } @@ -359,6 +374,7 @@ typedef enum compile_mode_t { LexTest, PrintAst, PrintFluffy, + PrintCaml, Link } compile_mode_t; @@ -464,6 +480,7 @@ int main(int argc, char **argv) case 3: set_option("cond-eval"); set_option("if-conv"); + use_builtins = true; /* fallthrough */ case 2: set_option("inline"); @@ -633,7 +650,7 @@ int main(int argc, char **argv) input = arg; } } else if(strcmp(option, "pg") == 0) { - set_be_option("-b gprof"); + set_be_option("gprof"); obstack_printf(&ldflags_obst, " -pg"); } else if(strcmp(option, "pedantic") == 0) { fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg); @@ -679,6 +696,8 @@ int main(int argc, char **argv) print_parenthesis = true; } else if(strcmp(option, "print-fluffy") == 0) { mode = PrintFluffy; + } else if(strcmp(option, "print-caml") == 0) { + mode = PrintCaml; } else if(strcmp(option, "version") == 0) { print_cparser_version(); exit(EXIT_SUCCESS); @@ -718,7 +737,8 @@ int main(int argc, char **argv) continue; } - if (strcmp(arg+len-2, ".c") == 0) { + if (strcmp(arg+len-2, ".c") == 0 + || strcmp(arg+len-2, ".h") == 0) { entry->next = c_files; c_files = entry; } else if (strcmp(arg+len-2, ".s") == 0) { @@ -775,6 +795,7 @@ int main(int argc, char **argv) case BenchmarkParser: case PrintAst: case PrintFluffy: + case PrintCaml: case LexTest: if(outname == NULL) outname = "-"; @@ -902,10 +923,11 @@ int main(int argc, char **argv) return result; if(mode == PrintFluffy) { - type_set_output(out); - ast_set_output(out); write_fluffy_decls(out, unit); } + if (mode == PrintCaml) { + write_caml_decls(out, unit); + } translation_unit_to_firm(unit); diff --git a/parser.c b/parser.c index 1882d8a..4e37812 100644 --- a/parser.c +++ b/parser.c @@ -104,6 +104,7 @@ static goto_statement_t *goto_first = NULL; static goto_statement_t *goto_last = NULL; static label_statement_t *label_first = NULL; static label_statement_t *label_last = NULL; +static translation_unit_t *unit = NULL; static struct obstack temp_obst; static source_position_t null_position = { NULL, 0 }; @@ -3900,7 +3901,7 @@ static declaration_t *internal_record_declaration( if (old_storage_class == STORAGE_CLASS_EXTERN && new_storage_class == STORAGE_CLASS_EXTERN) { warn_redundant_declaration: - if (warning.redundant_decls) { + if (warning.redundant_decls && strcmp(previous_declaration->source_position.input_name, "") != 0) { warningf(&declaration->source_position, "redundant declaration for '%Y' (declared %P)", symbol, &previous_declaration->source_position); @@ -8066,18 +8067,8 @@ static void check_unused_globals(void) /** * Parse a translation unit. */ -static translation_unit_t *parse_translation_unit(void) +static void parse_translation_unit(void) { - translation_unit_t *unit = allocate_ast_zero(sizeof(unit[0])); - - assert(global_scope == NULL); - global_scope = &unit->scope; - - assert(scope == NULL); - set_scope(&unit->scope); - - initialize_builtin_types(); - while(token.type != T_EOF) { if (token.type == ';') { /* TODO error in strict mode */ @@ -8087,16 +8078,6 @@ static translation_unit_t *parse_translation_unit(void) parse_external_declaration(); } } - - assert(scope == &unit->scope); - scope = NULL; - last_declaration = NULL; - - assert(global_scope == &unit->scope); - check_unused_globals(); - global_scope = NULL; - - return unit; } /** @@ -8104,7 +8085,7 @@ static translation_unit_t *parse_translation_unit(void) * * @return the translation unit or NULL if errors occurred. */ -translation_unit_t *parse(void) +void start_parsing(void) { environment_stack = NEW_ARR_F(stack_entry_t, 0); label_stack = NEW_ARR_F(stack_entry_t, 0); @@ -8115,16 +8096,43 @@ translation_unit_t *parse(void) type_set_output(stderr); ast_set_output(stderr); - lookahead_bufpos = 0; - for(int i = 0; i < MAX_LOOKAHEAD + 2; ++i) { - next_token(); - } - translation_unit_t *unit = parse_translation_unit(); + assert(unit == NULL); + unit = allocate_ast_zero(sizeof(unit[0])); + + assert(global_scope == NULL); + global_scope = &unit->scope; + + assert(scope == NULL); + set_scope(&unit->scope); + + initialize_builtin_types(); +} + +translation_unit_t *finish_parsing(void) +{ + assert(scope == &unit->scope); + scope = NULL; + last_declaration = NULL; + + assert(global_scope == &unit->scope); + check_unused_globals(); + global_scope = NULL; DEL_ARR_F(environment_stack); DEL_ARR_F(label_stack); - return unit; + translation_unit_t *result = unit; + unit = NULL; + return result; +} + +void parse(void) +{ + lookahead_bufpos = 0; + for(int i = 0; i < MAX_LOOKAHEAD + 2; ++i) { + next_token(); + } + parse_translation_unit(); } /** diff --git a/parser.h b/parser.h index c892482..b6ee305 100644 --- a/parser.h +++ b/parser.h @@ -28,7 +28,9 @@ typedef struct environment_entry_t environment_entry_t; void init_parser(void); void exit_parser(void); -translation_unit_t *parse(void); +void start_parsing(void); +void parse(void); +translation_unit_t *finish_parsing(void); type_t *revert_automatic_type_conversion(const expression_t *expression); declaration_t *expr_is_variable(const expression_t *expression); diff --git a/write_caml.c b/write_caml.c new file mode 100644 index 0000000..b688cc6 --- /dev/null +++ b/write_caml.c @@ -0,0 +1,385 @@ +/* + * This file is part of cparser. + * Copyright (C) 2007-2008 Matthias Braun + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include + +#include +#include + +#include "write_caml.h" +#include "symbol_t.h" +#include "ast_t.h" +#include "type_t.h" +#include "type.h" +#include "adt/error.h" + +static const scope_t *global_scope; +static FILE *out; + +static void write_type(const type_t *type); + +static const char *get_atomic_type_string(const atomic_type_kind_t type) +{ + switch(type) { + case ATOMIC_TYPE_VOID: return "unit"; + case ATOMIC_TYPE_CHAR: return "byte"; + case ATOMIC_TYPE_SCHAR: return "byte"; + case ATOMIC_TYPE_UCHAR: return "unsigned byte"; + case ATOMIC_TYPE_SHORT: return "short"; + case ATOMIC_TYPE_USHORT: return "unsigned short"; + case ATOMIC_TYPE_INT: return "int"; + case ATOMIC_TYPE_UINT: return "unsigned int"; + case ATOMIC_TYPE_LONG: return "int"; + case ATOMIC_TYPE_ULONG: return "unsigned int"; + case ATOMIC_TYPE_LONGLONG: return "long"; + case ATOMIC_TYPE_ULONGLONG: return "unsigned long"; + case ATOMIC_TYPE_FLOAT: return "float"; + case ATOMIC_TYPE_DOUBLE: return "double"; + case ATOMIC_TYPE_LONG_DOUBLE: return "double"; + case ATOMIC_TYPE_BOOL: return "bool"; + default: panic("unsupported atomic type"); + } +} + +static void write_atomic_type(const atomic_type_t *type) +{ + fprintf(out, "%s", get_atomic_type_string(type->akind)); +} + +static void write_pointer_type(const pointer_type_t *type) +{ + type_t *points_to = type->points_to; + if (points_to->kind == TYPE_ATOMIC && + is_type_atomic(points_to, ATOMIC_TYPE_CHAR)) { + fputs("string", out); + return; + } + + write_type(type->points_to); + fputc('*', out); +} + +static declaration_t *find_typedef(const type_t *type) +{ + /* first: search for a matching typedef in the global type... */ + declaration_t *declaration = global_scope->declarations; + while(declaration != NULL) { + if (! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) { + declaration = declaration->next; + continue; + } + if (declaration->type == type) + break; + declaration = declaration->next; + } + + return declaration; +} + +static void write_compound_type(const compound_type_t *type) +{ + declaration_t *declaration = find_typedef((const type_t*) type); + if (declaration != NULL) { + fprintf(out, "%s", declaration->symbol->string); + return; + } + + /* does the struct have a name? */ + symbol_t *symbol = type->declaration->symbol; + if (symbol != NULL) { + /* TODO: make sure we create a struct for it... */ + fprintf(out, "%s", symbol->string); + return; + } + /* TODO: create a struct and use its name here... */ + fprintf(out, "/* TODO anonymous struct */byte"); +} + +static void write_enum_type(const enum_type_t *type) +{ + declaration_t *declaration = find_typedef((const type_t*) type); + if (declaration != NULL) { + fprintf(out, "%s", declaration->symbol->string); + return; + } + + /* does the enum have a name? */ + symbol_t *symbol = type->declaration->symbol; + if (symbol != NULL) { + /* TODO: make sure we create an enum for it... */ + fprintf(out, "%s", symbol->string); + return; + } + /* TODO: create a struct and use its name here... */ + fprintf(out, "/* TODO anonymous enum */byte"); +} + +static void write_function_type(const function_type_t *type) +{ + fprintf(out, "(func("); + + function_parameter_t *parameter = type->parameters; + int first = 1; + while(parameter != NULL) { + if (!first) { + fprintf(out, ", "); + } else { + first = 0; + } + +#if 0 + if (parameter->symbol != NULL) { + fprintf(out, "%s : ", parameter->symbol->string); + } else { + /* TODO make up some unused names (or allow _ in fluffy?) */ + fprintf(out, "_ : "); + } +#endif + fputs("_ : ", out); + write_type(parameter->type); + + parameter = parameter->next; + } + + fprintf(out, ") : "); + write_type(type->return_type); + fprintf(out, ")"); +} + +static void write_type(const type_t *type) +{ + switch(type->kind) { + case TYPE_ATOMIC: + write_atomic_type(&type->atomic); + return; + case TYPE_POINTER: + write_pointer_type(&type->pointer); + return; + case TYPE_COMPOUND_UNION: + case TYPE_COMPOUND_STRUCT: + write_compound_type(&type->compound); + return; + case TYPE_ENUM: + write_enum_type(&type->enumt); + return; + case TYPE_FUNCTION: + write_function_type(&type->function); + return; + case TYPE_INVALID: + panic("invalid type found"); + break; + case TYPE_COMPLEX: + case TYPE_IMAGINARY: + default: + fprintf(out, "/* TODO type */"); + break; + } +} + +#if 0 +static void write_struct_entry(const declaration_t *declaration) +{ + fprintf(out, "\t%s : ", declaration->symbol->string); + write_type(declaration->type); + fprintf(out, "\n"); +} + +static void write_struct(const symbol_t *symbol, const compound_type_t *type) +{ + fprintf(out, "struct %s:\n", symbol->string); + + const declaration_t *declaration = type->declaration->scope.declarations; + while(declaration != NULL) { + write_struct_entry(declaration); + declaration = declaration->next; + } + + fprintf(out, "\n"); +} + +static void write_union(const symbol_t *symbol, const compound_type_t *type) +{ + fprintf(out, "union %s:\n", symbol->string); + + const declaration_t *declaration = type->declaration->scope.declarations; + while(declaration != NULL) { + write_struct_entry(declaration); + declaration = declaration->next; + } + + fprintf(out, "\n"); +} + +static void write_expression(const expression_t *expression); + +static void write_unary_expression(const unary_expression_t *expression) +{ + switch(expression->base.kind) { + case EXPR_UNARY_NEGATE: + fputc('-', out); + break; + case EXPR_UNARY_NOT: + fputc('!', out); + break; + default: + panic("unimeplemented unary expression found"); + } + write_expression(expression->value); +} + +static void write_expression(const expression_t *expression) +{ + const const_expression_t *constant; + /* TODO */ + switch(expression->kind) { + case EXPR_CONST: + constant = &expression->conste; + if (is_type_integer(expression->base.type)) { + fprintf(out, "%lld", constant->v.int_value); + } else { + fprintf(out, "%Lf", constant->v.float_value); + } + break; + EXPR_UNARY_CASES + write_unary_expression((const unary_expression_t*) expression); + break; + default: + panic("not implemented expression"); + } +} + +static void write_enum(const symbol_t *symbol, const enum_type_t *type) +{ + fprintf(out, "enum %s:\n", symbol->string); + + declaration_t *entry = type->declaration->next; + for ( ; entry != NULL && entry->storage_class == STORAGE_CLASS_ENUM_ENTRY; + entry = entry->next) { + fprintf(out, "\t%s", entry->symbol->string); + if (entry->init.initializer != NULL) { + fprintf(out, " <- "); + write_expression(entry->init.enum_value); + } + fputc('\n', out); + } + fprintf(out, "typealias %s <- int\n", symbol->string); + fprintf(out, "\n"); +} + +static void write_variable(const declaration_t *declaration) +{ + fprintf(out, "var %s : ", declaration->symbol->string); + write_type(declaration->type); + /* TODO: initializers */ + fprintf(out, "\n"); +} +#endif + +static void write_function(const declaration_t *declaration) +{ + if (declaration->init.statement != NULL) { + fprintf(stderr, "Warning: can't convert function bodies (at %s)\n", + declaration->symbol->string); + } + + fprintf(out, "external %s: ", declaration->symbol->string); + + const function_type_t *function_type + = (const function_type_t*) declaration->type; + + declaration_t *parameter = declaration->scope.declarations; + for( ; parameter != NULL; parameter = parameter->next) { + write_type(parameter->type); + fputs(" -> ", out); + } + if (function_type->variadic) { + fprintf(stderr, "WARNING: Variadic function not supported yet\n"); + } + if (function_type->unspecified_parameters) { + fprintf(stderr, "WARNING: unspecified params not supported\n"); + } + const type_t *return_type = function_type->return_type; + write_type(return_type); + + fputs(" = \"", out); + fputs(declaration->symbol->string, out); + fputs("\"", out); + + fputc('\n', out); +} + +void write_caml_decls(FILE *output, const translation_unit_t *unit) +{ + out = output; + global_scope = &unit->scope; + + ast_set_output(out); + fprintf(out, "(* WARNING: Automatically generated file - chaning is useless *)\n"); + +#if 0 + /* write structs,unions + enums */ + declaration_t *declaration = unit->scope.declarations; + for( ; declaration != NULL; declaration = declaration->next) { + //fprintf(out, "// Decl: %s\n", declaration->symbol->string); + if (! (declaration->storage_class == STORAGE_CLASS_TYPEDEF)) { + continue; + } + type_t *type = declaration->type; + if (type->kind == TYPE_COMPOUND_STRUCT) { + write_struct(declaration->symbol, &type->compound); + } else if (type->kind == TYPE_COMPOUND_UNION) { + write_union(declaration->symbol, &type->compound); + } else if (type->kind == TYPE_ENUM) { + write_enum(declaration->symbol, &type->enumt); + } + } + + /* write global variables */ + declaration = unit->scope.declarations; + for( ; declaration != NULL; declaration = declaration->next) { + if (declaration->namespc != NAMESPACE_NORMAL) + continue; + if (declaration->storage_class == STORAGE_CLASS_TYPEDEF + || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY) + continue; + + type_t *type = declaration->type; + if (type->kind == TYPE_FUNCTION) + continue; + + write_variable(declaration); + } +#endif + + /* write functions */ + declaration_t *declaration = unit->scope.declarations; + for( ; declaration != NULL; declaration = declaration->next) { + if (declaration->namespc != NAMESPACE_NORMAL) + continue; + if (declaration->storage_class == STORAGE_CLASS_TYPEDEF + || declaration->storage_class == STORAGE_CLASS_ENUM_ENTRY) + continue; + + type_t *type = declaration->type; + if (type->kind != TYPE_FUNCTION) + continue; + + write_function(declaration); + } +} diff --git a/write_caml.h b/write_caml.h new file mode 100644 index 0000000..9273e47 --- /dev/null +++ b/write_caml.h @@ -0,0 +1,27 @@ +/* + * This file is part of cparser. + * Copyright (C) 2007-2008 Matthias Braun + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#ifndef WRITE_CAML_H +#define WRITE_CAML_H + +#include "ast.h" + +void write_caml_decls(FILE *out, const translation_unit_t *unit); + +#endif diff --git a/write_fluffy.c b/write_fluffy.c index 0d66b0b..5379aee 100644 --- a/write_fluffy.c +++ b/write_fluffy.c @@ -334,6 +334,7 @@ void write_fluffy_decls(FILE *output, const translation_unit_t *unit) global_scope = &unit->scope; ast_set_output(out); + type_set_output(out); fprintf(out, "/* WARNING: Automatically generated file */\n"); /* write structs,unions + enums */