VLA test
[cparser] / main.c
diff --git a/main.c b/main.c
index 086d82e..b7b0684 100644 (file)
--- a/main.c
+++ b/main.c
@@ -83,6 +83,12 @@ bool char_is_signed = true;
 /** true for strict language checking. */
 bool strict_mode = false;
 
+/* to switch on printing of implicit casts */
+extern bool print_implicit_casts;
+
+/* to switch on printing of  srenthesis to indicate operator precedence */
+extern bool print_parenthesis;
+
 static int            verbose;
 static struct obstack cppflags_obst, ldflags_obst;
 
@@ -162,6 +168,7 @@ static void lextest(FILE *in, const char *fname)
 static FILE* preprocess(FILE* in, const char *fname)
 {
        char buf[4096];
+       obstack_1grow(&cppflags_obst, '\0');
        const char *flags = obstack_finish(&cppflags_obst);
 
        if(in != stdin) {
@@ -185,6 +192,7 @@ static FILE* preprocess(FILE* in, const char *fname)
 static void do_link(const char *out, const char *in)
 {
        char buf[4096];
+       obstack_1grow(&ldflags_obst, '\0');
        const char *flags = obstack_finish(&ldflags_obst);
 
        snprintf(buf, sizeof(buf), LINKER " %s -o %s %s", flags, out, in);
@@ -310,6 +318,7 @@ void lower_compound_params(void)
 }
 
 typedef enum compile_mode_t {
+       BenchmarkParser,
        ParseOnly,
        Compile,
        CompileDump,
@@ -333,6 +342,7 @@ int main(int argc, char **argv)
        const char     *outname      = NULL;
        const char     *dumpfunction = NULL;
        compile_mode_t  mode         = CompileAssembleLink;
+       int             opt_level    = 1;
 
        obstack_init(&cppflags_obst);
        obstack_init(&ldflags_obst);
@@ -356,6 +366,43 @@ int main(int argc, char **argv)
 
 #define SINGLE_OPTION(ch) (option[0] == (ch) && option[1] == '\0')
 
+       /* early options parsing (find out optimisation level) */
+       for(int i = 1; i < argc; ++i) {
+               const char *arg = argv[i];
+               if(arg[0] != '-')
+                       continue;
+
+               const char *option = &arg[1];
+               if(option[0] == 'O') {
+                       sscanf(&option[1], "%d", &opt_level);
+               }
+       }
+
+       /* apply optimisation level */
+       switch(opt_level) {
+       case 0:
+               firm_option("no-opt");
+               break;
+       case 1:
+               firm_option("no-inline");
+               break;
+       default:
+       case 4:
+               firm_option("strict-aliasing");
+               /* fallthrough */
+       case 3:
+               firm_option("cond-eval");
+               firm_option("if-conv");
+               /* fallthrough */
+       case 2:
+               firm_option("inline");
+               firm_option("no-strength-red");
+               firm_option("deconv");
+               firm_be_option("omitfp");
+               break;
+       }
+
+       /* parse rest of options */
        bool help_displayed  = false;
        bool argument_errors = false;
        for(int i = 1; i < argc; ++i) {
@@ -365,10 +412,16 @@ int main(int argc, char **argv)
                        const char *option = &arg[1];
                        if(option[0] == 'o') {
                                GET_ARG_AFTER(outname, "-o");
+                       } else if(option[0] == 'g') {
+                               firm_be_option("stabs=yes");
+                               firm_be_option("omitfp=no");
+                               firm_be_option("ia32-nooptcc=yes");
                        } else if(SINGLE_OPTION('c')) {
                                mode = CompileAssemble;
                        } else if(SINGLE_OPTION('S')) {
                                mode = Compile;
+                       } else if(option[0] == 'O') {
+                               continue;
                        } else if(option[0] == 'I') {
                                const char *opt;
                                GET_ARG_AFTER(opt, "-I");
@@ -451,9 +504,7 @@ int main(int argc, char **argv)
                                }
                        } else if(strcmp(option, "pedantic") == 0) {
                                fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
-                       } else if(option[0] == 'O' ||
-                                 option[0] == 'g' ||
-                                 strncmp(option, "std=", 4) == 0) {
+                       } else if(strncmp(option, "std=", 4) == 0) {
                                fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
                        } else if (option[0] == '-') {
                                /* double dash option */
@@ -474,8 +525,14 @@ int main(int argc, char **argv)
                                        strict_mode = true;
                                } else if(strcmp(option, "lextest") == 0) {
                                        mode = LexTest;
+                               } else if(strcmp(option, "benchmark") == 0) {
+                                       mode = BenchmarkParser;
                                } else if(strcmp(option, "print-ast") == 0) {
                                        mode = PrintAst;
+                               } else if(strcmp(option, "print-implicit-cast") == 0) {
+                                       print_implicit_casts = true;
+                               } else if(strcmp(option, "print-parenthesis") == 0) {
+                                       print_parenthesis = true;
                                } else if(strcmp(option, "print-fluffy") == 0) {
                                        mode = PrintFluffy;
                                } else if(strcmp(option, "version") == 0) {
@@ -546,6 +603,7 @@ int main(int argc, char **argv)
        char  outnamebuf[4096];
        if(outname == NULL) {
                switch(mode) {
+               case BenchmarkParser:
                case PrintAst:
                case PrintFluffy:
                case LexTest:
@@ -622,6 +680,10 @@ int main(int argc, char **argv)
                fprintf(stderr, "%u warning(s)\n", warning_count);
        }
 
+       if(mode == BenchmarkParser) {
+               return 0;
+       }
+
        if(mode == PrintAst) {
                type_set_output(out);
                ast_set_output(out);