/*
* This file is part of cparser.
- * Copyright (C) 2007-2008 Matthias Braun <matze@braunis.de>
+ * Copyright (C) 2007-2009 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
#include "driver/firm_opt.h"
#include "driver/firm_cmdline.h"
#include "adt/error.h"
-#include "write_fluffy.h"
-#include "write_caml.h"
+#include "wrappergen/write_fluffy.h"
+#include "wrappergen/write_caml.h"
+#include "wrappergen/write_jna.h"
#include "revision.h"
#include "warning.h"
#include "mangle.h"
FILETYPE_ASSEMBLER,
FILETYPE_PREPROCESSED_ASSEMBLER,
FILETYPE_OBJECT,
+ FILETYPE_IR,
FILETYPE_UNKNOWN
} filetype_t;
static void get_output_name(char *buf, size_t buflen, const char *inputname,
const char *newext)
{
- size_t last_dot = 0xffffffff;
- size_t i = 0;
-
- if (inputname == NULL) {
- snprintf(buf, buflen, "a%s", newext);
- return;
- }
-
- for (const char *c = inputname; *c != 0; ++c) {
- if (*c == '.')
- last_dot = i;
- ++i;
- }
- if (last_dot == 0xffffffff)
- last_dot = i;
-
- if (last_dot >= buflen)
- panic("filename too long");
- memcpy(buf, inputname, last_dot);
-
- size_t extlen = strlen(newext) + 1;
- if (extlen + last_dot >= buflen)
+ if (inputname == NULL)
+ inputname = "a";
+
+ char const *const last_slash = strrchr(inputname, '/');
+ char const *const filename =
+ last_slash != NULL ? last_slash + 1 : inputname;
+ char const *const last_dot = strrchr(filename, '.');
+ char const *const name_end =
+ last_dot != NULL ? last_dot : strchr(filename, '\0');
+
+ int const len = snprintf(buf, buflen, "%.*s%s",
+ (int)(name_end - filename), filename, newext);
+#ifdef _WIN32
+ if (len < 0 || buflen <= (size_t)len)
+#else
+ if (buflen <= (size_t)len)
+#endif
panic("filename too long");
- memcpy(buf+last_dot, newext, extlen);
}
#include "builtins.h"
static void add_flag(struct obstack *obst, const char *format, ...)
{
- char buf[4096];
+ char buf[65536];
va_list ap;
va_start(ap, format);
add_flag(&cppflags_obst, "-U__SIZE_TYPE__");
add_flag(&cppflags_obst, "-D__SIZE_TYPE__=%s", type_to_string(type_size_t));
- /* hack... */
+ /* TODO hack... */
+ add_flag(&cppflags_obst, "-D__builtin_abort=abort");
+ add_flag(&cppflags_obst, "-D__builtin_abs=abs");
+ add_flag(&cppflags_obst, "-D__builtin_exit=exit");
+ add_flag(&cppflags_obst, "-D__builtin_malloc=malloc");
+ add_flag(&cppflags_obst, "-D__builtin_memcmp=memcmp");
add_flag(&cppflags_obst, "-D__builtin_memcpy=memcpy");
+ add_flag(&cppflags_obst, "-D__builtin_memset=memset");
+ add_flag(&cppflags_obst, "-D__builtin_strlen=strlen");
+ add_flag(&cppflags_obst, "-D__builtin_strcmp=strcmp");
+ add_flag(&cppflags_obst, "-D__builtin_strcpy=strcpy");
/* handle dependency generation */
if (dep_target[0] != '\0') {
}
}
if (flags[0] != '\0') {
- obstack_printf(&cppflags_obst, " %s", flags);
+ size_t len = strlen(flags);
+ obstack_1grow(&cppflags_obst, ' ');
+ obstack_grow(&cppflags_obst, flags, len);
}
add_flag(&cppflags_obst, fname);
static void assemble(const char *out, const char *in)
{
- char buf[4096];
+ char buf[65536];
snprintf(buf, sizeof(buf), "%s %s -o %s", ASSEMBLER, in, out);
if (verbose) {
ParseOnly,
Compile,
CompileDump,
+ CompileExportIR,
CompileAssemble,
CompileAssembleLink,
LexTest,
PrintAst,
PrintFluffy,
- PrintCaml
+ PrintCaml,
+ PrintJna
} compile_mode_t;
static void usage(const char *argv0)
fprintf(stderr, "Usage %s input [-o output] [-c]\n", argv0);
}
-static void print_cparser_version(void) {
- firm_version_t ver;
- firm_get_version(&ver);
-
+static void print_cparser_version(void)
+{
printf("cparser (%s) using libFirm (%u.%u",
- cparser_REVISION, ver.major, ver.minor);
- if (ver.revision[0] != 0) {
+ cparser_REVISION, ir_get_version_major(),
+ ir_get_version_minor());
+
+ const char *revision = ir_get_version_revision();
+ if (revision[0] != 0) {
putchar(' ');
- fputs(ver.revision, stdout);
+ fputs(revision, stdout);
}
- if (ver.build[0] != 0) {
+
+ const char *build = ir_get_version_build();
+ if (build[0] != 0) {
putchar(' ');
- fputs(ver.build, stdout);
+ fputs(build, stdout);
}
- puts(")\n");
+ puts(")");
+ puts("This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
}
static void set_be_option(const char *arg)
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, "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 {
opt += 3;
}
- if (streq(opt, "dollars-in-identifiers")) {
- allow_dollar_in_symbol = truth_value;
- } if (streq(opt, "builtins")) {
+ if (streq(opt, "builtins")) {
use_builtins = truth_value;
+ } else if (streq(opt, "dollars-in-identifiers")) {
+ allow_dollar_in_symbol = truth_value;
+ } else if (streq(opt, "omit-frame-pointer")) {
+ set_be_option(truth_value ? "omitfp" : "omitfp=no");
} else if (streq(opt, "short-wchar")) {
wchar_atomic_kind = truth_value ? ATOMIC_TYPE_USHORT
: ATOMIC_TYPE_INT;
- } else if (streq(opt, "syntax-only")) {
- mode = truth_value ? ParseOnly : CompileAssembleLink;
- } else if (streq(opt, "omit-frame-pointer")) {
- set_be_option(truth_value ? "omitfp" : "omitfp=no");
+ } else if (streq(opt, "signed-char")) {
+ char_is_signed = truth_value;
} else if (streq(opt, "strength-reduce")) {
firm_option(truth_value ? "strength-red" : "no-strength-red");
+ } else if (streq(opt, "syntax-only")) {
+ mode = truth_value ? ParseOnly : CompileAssembleLink;
+ } else if (streq(opt, "unsigned-char")) {
+ char_is_signed = !truth_value;
} else if (streq(opt, "fast-math") ||
streq(opt, "jump-tables") ||
streq(opt, "unroll-loops") ||
set_be_option("omitleaffp=1");
} else if (streq(opt, "no-omit-leaf-frame-pointer")) {
set_be_option("omitleaffp=0");
+ } else if (streq(opt, "rtd")) {
+ default_calling_convention = CC_STDCALL;
} else {
char *endptr;
long int value = strtol(opt, &endptr, 10);
} else if (streq(option, "no-ms")) {
features_on &= ~_MS;
features_off |= _MS;
- } else if (streq(option, "signed-chars")) {
- char_is_signed = true;
- } else if (streq(option, "unsigned-chars")) {
- char_is_signed = false;
} else if (streq(option, "strict")) {
strict_mode = true;
} else if (streq(option, "lextest")) {
mode = PrintFluffy;
} else if (streq(option, "print-caml")) {
mode = PrintCaml;
+ } else if (streq(option, "print-jna")) {
+ mode = PrintJna;
} else if (streq(option, "version")) {
print_cparser_version();
exit(EXIT_SUCCESS);
}
dumpfunction = argv[i];
mode = CompileDump;
+ } else if (streq(option, "export-ir")) {
+ mode = CompileExportIR;
} else {
fprintf(stderr, "error: unknown argument '%s'\n", arg);
argument_errors = true;
streq(suffix, "cpp") ? FILETYPE_CXX :
streq(suffix, "cxx") ? FILETYPE_CXX :
streq(suffix, "h") ? FILETYPE_C :
+ streq(suffix, "ir") ? FILETYPE_IR :
streq(suffix, "o") ? FILETYPE_OBJECT :
streq(suffix, "s") ? FILETYPE_PREPROCESSED_ASSEMBLER :
streq(suffix, "so") ? FILETYPE_OBJECT :
/* we do the lowering in ast2firm */
firm_opt.lower_bitfields = FALSE;
+ /* set the c_mode here, types depends on it */
+ c_mode |= features_on;
+ c_mode &= ~features_off;
+
gen_firm_init();
init_symbol_table();
init_types();
case PrintAst:
case PrintFluffy:
case PrintCaml:
+ case PrintJna:
case LexTest:
case PreprocessOnly:
case ParseOnly:
".vcg");
outname = outnamebuf;
break;
+ case CompileExportIR:
+ get_output_name(outnamebuf, sizeof(outnamebuf), filename, ".ir");
+ outname = outnamebuf;
+ break;
case CompileAssembleLink:
#ifdef _WIN32
outname = "a.exe";
switch (standard) {
case STANDARD_ANSI:
case STANDARD_C89: c_mode = _C89; break;
- /* TODO ^v determine difference between these two */
+ /* 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;
do_parsing:
c_mode |= features_on;
c_mode &= ~features_off;
+
init_tokens();
translation_unit_t *const unit = do_parsing(in, filename);
} else if (mode == PrintCaml) {
write_caml_decls(out, unit);
continue;
+ } else if (mode == PrintJna) {
+ write_jna_decls(out, unit);
+ continue;
}
translation_unit_to_firm(unit);
+graph_built:
if (mode == ParseOnly) {
continue;
}
exit(0);
}
+ if (mode == CompileExportIR) {
+ fclose(out);
+ ir_export(outname);
+ exit(0);
+ }
+
gen_firm_finish(asm_out, filename, /*c_mode=*/1,
have_const_functions);
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) {