Slightly simplify creating an ident from a string on an obstack.
[cparser] / main.c
diff --git a/main.c b/main.c
index f583c08..b3a9065 100644 (file)
--- a/main.c
+++ b/main.c
 #define fdopen(fd, mode)         _fdopen(fd, mode)
 #define popen(cmd, mode)         _popen(cmd, mode)
 #define pclose(file)             _pclose(file)
+#define unlink(filename)         _unlink(filename)
 
 #else
 #include <unistd.h>
 #define HAVE_MKSTEMP
 #endif
 
-#ifndef WITH_LIBCORE
-#define WITH_LIBCORE
-#endif
-
 #include <libfirm/firm.h>
 #include <libfirm/be.h>
 
@@ -68,6 +65,7 @@
 #include "types.h"
 #include "type_hash.h"
 #include "parser.h"
+#include "type_t.h"
 #include "ast2firm.h"
 #include "diagnostic.h"
 #include "lang_features.h"
 #include "write_caml.h"
 #include "revision.h"
 #include "warning.h"
+#include "mangle.h"
 
 #ifndef PREPROCESSOR
 #ifdef __APPLE__
-#define PREPROCESSOR "gcc -E -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int -U__SIZE_TYPE__ -D__SIZE_TYPE__=unsigned\\ long -m32 -U__STRICT_ANSI__"
+#define PREPROCESSOR "gcc -E -std=c99 -m32 -U__STRICT_ANSI__"
 #else
-#define PREPROCESSOR "cpp -std=c99 -U__WCHAR_TYPE__ -D__WCHAR_TYPE__=int -U__SIZE_TYPE__ -D__SIZE_TYPE__=unsigned\\ long -m32 -U__STRICT_ANSI__"
+#define PREPROCESSOR "cpp -std=c99 -m32 -U__STRICT_ANSI__"
 #endif
 #endif
 
 #endif
 
 /** The current c mode/dialect. */
-lang_features_t c_mode;
+unsigned int c_mode = _C89 | _ANSI | _C99 | _GNUC;
 
 /** The 'machine size', 16, 32 or 64 bit, 32bit is the default. */
 unsigned int machine_size = 32;
@@ -117,6 +116,8 @@ bool use_builtins = false;
 /** we have extern function with const attribute. */
 bool have_const_functions = false;
 
+atomic_type_kind_t wchar_atomic_kind = ATOMIC_TYPE_INT;
+
 /* to switch on printing of implicit casts */
 extern bool print_implicit_casts;
 
@@ -143,11 +144,13 @@ typedef enum filetype_t {
 } filetype_t;
 
 struct file_list_entry_t {
-       const char        *name; /**< filename or NULL for stdin */
-       filetype_t         type;
+       const char  *name; /**< filename or NULL for stdin */
+       filetype_t   type;
        file_list_entry_t *next;
 };
 
+static file_list_entry_t *temp_files;
+
 #if defined(_DEBUG) || defined(FIRM_DEBUG)
 /**
  * Debug printf implementation.
@@ -266,12 +269,27 @@ static void add_flag(struct obstack *obst, const char *format, ...)
        va_end(ap);
 }
 
+static const char *type_to_string(type_t *type)
+{
+       assert(type->kind == TYPE_ATOMIC);
+       return get_atomic_kind_name(type->atomic.akind);
+}
+
 static FILE *preprocess(const char *fname)
 {
        obstack_1grow(&cppflags_obst, '\0');
        const char *flags = obstack_finish(&cppflags_obst);
 
        obstack_printf(&cppflags_obst, "%s", PREPROCESSOR);
+
+       /* setup default defines */
+       add_flag(&cppflags_obst, "-U__WCHAR_TYPE__");
+       add_flag(&cppflags_obst, "-D__WCHAR_TYPE__=%s",
+                type_to_string(type_wchar_t));
+       add_flag(&cppflags_obst, "-U__SIZE_TYPE__");
+       add_flag(&cppflags_obst, "-D__SIZE_TYPE__=%s", type_to_string(type_size_t));
+
+       /* handle dependency generation */
        if (dep_target[0] != '\0') {
                add_flag(&cppflags_obst, "-MF");
                add_flag(&cppflags_obst, "%s", dep_target);
@@ -388,9 +406,34 @@ static FILE *make_temp_file(char *buffer, size_t buflen, const char *prefix)
                exit(1);
        }
 
+       file_list_entry_t *entry = xmalloc(sizeof(*entry));
+       memset(entry, 0, sizeof(*entry));
+
+       size_t  name_len = strlen(buffer) + 1;
+       char   *name     = malloc(name_len);
+       memcpy(name, buffer, name_len);
+       entry->name      = name;
+
+       entry->next = temp_files;
+       temp_files  = entry;
+
        return out;
 }
 
