#include "warning.h"
#ifndef PREPROCESSOR
-#define PREPROCESSOR "cpp -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int -U__SIZE_TYPE__ -D__SIZE_TYPE__=__SIZE_TYPE__ -m32"
+#define PREPROCESSOR "cpp -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int -U__SIZE_TYPE__ -D__SIZE_TYPE__=__SIZE_TYPE__ -m32 -U__STRICT_ANSI__"
#endif
#ifndef LINKER
typedef struct file_list_entry_t file_list_entry_t;
typedef enum filetype_t {
+ FILETYPE_AUTODETECT,
FILETYPE_C,
FILETYPE_PREPROCESSED_C,
FILETYPE_ASSEMBLER,
return in;
}
+static filetype_t get_filetype_from_string(const char *string)
+{
+ if (strcmp(string, "c") == 0 || strcmp(string, "c-header") == 0)
+ return FILETYPE_C;
+ if (strcmp(string, "assembler") == 0)
+ return FILETYPE_PREPROCESSED_ASSEMBLER;
+ if (strcmp(string, "assembler-with-cpp") == 0)
+ return FILETYPE_ASSEMBLER;
+ if (strcmp(string, "none") == 0)
+ return FILETYPE_AUTODETECT;
+
+ return FILETYPE_UNKNOWN;
+}
+
int main(int argc, char **argv)
{
initialize_firm();
}
/* parse rest of options */
- bool help_displayed = false;
- bool argument_errors = false;
+ filetype_t forced_filetype = FILETYPE_AUTODETECT;
+ bool help_displayed = false;
+ bool argument_errors = false;
for(int i = 1; i < argc; ++i) {
const char *arg = argv[i];
if(arg[0] == '-' && arg[1] != 0) {
verbose = 1;
} else if(SINGLE_OPTION('w')) {
inhibit_all_warnings = true;
+ } else if(option[0] == 'x') {
+ const char *opt;
+ GET_ARG_AFTER(opt, "-x");
+ forced_filetype = get_filetype_from_string(opt);
+ if (forced_filetype == FILETYPE_UNKNOWN) {
+ fprintf(stderr, "Unknown language '%s'\n", opt);
+ argument_errors = true;
+ }
} else if(strcmp(option, "M") == 0) {
mode = PreprocessOnly;
add_flag(&cppflags_obst, "-M");
- } else if(strcmp(option, "MMD") == 0
- || strcmp(option, "MD") == 0
- || strcmp(option, "MM") == 0) {
+ } else if (strcmp(option, "MMD") == 0 ||
+ strcmp(option, "MD") == 0 ||
+ strcmp(option, "MM") == 0 ||
+ strcmp(option, "MP") == 0) {
add_flag(&cppflags_obst, "-%s", option);
} else if(strcmp(option, "MT") == 0
|| strcmp(option, "MQ") == 0
add_flag(&cppflags_obst, "%s", opt);
} else if(strcmp(option, "pipe") == 0) {
/* here for gcc compatibility */
- } else if(option[0] == 'f') {
+ } else if (option[0] == 'f') {
+ bool truth_value = true;
const char *opt;
GET_ARG_AFTER(opt, "-f");
+ if (opt[0] == 'n' && opt[1] == 'o' && opt[2] == '-') {
+ truth_value = false;
+ opt += 3;
+ }
- if(strcmp(opt, "syntax-only") == 0) {
+ if (strcmp(opt, "dollars-in-identifiers") == 0) {
+ allow_dollar_in_symbol = truth_value;
+ } else if (strcmp(opt, "short-wchar") == 0) {
+ opt_short_wchar_t = truth_value;
+ } else if (strcmp(opt, "syntax-only") == 0) {
mode = ParseOnly;
} else if(strcmp(opt, "omit-frame-pointer") == 0) {
- set_be_option("omitfp");
- } else if(strcmp(opt, "no-omit-frame-pointer") == 0) {
- set_be_option("omitfp=no");
+ set_be_option(truth_value ? "omitfp" : "omitfp=no");
} else if(strcmp(opt, "strength-reduce") == 0) {
firm_option("strength-red");
- } else if(strcmp(opt, "fast-math") == 0
+ } else if (strcmp(opt, "fast-math") == 0
+ || strcmp(opt, "jump-tables") == 0
|| strcmp(opt, "unroll-loops") == 0
|| strcmp(opt, "expensive-optimizations") == 0
|| strcmp(opt, "no-common") == 0
+ || strcmp(opt, "PIC") == 0
|| strncmp(opt, "align-loops=", sizeof("align-loops=")-1) == 0
|| strncmp(opt, "align-jumps=", sizeof("align-jumps=")-1) == 0
|| strncmp(opt, "align-functions=", sizeof("align-functions=")-1) == 0) {
- fprintf(stderr, "ignoring gcc option '-f %s'\n", opt);
+ fprintf(stderr, "ignoring gcc option '-f %s'\n", truth_value ? opt : opt - 3);
} else {
+ if (! truth_value)
+ opt -= 3;
int res = firm_option(opt);
if (res == 0) {
fprintf(stderr, "error: unknown Firm option '-f %s'\n",
help_displayed = true;
}
}
- } else if(option[0] == 'b') {
+ } else if (option[0] == 'b') {
const char *opt;
GET_ARG_AFTER(opt, "-b");
int res = firm_be_option(opt);
if (strncmp(opt, "isa=", 4) == 0)
strncpy(cpu_arch, opt, sizeof(cpu_arch));
}
- } else if(option[0] == 'W') {
- set_warning_opt(&option[1]);
+ } else if (option[0] == 'W') {
+ if (strncmp(option + 1, "l,", 2) == 0) // a gcc-style linker option
+ {
+ const char *opt;
+ GET_ARG_AFTER(opt, "-Wl,");
+ add_flag(&ldflags_obst, "-Wl,%s", opt);
+ }
+ else set_warning_opt(&option[1]);
} else if(option[0] == 'm') {
/* -m options */
const char *opt;
char arch_opt[64];
GET_ARG_AFTER(opt, "-m");
- if(strncmp(opt, "arch=", 5) == 0) {
+ if (strncmp(opt, "arch=", 5) == 0) {
GET_ARG_AFTER(opt, "-march=");
snprintf(arch_opt, sizeof(arch_opt), "%s-arch=%s", cpu_arch, opt);
int res = firm_be_option(arch_opt);
} else if(strcmp(option, "pg") == 0) {
set_be_option("gprof");
add_flag(&ldflags_obst, "-pg");
- } else if(strcmp(option, "pedantic") == 0) {
+ } else if(strcmp(option, "pedantic") == 0
+ || strcmp(option, "ansi") == 0) {
fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg);
} else if(strcmp(option, "shared") == 0) {
add_flag(&ldflags_obst, "-shared");
argument_errors = true;
}
} else {
- filetype_t type = FILETYPE_UNKNOWN;
- size_t len = strlen(arg);
+ filetype_t type = forced_filetype;
const char *filename = arg;
- if (len < 2 && arg[0] == '-') {
- /* - implicitely means C source file */
- type = FILETYPE_C;
- filename = NULL;
- } else if (len > 2 && arg[len-2] == '.') {
- switch(arg[len-1]) {
- case 'c': type = FILETYPE_C; break;
- case 'h': type = FILETYPE_C; break;
- case 's': type = FILETYPE_PREPROCESSED_ASSEMBLER; break;
- case 'S': type = FILETYPE_ASSEMBLER; break;
- case 'o': type = FILETYPE_OBJECT; break;
+ if (type == FILETYPE_AUTODETECT) {
+ size_t len = strlen(arg);
+ if (len < 2 && arg[0] == '-') {
+ /* - implicitly means C source file */
+ type = FILETYPE_C;
+ filename = NULL;
+ } else if (len > 2 && arg[len-2] == '.') {
+ switch(arg[len-1]) {
+ case 'c': type = FILETYPE_C; break;
+ case 'h': type = FILETYPE_C; break;
+ case 's': type = FILETYPE_PREPROCESSED_ASSEMBLER; break;
+ case 'S': type = FILETYPE_ASSEMBLER; break;
+
+ case 'a':
+ case 'o': type = FILETYPE_OBJECT; break;
+ }
+ } else if (len > 3 && arg[len-3] == '.') {
+ if(strcmp(arg + len - 2, "so") == 0) {
+ type = FILETYPE_OBJECT;
+ }
+ }
+
+ if (type == FILETYPE_AUTODETECT) {
+ fprintf(stderr, "'%s': file format not recognized\n", arg);
+ continue;
}
}
- if (type == FILETYPE_UNKNOWN) {
- fprintf(stderr, "'%s': file format not recognized\n", arg);
+ file_list_entry_t *entry
+ = obstack_alloc(&file_obst, sizeof(entry[0]));
+ memset(entry, 0, sizeof(entry[0]));
+ entry->name = arg;
+ entry->type = type;
+
+ if (last_file != NULL) {
+ last_file->next = entry;
} else {
- file_list_entry_t *entry
- = obstack_alloc(&file_obst, sizeof(entry[0]));
- memset(entry, 0, sizeof(entry[0]));
- entry->name = arg;
- entry->type = type;
-
- if (last_file != NULL) {
- last_file->next = entry;
- } else {
- files = entry;
- }
- last_file = entry;
+ files = entry;
}
+ last_file = entry;
}
}
if (in == preprocessed_in) {
int pp_result = pclose(preprocessed_in);
if (pp_result != EXIT_SUCCESS) {
- return pp_result;
+ exit(EXIT_FAILURE);
}
}
return pp_result;
}
}
+ if(asm_out != out) {
+ fclose(asm_out);
+ }
}
if (mode == Compile)
file->type = filetype;
}
+ if (result != EXIT_SUCCESS)
+ return result;
+
/* link program file */
if(mode == CompileAssembleLink) {
obstack_1grow(&ldflags_obst, '\0');