OSDN Git Service

Add - before rms to be more portable.
[pf3gnuchains/gcc-fork.git] / gcc / cp / repo.c
index 6927fcf..8feab83 100644 (file)
@@ -1,5 +1,5 @@
 /* Code to maintain a C++ template repository.
-   Copyright (C) 1995, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1995, 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
    Contributed by Jason Merrill (jason@cygnus.com)
 
 This file is part of GNU CC.
@@ -32,15 +32,14 @@ Boston, MA 02111-1307, USA.  */
 #include "input.h"
 #include "obstack.h"
 #include "toplev.h"
+#include "ggc.h"
 
-extern char *getpwd PROTO((void));
-
-static tree repo_get_id PROTO((tree));
-static char *extract_string PROTO((char **));
-static char *get_base_filename PROTO((char *));
-static void open_repo_file PROTO((char *));
-static char *afgets PROTO((FILE *));
-static void reopen_repo_file_for_write PROTO((void));
+static tree repo_get_id PARAMS ((tree));
+static char *extract_string PARAMS ((char **));
+static 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 tree pending_repo;
 static tree original_repo;
@@ -50,8 +49,7 @@ static FILE *repo_file;
 static char *old_args, *old_dir, *old_main;
 
 extern int flag_use_repository;
-extern int errorcount, sorrycount;
-extern struct obstack temporary_obstack;
+static struct obstack temporary_obstack;
 extern struct obstack permanent_obstack;
 
 #define IDENTIFIER_REPO_USED(NODE)   (TREE_LANG_FLAG_3 (NODE))
@@ -97,9 +95,38 @@ 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))
+       my_friendly_abort (981113);
+
+      vtable = get_vtbl_decl_for_binfo (TYPE_BINFO (t));
+
+      /* If we don't have a primary vtable, try looking for a secondary
+        vtable.  */
+      if (vtable == NULL_TREE && !flag_new_abi
+         && TYPE_USES_VIRTUAL_BASECLASSES (t))
+       {
+         tree binfos = BINFO_BASETYPES (TYPE_BINFO (t));
+         int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;
+         for (i = 0; i < n_baselinks; ++i)
+           {
+             tree base_binfo = TREE_VEC_ELT (binfos, i);
+             if (TREE_VIA_VIRTUAL (base_binfo))
+               {
+                 vtable = get_vtbl_decl_for_binfo (base_binfo);
+                 if (vtable)
+                   break;
+               }
+           }
+       }
+
+      t = vtable;
       if (t == NULL_TREE)
        return t;
     }
@@ -122,12 +149,12 @@ 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);
@@ -138,7 +165,7 @@ repo_template_used (t)
   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);
     }
 }
 
@@ -152,7 +179,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
@@ -166,13 +193,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
@@ -233,7 +261,7 @@ extract_string (pp)
 
 static char *
 get_base_filename (filename)
-     char *filename;
+     const char *filename;
 {
   char *p = getenv ("COLLECT_GCC_OPTIONS");
   char *output = NULL;
@@ -254,7 +282,7 @@ get_base_filename (filename)
 
   if (p && ! compiling)
     {
-      cp_warning (ec_frepo_must_be_used_with_c);
+      warning ("-frepo must be used with -c");
       flag_use_repository = 0;
       return NULL;
     }
@@ -264,16 +292,16 @@ get_base_filename (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 = file_name_nondirectory (s);
-  p = rindex (p, '.');
+  p = strrchr (p, '.');
   if (! p)
     p = s + strlen (s);
 
@@ -298,13 +326,17 @@ afgets (stream)
 
 void
 init_repo (filename)
-     char *filename;
+     const char *filename;
 {
   char *buf;
 
   if (! flag_use_repository)
     return;
 
+  ggc_add_tree_root (&pending_repo, 1);
+  ggc_add_tree_root (&original_repo, 1);
+  gcc_obstack_init (&temporary_obstack);
+
   open_repo_file (filename);
 
   if (repo_file == 0)
@@ -340,11 +372,11 @@ 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:
-         cp_error (ec_mysterious_repository_information_in_s, repo_name);
+         error ("mysterious repository information in %s", repo_name);
        }
       obstack_free (&temporary_obstack, buf);
     }
@@ -359,7 +391,7 @@ reopen_repo_file_for_write ()
 
   if (repo_file == 0)
     {
-      cp_error (ec_cant_create_repository_information_file_s, repo_name);
+      error ("can't create repository information file `%s'", repo_name);
       flag_use_repository = 0;
     }
 }