X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcp%2Frepo.c;h=64c6ec873fcc0e62248301186b42571a9bd9470a;hb=3e5d979595c5dd72ad98fdffb3deae78547b939b;hp=47a111bc00d466d6251450e6695572cf768106f8;hpb=96624a9e8a0220e125e50f65f0ef5945cc83ee72;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c index 47a111bc00d..64c6ec873fc 100644 --- a/gcc/cp/repo.c +++ b/gcc/cp/repo.c @@ -1,5 +1,5 @@ /* Code to maintain a C++ template repository. - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. Contributed by Jason Merrill (jason@cygnus.com) This file is part of GNU CC. @@ -25,26 +25,31 @@ Boston, MA 02111-1307, USA. */ The results of the automatic process should be easily reproducible with explicit code. */ -#include #include "config.h" +#include "system.h" #include "tree.h" #include "cp-tree.h" #include "input.h" #include "obstack.h" - -extern char * rindex (); -extern char * getenv (); -extern char * getpwd (); - -static tree pending_repo; -static tree original_repo; +#include "toplev.h" +#include "ggc.h" +#include "diagnostic.h" + +static tree repo_get_id PARAMS ((tree)); +static char *extract_string PARAMS ((char **)); +static const char *get_base_filename PARAMS ((const char *)); +static void open_repo_file PARAMS ((const char *)); +static char *afgets PARAMS ((FILE *)); +static void reopen_repo_file_for_write PARAMS ((void)); + +static GTY(()) tree pending_repo; +static GTY(()) tree original_repo; static char *repo_name; static FILE *repo_file; -extern int flag_use_repository; -extern int errorcount, sorrycount; -extern struct obstack temporary_obstack; -extern struct obstack permanent_obstack; +static const char *old_args, *old_dir, *old_main; + +static struct obstack temporary_obstack; #define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE)) #define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE)) @@ -89,9 +94,19 @@ static tree repo_get_id (t) tree t; { - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') + if (TYPE_P (t)) { - t = TYPE_BINFO_VTABLE (t); + tree vtable; + + /* If we're not done setting up the class, we may not have set up + the vtable, so going ahead would give the wrong answer. + See g++.pt/instantiate4.C. */ + if (!COMPLETE_TYPE_P (t) || TYPE_BEING_DEFINED (t)) + abort (); + + vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (t)); + + t = vtable; if (t == NULL_TREE) return t; } @@ -114,23 +129,29 @@ repo_template_used (t) if (id == NULL_TREE) return; - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') + if (TYPE_P (t)) { if (IDENTIFIER_REPO_CHOSEN (id)) mark_class_instantiated (t, 0); } - else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd') + else if (DECL_P (t)) { if (IDENTIFIER_REPO_CHOSEN (id)) - mark_decl_instantiated (t, 0); + /* It doesn't make sense to instantiate a clone, so we + instantiate the cloned function instead. Note that this + approach will not work correctly if collect2 assigns + different clones to different files -- but it shouldn't. */ + mark_decl_instantiated (DECL_CLONED_FUNCTION_P (t) + ? DECL_CLONED_FUNCTION (t) : t, + 0); } else - my_friendly_abort (1); + abort (); if (! IDENTIFIER_REPO_USED (id)) { IDENTIFIER_REPO_USED (id) = 1; - pending_repo = perm_tree_cons (NULL_TREE, id, pending_repo); + pending_repo = tree_cons (NULL_TREE, id, pending_repo); } } @@ -144,7 +165,7 @@ repo_vtable_used (t) if (! flag_use_repository) return; - pending_repo = perm_tree_cons (NULL_TREE, t, pending_repo); + pending_repo = tree_cons (NULL_TREE, t, pending_repo); } /* Note that an inline with external linkage has been used, and offer to @@ -158,13 +179,14 @@ repo_inline_used (fn) return; /* Member functions of polymorphic classes go with their vtables. */ - if (DECL_FUNCTION_MEMBER_P (fn) && TYPE_VIRTUAL_P (DECL_CLASS_CONTEXT (fn))) + if (DECL_FUNCTION_MEMBER_P (fn) + && TYPE_POLYMORPHIC_P (DECL_CONTEXT (fn))) { - repo_vtable_used (DECL_CLASS_CONTEXT (fn)); + repo_vtable_used (DECL_CONTEXT (fn)); return; } - pending_repo = perm_tree_cons (NULL_TREE, fn, pending_repo); + pending_repo = tree_cons (NULL_TREE, fn, pending_repo); } /* Note that a particular typeinfo node has been used, and offer to @@ -190,43 +212,55 @@ repo_template_instantiated (t, extern_p) } } +/* Parse a reasonable subset of shell quoting syntax. */ + static char * -save_string (s, len) - char *s; - int len; +extract_string (pp) + char **pp; { - return obstack_copy0 (&temporary_obstack, s, len); + char *p = *pp; + int backquote = 0; + int inside = 0; + + for (;;) + { + char c = *p; + if (c == '\0') + break; + ++p; + if (backquote) + obstack_1grow (&temporary_obstack, c); + else if (! inside && c == ' ') + break; + else if (! inside && c == '\\') + backquote = 1; + else if (c == '\'') + inside = !inside; + else + obstack_1grow (&temporary_obstack, c); + } + + obstack_1grow (&temporary_obstack, '\0'); + *pp = p; + return obstack_finish (&temporary_obstack); } -static char * +const char * get_base_filename (filename) - char *filename; + const char *filename; { char *p = getenv ("COLLECT_GCC_OPTIONS"); - char *output = 0; + char *output = NULL; int compiling = 0; - if (p) - while (*p) - { - char *q = p; - while (*q && *q != ' ') q++; - if (*p == '-' && p[1] == 'o') - { - p += 2; - if (p == q) - { - p++; q++; - if (*q) - while (*q && *q != ' ') q++; - } + while (p && *p) + { + char *q = extract_string (&p); - output = save_string (p, q - p); - } - else if (*p == '-' && p[1] == 'c') - compiling = 1; - if (*q) q++; - p = q; + if (strcmp (q, "-o") == 0) + output = extract_string (&p); + else if (strcmp (q, "-c") == 0) + compiling = 1; } if (compiling && output) @@ -239,32 +273,27 @@ get_base_filename (filename) return NULL; } - p = rindex (filename, '/'); - if (p) - return p+1; - else - return filename; + return lbasename (filename); } static void open_repo_file (filename) - char *filename; + const char *filename; { - register char *p; - char *s = get_base_filename (filename); + register const char *p; + const char *s = get_base_filename (filename); if (s == NULL) return; - p = rindex (s, '/'); - if (! p) - p = s; - p = rindex (p, '.'); + p = lbasename (s); + p = strrchr (p, '.'); if (! p) p = s + strlen (s); - obstack_grow (&permanent_obstack, s, p - s); - repo_name = obstack_copy0 (&permanent_obstack, ".rpo", 4); + repo_name = xmalloc (p - s + 5); + memcpy (repo_name, s, p - s); + memcpy (repo_name + (p - s), ".rpo", 5); repo_file = fopen (repo_name, "r"); } @@ -284,25 +313,32 @@ afgets (stream) void init_repo (filename) - char *filename; + const char *filename; { char *buf; if (! flag_use_repository) return; + gcc_obstack_init (&temporary_obstack); + open_repo_file (filename); if (repo_file == 0) return; - while (buf = afgets (repo_file)) + while ((buf = afgets (repo_file))) { switch (buf[0]) { case 'A': + old_args = ggc_strdup (buf + 2); + break; case 'D': + old_dir = ggc_strdup (buf + 2); + break; case 'M': + old_main = ggc_strdup (buf + 2); break; case 'C': case 'O': @@ -318,7 +354,7 @@ init_repo (filename) else orig = NULL_TREE; - original_repo = perm_tree_cons (orig, id, original_repo); + original_repo = tree_cons (orig, id, original_repo); } break; default: @@ -348,8 +384,8 @@ void finish_repo () { tree t; - char *p; int repo_changed = 0; + char *dir, *args; if (! flag_use_repository) return; @@ -382,6 +418,16 @@ finish_repo () } } + dir = getpwd (); + args = getenv ("COLLECT_GCC_OPTIONS"); + + if (! repo_changed && pending_repo) + if (strcmp (old_main, main_input_filename) != 0 + || strcmp (old_dir, dir) != 0 + || (args == NULL) != (old_args == NULL) + || (args && strcmp (old_args, args) != 0)) + repo_changed = 1; + if (! repo_changed || errorcount || sorrycount) goto out; @@ -391,13 +437,9 @@ finish_repo () goto out; fprintf (repo_file, "M %s\n", main_input_filename); - - p = getpwd (); - fprintf (repo_file, "D %s\n", p); - - p = getenv ("COLLECT_GCC_OPTIONS"); - if (p != 0) - fprintf (repo_file, "A %s\n", p); + fprintf (repo_file, "D %s\n", dir); + if (args) + fprintf (repo_file, "A %s\n", args); for (t = pending_repo; t; t = TREE_CHAIN (t)) { @@ -411,3 +453,5 @@ finish_repo () if (repo_file) fclose (repo_file); } + +#include "gt-cp-repo.h"