+/*
+ * This file is part of cparser.
+ * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ *
+ * 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 <config.h>
#define _GNU_SOURCE
/* to switch on printing of implicit casts */
extern bool print_implicit_casts;
-/* to switch on printing of srenthesis to indicate operator precedence */
+/* to switch on printing of parenthesis to indicate operator precedence */
extern bool print_parenthesis;
static int verbose;
const char *outname = NULL;
const char *dumpfunction = NULL;
compile_mode_t mode = CompileAssembleLink;
+ int opt_level = 1;
+ int result = EXIT_SUCCESS;
obstack_init(&cppflags_obst);
obstack_init(&ldflags_obst);
#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("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) {
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");
}
} 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 */
} else if(strcmp(option, "version") == 0) {
firm_version_t ver;
firm_get_version(&ver);
- printf("cparser (%d.%d %s) using libFirm (%u.%u", 0, 1, cparser_REVISION, ver.major, ver.minor);
+ printf("cparser (%s) using libFirm (%u.%u",
+ cparser_REVISION, ver.major, ver.minor);
if(ver.revision[0] != 0) {
putchar(' ');
fputs(ver.revision, stdout);
FILE *preprocessed_in = preprocess(in, input);
translation_unit_t *const unit = do_parsing(preprocessed_in, input);
- int result = pclose(preprocessed_in);
- if(result != 0) {
- return result;
+ int res = pclose(preprocessed_in);
+ if(res != 0) {
+ return res;
}
- if(unit == NULL) {
+
+ if(error_count > 0) {
/* parsing failed because of errors */
fprintf(stderr, "%u error(s), %u warning(s)\n", error_count, warning_count);
- return EXIT_FAILURE;
- }
- if (warning_count > 0) {
+ result = EXIT_FAILURE;
+ } else if(warning_count > 0) {
fprintf(stderr, "%u warning(s)\n", warning_count);
}
if(mode == BenchmarkParser) {
- return 0;
+ return result;
}
+ /* prints the AST even if errors occurred */
if(mode == PrintAst) {
type_set_output(out);
ast_set_output(out);
print_ast(unit);
- return 0;
+ return result;
}
+
+ /* cannot handle other modes with errors */
+ if(result != EXIT_SUCCESS)
+ return result;
+
if(mode == PrintFluffy) {
type_set_output(out);
ast_set_output(out);