/* 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.
#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;
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))
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;
}
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);
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);
}
}
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
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
static char *
get_base_filename (filename)
- char *filename;
+ const char *filename;
{
char *p = getenv ("COLLECT_GCC_OPTIONS");
char *output = NULL;
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;
}
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);
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)
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);
}
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;
}
}