- file_list_entry_t *file;
- bool already_constructed_firm = false;
- for (file = files; file != NULL; file = file->next) {
- char asm_tempfile[1024];
- const char *filename = file->name;
- filetype_t filetype = file->type;
-
- if (filetype == FILETYPE_OBJECT)
- continue;
-
- FILE *in = NULL;
- if (mode == LexTest) {
- if (in == NULL)
- in = open_file(filename);
- lextest(in, filename);
- fclose(in);
- return EXIT_SUCCESS;
- }
-
- FILE *preprocessed_in = NULL;
- filetype_t next_filetype = filetype;
- switch (filetype) {
- case FILETYPE_C:
- next_filetype = FILETYPE_PREPROCESSED_C;
- goto preprocess;
- case FILETYPE_CXX:
- next_filetype = FILETYPE_PREPROCESSED_CXX;
- goto preprocess;
- case FILETYPE_ASSEMBLER:
- next_filetype = FILETYPE_PREPROCESSED_ASSEMBLER;
- goto preprocess;
-preprocess:
- /* no support for input on FILE* yet */
- if (in != NULL)
- panic("internal compiler error: in for preprocessor != NULL");
-
- preprocessed_in = preprocess(filename, filetype);
- if (mode == PreprocessOnly) {
- copy_file(out, preprocessed_in);
- int result = pclose(preprocessed_in);
- fclose(out);
- /* remove output file in case of error */
- if (out != stdout && result != EXIT_SUCCESS) {
- unlink(outname);
- }
- return result;
- }
-
- in = preprocessed_in;
- filetype = next_filetype;
- break;
-
- default:
- break;
- }
-
- 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);
- return EXIT_FAILURE;
- }
- }
-
- if (mode == BenchmarkParser) {
- return result;
- } else if (mode == PrintFluffy) {
- write_fluffy_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);
- if (already_constructed_firm) {
- panic("compiling multiple files/translation units not possible");
- }
- translation_unit_to_firm(unit);
- already_constructed_firm = true;
- 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);
- return EXIT_FAILURE;
- }
-
- dump_ir_graph_file(out, irg);
- fclose(out);
- return EXIT_SUCCESS;
- }
-
- if (mode == CompileExportIR) {
- fclose(out);
- ir_export(outname);
- return EXIT_SUCCESS;
- }
-
- gen_firm_finish(asm_out, filename);
- 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);
- }
- }
-
- if (mode == Compile)
- continue;
-
- /* if we're here then we have preprocessed assembly */
- filename = asm_tempfile;
- filetype = FILETYPE_PREPROCESSED_ASSEMBLER;
-
- /* assemble */
- if (filetype == FILETYPE_PREPROCESSED_ASSEMBLER) {
- char temp[1024];
- const char *filename_o;
- if (mode == CompileAssemble) {
- fclose(out);
- filename_o = outname;
- } else {
- FILE *tempf = make_temp_file(temp, sizeof(temp), "cco");
- fclose(tempf);
- filename_o = temp;
- }
-
- assemble(filename_o, filename);
-
- size_t len = strlen(filename_o) + 1;
- filename = obstack_copy(&file_obst, filename_o, len);
- filetype = FILETYPE_OBJECT;
- }
-
- /* ok we're done here, process next file */
- file->name = filename;
- file->type = filetype;
- }
-