option was parsed twice
[cparser] / main.c
diff --git a/main.c b/main.c
index ff41e7d..462258e 100644 (file)
--- a/main.c
+++ b/main.c
@@ -72,7 +72,7 @@
 #include "driver/firm_opt.h"
 #include "driver/firm_cmdline.h"
 #include "driver/firm_timing.h"
-#include "driver/firm_os.h"
+#include "driver/firm_machine.h"
 #include "adt/error.h"
 #include "adt/strutil.h"
 #include "wrappergen/write_fluffy.h"
@@ -123,6 +123,7 @@ static struct obstack    ldflags_obst;
 static struct obstack    asflags_obst;
 static char              dep_target[1024];
 static const char       *outname;
+static bool              define_intmax_types;
 
 typedef enum lang_standard_t {
        STANDARD_DEFAULT, /* gnu99 (for C, GCC does gnu89) or gnu++98 (for C++) */
@@ -161,11 +162,6 @@ struct file_list_entry_t {
 
 static file_list_entry_t *temp_files;
 
-static void initialize_firm(void)
-{
-       firm_early_init();
-}
-
 static void get_output_name(char *buf, size_t buflen, const char *inputname,
                             const char *newext)
 {
@@ -288,6 +284,13 @@ static FILE *preprocess(const char *fname, filetype_t filetype)
                add_flag(&cppflags_obst, "-U__VERSION__");
                add_flag(&cppflags_obst, "-D__VERSION__=\"%s\"", cparser_REVISION);
 
+               if (define_intmax_types) {
+                       add_flag(&cppflags_obst, "-U__INTMAX_TYPE__");
+                       add_flag(&cppflags_obst, "-D__INTMAX_TYPE__=%s", type_to_string(type_intmax_t));
+                       add_flag(&cppflags_obst, "-U__UINTMAX_TYPE__");
+                       add_flag(&cppflags_obst, "-D__UINTMAX_TYPE__=%s", type_to_string(type_uintmax_t));
+               }
+
                if (flags[0] != '\0') {
                        size_t len = strlen(flags);
                        obstack_1grow(&cppflags_obst, ' ');
@@ -622,6 +625,7 @@ static bool init_os_support(void)
        wchar_atomic_kind         = ATOMIC_TYPE_INT;
        force_long_double_size    = 0;
        enable_main_collect2_hack = false;
+       define_intmax_types       = false;
 
        if (strstr(os, "linux") != NULL || strstr(os, "bsd") != NULL
                        || streq(os, "solaris")) {
@@ -629,6 +633,7 @@ static bool init_os_support(void)
        } else if (streq(os, "darwin")) {
                force_long_double_size = 16;
                set_create_ld_ident(create_name_macho);
+               define_intmax_types = true;
        } else if (strstr(os, "mingw") != NULL || streq(os, "win32")) {
                wchar_atomic_kind         = ATOMIC_TYPE_USHORT;
                enable_main_collect2_hack = true;
@@ -647,12 +652,20 @@ static bool parse_target_triple(const char *arg)
                fprintf(stderr, "Target-triple is not in the form 'cpu_type-manufacturer-operating_system'\n");
                return false;
        }
+       target_machine = triple;
        return true;
 }
 
+static void setup_target_machine(void)
+{
+       if (!setup_firm_for_machine(target_machine))
+               exit(1);
+       init_os_support();
+}
+
 int main(int argc, char **argv)
 {
-       initialize_firm();
+       firm_early_init();
 
        const char        *dumpfunction         = NULL;
        const char        *print_file_name_file = NULL;
@@ -664,6 +677,8 @@ int main(int argc, char **argv)
        file_list_entry_t *last_file            = NULL;
        bool               construct_dep_target = false;
        bool               do_timing            = false;
+       bool               profile_generate     = false;
+       bool               profile_use          = false;
        struct obstack     file_obst;
 
        atexit(free_temp_files);
@@ -717,8 +732,7 @@ int main(int argc, char **argv)
                target_machine = firm_get_host_machine();
        }
        choose_optimization_pack(opt_level);
-       setup_firm_for_machine(target_machine);
-       init_os_support();
+       setup_target_machine();
 
        /* parse rest of options */
        standard                   = STANDARD_DEFAULT;
@@ -829,9 +843,14 @@ int main(int argc, char **argv)
                                if (strstart(orig_opt, "input-charset=")) {
                                        char const* const encoding = strchr(orig_opt, '=') + 1;
                                        select_input_encoding(encoding);
-                               } else if (streq(orig_opt, "verbose-asm")) {
-                                       /* ignore: we always print verbose assembler */
+                               } else if (strstart(orig_opt, "align-loops=") ||
+                                          strstart(orig_opt, "align-jumps=") ||
+                                          strstart(orig_opt, "align-functions=")) {
+                                       fprintf(stderr, "ignoring gcc option '-f%s'\n", orig_opt);
+                               } else if (strstart(orig_opt, "message-length=")) {
+                                       /* ignore: would only affect error message format */
                                } else {
+                                       /* -f options which have an -fno- variant */
                                        char const *opt         = orig_opt;
                                        bool        truth_value = true;
                                        if (opt[0] == 'n' && opt[1] == 'o' && opt[2] == '-') {
@@ -857,19 +876,19 @@ int main(int argc, char **argv)
                                        } else if (streq(opt, "unsigned-char")) {
                                                char_is_signed = !truth_value;
                                        } else if (streq(opt, "freestanding")) {
-                                               freestanding = true;
+                                               freestanding = truth_value;
                                        } else if (streq(opt, "hosted")) {
-                                               freestanding = false;
-                                       } else if (truth_value == false &&
+                                               freestanding = !truth_value;
+                                       } else if (streq(opt, "profile-generate")) {
+                                               profile_generate = truth_value;
+                                       } else if (streq(opt, "profile-use")) {
+                                               profile_use = truth_value;
+                                       } else if (!truth_value &&
                                                   streq(opt, "asynchronous-unwind-tables")) {
                                            /* nothing todo, a gcc feature which we don't support
                                             * anyway was deactivated */
-                                       } else if (strstart(orig_opt, "align-loops=") ||
-                                                       strstart(orig_opt, "align-jumps=") ||
-                                                       strstart(orig_opt, "align-functions=")) {
-                                               fprintf(stderr, "ignoring gcc option '-f%s'\n", orig_opt);
-                                       } else if (strstart(orig_opt, "message-length=")) {
-                                                       /* ignore: would only affect error message format */
+                                       } else if (streq(orig_opt, "verbose-asm")) {
+                                               /* ignore: we always print verbose assembler */
                                        } else if (streq(opt, "fast-math")               ||
                                                   streq(opt, "jump-tables")             ||
                                                   streq(opt, "expensive-optimizations") ||
@@ -935,7 +954,7 @@ int main(int argc, char **argv)
                                        if (!parse_target_triple(opt)) {
                                                argument_errors = true;
                                        } else {
-                                               setup_firm_for_machine(target_machine);
+                                               setup_target_machine();
                                                target_triple = opt;
                                        }
                                } else if (strstart(opt, "triple=")) {
@@ -943,7 +962,7 @@ int main(int argc, char **argv)
                                        if (!parse_target_triple(opt)) {
                                                argument_errors = true;
                                        } else {
-                                               setup_firm_for_machine(target_machine);
+                                               setup_target_machine();
                                                target_triple = opt;
                                        }
                                } else if (strstart(opt, "arch=")) {
@@ -1025,8 +1044,6 @@ int main(int argc, char **argv)
                        } else if (streq(option, "pedantic") ||
                                   streq(option, "ansi")) {
                                fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
-                       } else if (streq(option, "shared")) {
-                               add_flag(&ldflags_obst, "-shared");
                        } else if (strstart(option, "std=")) {
                                const char *const o = &option[4];
                                standard =
@@ -1140,6 +1157,7 @@ int main(int argc, char **argv)
                                                        streq(suffix, "S")   ? FILETYPE_ASSEMBLER              :
                                                        streq(suffix, "a")   ? FILETYPE_OBJECT                 :
                                                        streq(suffix, "c")   ? FILETYPE_C                      :
+                                                       streq(suffix, "i")   ? FILETYPE_PREPROCESSED_C         :
                                                        streq(suffix, "C")   ? FILETYPE_CXX                    :
                                                        streq(suffix, "cc")  ? FILETYPE_CXX                    :
                                                        streq(suffix, "cp")  ? FILETYPE_CXX                    :
@@ -1147,7 +1165,7 @@ int main(int argc, char **argv)
                                                        streq(suffix, "CPP") ? FILETYPE_CXX                    :
                                                        streq(suffix, "cxx") ? FILETYPE_CXX                    :
                                                        streq(suffix, "c++") ? FILETYPE_CXX                    :
-                                                       streq(suffix, "ii")  ? FILETYPE_CXX                    :
+                                                       streq(suffix, "ii")  ? FILETYPE_PREPROCESSED_CXX       :
                                                        streq(suffix, "h")   ? FILETYPE_C                      :
                                                        streq(suffix, "ir")  ? FILETYPE_IR                     :
                                                        streq(suffix, "o")   ? FILETYPE_OBJECT                 :
@@ -1191,9 +1209,16 @@ int main(int argc, char **argv)
                return EXIT_FAILURE;
        }
 
-       /* set the c_mode here, types depends on it */
+       /* apply some effects from switches */
        c_mode |= features_on;
        c_mode &= ~features_off;
+       if (profile_generate) {
+               add_flag(&ldflags_obst, "-lfirmprof");
+               set_be_option("profilegenerate");
+       }
+       if (profile_use) {
+               set_be_option("profileuse");
+       }
 
        gen_firm_init();
        byte_order_big_endian = be_get_backend_param()->byte_order_big_endian;