+ }
+
+ FILE *asm_out;
+ if (mode == Compile) {
+ asm_out = out;
+ } else {
+ asm_out = make_temp_file(asm_tempfile, sizeof(asm_tempfile), "ccs");
+ }
+
+ if (in == NULL)
+ in = open_file(filename);
+
+ /* preprocess and compile */
+ if (filetype == FILETYPE_PREPROCESSED_C) {
+ char const* invalid_mode;
+ switch (standard) {
+ case STANDARD_ANSI:
+ case STANDARD_C89: c_mode = _C89; break;
+ /* TODO determine difference between these two */
+ case STANDARD_C90: c_mode = _C89; break;
+ case STANDARD_C99: c_mode = _C89 | _C99; break;
+ case STANDARD_GNU89: c_mode = _C89 | _GNUC; break;
+
+default_c_warn:
+ fprintf(stderr,
+ "warning: command line option \"-std=%s\" is not valid for C\n",
+ invalid_mode);
+ /* FALLTHROUGH */
+ case STANDARD_DEFAULT:
+ case STANDARD_GNU99: c_mode = _C89 | _C99 | _GNUC; break;
+
+ case STANDARD_CXX98: invalid_mode = "c++98"; goto default_c_warn;
+ case STANDARD_GNUXX98: invalid_mode = "gnu98"; goto default_c_warn;
+ }
+ goto do_parsing;
+ } else if (filetype == FILETYPE_PREPROCESSED_CXX) {
+ char const* invalid_mode;
+ switch (standard) {
+ case STANDARD_C89: invalid_mode = "c89"; goto default_cxx_warn;
+ case STANDARD_C90: invalid_mode = "c90"; goto default_cxx_warn;
+ case STANDARD_C99: invalid_mode = "c99"; goto default_cxx_warn;
+ case STANDARD_GNU89: invalid_mode = "gnu89"; goto default_cxx_warn;
+ case STANDARD_GNU99: invalid_mode = "gnu99"; goto default_cxx_warn;
+
+ case STANDARD_ANSI:
+ case STANDARD_CXX98: c_mode = _CXX; break;
+
+default_cxx_warn:
+ fprintf(stderr,
+ "warning: command line option \"-std=%s\" is not valid for C++\n",
+ invalid_mode);
+ case STANDARD_DEFAULT:
+ case STANDARD_GNUXX98: c_mode = _CXX | _GNUC; break;
+ }
+
+do_parsing:
+ c_mode |= features_on;
+ c_mode &= ~features_off;
+
+ /* do the actual parsing */
+ ir_timer_t *t_parsing = ir_timer_new();
+ timer_register(t_parsing, "Frontend: Parsing");
+ timer_push(t_parsing);
+ init_tokens();
+ translation_unit_t *const unit = do_parsing(in, filename);
+ timer_pop(t_parsing);
+
+ /* prints the AST even if errors occurred */
+ if (mode == PrintAst) {
+ print_to_file(out);
+ print_ast(unit);
+ }
+
+ if (error_count > 0) {
+ /* parsing failed because of errors */
+ fprintf(stderr, "%u error(s), %u warning(s)\n", error_count,
+ warning_count);
+ result = EXIT_FAILURE;
+ continue;
+ } else if (warning_count > 0) {
+ fprintf(stderr, "%u warning(s)\n", warning_count);
+ }
+
+ if (in == preprocessed_in) {
+ int pp_result = pclose(preprocessed_in);
+ if (pp_result != EXIT_SUCCESS) {
+ /* remove output file */
+ if (out != stdout)
+ unlink(outname);
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (mode == BenchmarkParser) {
+ return result;
+ } else if (mode == PrintFluffy) {
+ write_fluffy_decls(out, unit);
+ continue;
+ } else if (mode == PrintCaml) {
+ write_caml_decls(out, unit);
+ continue;
+ } else if (mode == PrintJna) {
+ write_jna_decls(out, unit);
+ continue;
+ }
+
+ /* build the firm graph */
+ ir_timer_t *t_construct = ir_timer_new();
+ timer_register(t_construct, "Frontend: Graph construction");
+ timer_push(t_construct);
+ translation_unit_to_firm(unit);
+ timer_pop(t_construct);
+
+graph_built:
+ if (mode == ParseOnly) {
+ continue;
+ }
+
+ if (mode == CompileDump) {
+ /* find irg */
+ ident *id = new_id_from_str(dumpfunction);
+ ir_graph *irg = NULL;
+ int n_irgs = get_irp_n_irgs();
+ for (int i = 0; i < n_irgs; ++i) {
+ ir_graph *tirg = get_irp_irg(i);
+ ident *irg_id = get_entity_ident(get_irg_entity(tirg));
+ if (irg_id == id) {
+ irg = tirg;
+ break;
+ }
+ }
+
+ if (irg == NULL) {
+ fprintf(stderr, "No graph for function '%s' found\n",
+ dumpfunction);
+ exit(1);
+ }
+
+ dump_ir_block_graph_file(irg, out);
+ fclose(out);
+ exit(0);
+ }
+
+ if (mode == CompileExportIR) {
+ fclose(out);
+ ir_export(outname);
+ exit(0);
+ }
+
+ gen_firm_finish(asm_out, filename, /*c_mode=*/1,
+ have_const_functions);
+ if (asm_out != out) {
+ fclose(asm_out);
+ }
+ } else if (filetype == FILETYPE_IR) {
+ fclose(in);
+ ir_import(filename);
+ goto graph_built;
+ } else if (filetype == FILETYPE_PREPROCESSED_ASSEMBLER) {
+ copy_file(asm_out, in);
+ if (in == preprocessed_in) {
+ int pp_result = pclose(preprocessed_in);
+ if (pp_result != EXIT_SUCCESS) {
+ /* remove output in error case */
+ if (out != stdout)
+ unlink(outname);
+ return pp_result;
+ }
+ }
+ if (asm_out != out) {
+ fclose(asm_out);