+static void free_temp_files(void)
+{
+       file_list_entry_t *entry = temp_files;
+       file_list_entry_t *next;
+       for ( ; entry != NULL; entry = next) {
+               next = entry->next;
+
+               unlink(entry->name);
+               free((char*) entry->name);
+               free(entry);
+       }
+       temp_files = NULL;
+}
+
 /**
  * Do the necessary lowering for compound parameters.
  */
@@ -514,6 +557,25 @@ static filetype_t get_filetype_from_string(const char *string)
        return FILETYPE_UNKNOWN;
 }
 
+static void init_os_support(void)
+{
+       /* OS option must be set to the backend */
+       switch (firm_opt.os_support) {
+       case OS_SUPPORT_MINGW:
+               set_be_option("ia32-gasmode=mingw");
+               wchar_atomic_kind = ATOMIC_TYPE_USHORT;
+               break;
+       case OS_SUPPORT_LINUX:
+               set_be_option("ia32-gasmode=elf");
+               break;
+       case OS_SUPPORT_MACHO:
+               set_be_option("ia32-gasmode=macho");
+               set_be_option("ia32-stackalign=4");
+               set_be_option("pic");
+               break;
+       }
+}
+
 typedef enum lang_standard_t {
        STANDARD_DEFAULT, /* gnu99 (for C, GCC does gnu89) or gnu++98 (for C++) */
        STANDARD_ANSI,    /* c89 (for C) or c++98 (for C++) */
@@ -540,6 +602,14 @@ int main(int argc, char **argv)
        bool               construct_dep_target = false;
        struct obstack     file_obst;
 
+       atexit(free_temp_files);
+
+       /* hack for now... */
+       if (strstr(argv[0], "pptest") != NULL) {
+               extern int pptest_main(int argc, char **argv);
+               return pptest_main(argc, argv);
+       }
+
        obstack_init(&cppflags_obst);
        obstack_init(&ldflags_obst);
        obstack_init(&file_obst);
@@ -563,18 +633,28 @@ 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) {
+       /* early options parsing (find out optimisation level and OS) */
+       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') {
+               if (option[0] == 'O') {
                        sscanf(&option[1], "%d", &opt_level);
                }
+               if (strcmp(arg, "-fwin32") == 0) {
+                       firm_opt.os_support = OS_SUPPORT_MINGW;
+               } else if (strcmp(arg, "-fmac") == 0) {
+                       firm_opt.os_support = OS_SUPPORT_MACHO;
+               } else if (strcmp(arg, "-flinux") == 0) {
+                       firm_opt.os_support = OS_SUPPORT_LINUX;
+               }
        }
 
+       /* set target/os specific stuff */
+       init_os_support();
+
        /* apply optimisation level */
        switch(opt_level) {
        case 0:
@@ -599,15 +679,10 @@ int main(int argc, char **argv)
                break;
        }
 
-#ifdef __APPLE__
-       /* Darwin expects the stack to be aligned to 16byte boundary */
-       firm_be_option("ia32-stackalign=4");
-#endif
-
        /* parse rest of options */
        lang_standard_t standard        = STANDARD_DEFAULT;
-       lang_features_t features_on     = 0;
-       lang_features_t features_off    = 0;
+       unsigned        features_on     = 0;
+       unsigned        features_off    = 0;
        filetype_t      forced_filetype = FILETYPE_AUTODETECT;
        bool            help_displayed  = false;
        bool            argument_errors = false;
@@ -702,7 +777,8 @@ int main(int argc, char **argv)
                                        } if (streq(opt, "builtins")) {
                                                use_builtins = truth_value;
                                        } else if (streq(opt, "short-wchar")) {
-                                               opt_short_wchar_t = truth_value;
+                                               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")) {
@@ -833,6 +909,7 @@ int main(int argc, char **argv)
                        } else if (strstart(option, "std=")) {
                                const char *const o = &option[4];
                                standard =
+                                       streq(o, "c++")            ? STANDARD_CXX98   :
                                        streq(o, "c++98")          ? STANDARD_CXX98   :
                                        streq(o, "c89")            ? STANDARD_C89     :
                                        streq(o, "c99")            ? STANDARD_C99     :
@@ -976,6 +1053,7 @@ int main(int argc, char **argv)
        init_ast();
        init_parser();
        init_ast2firm();
+       init_mangle();
 
        if (construct_dep_target) {
                if (outname != 0 && strlen(outname) >= 2) {
@@ -1294,6 +1372,7 @@ do_parsing:
        obstack_free(&ldflags_obst, NULL);
        obstack_free(&file_obst, NULL);
 
+       exit_mangle();
        exit_ast2firm();
        exit_parser();
        exit_ast();