⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 search.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Breadth-first and depth-first routines for   searching multiple-inheritance lattice for GNU C++.   Copyright (C) 1987, 89, 92, 93, 94, 1995 Free Software Foundation, Inc.   Contributed by Michael Tiemann (tiemann@cygnus.com)This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* High-level class interface. */#include "config.h"#include "tree.h"#include <stdio.h>#include "cp-tree.h"#include "obstack.h"#include "flags.h"#include "rtl.h"#include "output.h"#define obstack_chunk_alloc xmalloc#define obstack_chunk_free freevoid init_search ();extern struct obstack *current_obstack;extern tree abort_fndecl;#include "stack.h"/* Obstack used for remembering decision points of breadth-first.  */static struct obstack search_obstack;/* Methods for pushing and popping objects to and from obstacks.  */struct stack_level *push_stack_level (obstack, tp, size)     struct obstack *obstack;     char *tp;  /* Sony NewsOS 5.0 compiler doesn't like void * here.  */     int size;{  struct stack_level *stack;  obstack_grow (obstack, tp, size);  stack = (struct stack_level *) ((char*)obstack_next_free (obstack) - size);  obstack_finish (obstack);  stack->obstack = obstack;  stack->first = (tree *) obstack_base (obstack);  stack->limit = obstack_room (obstack) / sizeof (tree *);  return stack;}struct stack_level *pop_stack_level (stack)     struct stack_level *stack;{  struct stack_level *tem = stack;  struct obstack *obstack = tem->obstack;  stack = tem->prev;  obstack_free (obstack, tem);  return stack;}#define search_level stack_levelstatic struct search_level *search_stack;static tree lookup_field_1 ();static int lookup_fnfields_1 ();static void dfs_walk ();static int markedp ();static void dfs_unmark ();static void dfs_init_vbase_pointers ();static tree vbase_types;static tree vbase_decl, vbase_decl_ptr;static tree vbase_decl_ptr_intermediate;static tree vbase_init_result;/* Allocate a level of searching.  */static struct search_level *push_search_level (stack, obstack)     struct stack_level *stack;     struct obstack *obstack;{  struct search_level tem;  tem.prev = stack;  return push_stack_level (obstack, (char *)&tem, sizeof (tem));}/* Discard a level of search allocation.  */static struct search_level *pop_search_level (obstack)     struct stack_level *obstack;{  register struct search_level *stack = pop_stack_level (obstack);  return stack;}/* Search memoization.  */struct type_level{  struct stack_level base;  /* First object allocated in obstack of entries.  */  char *entries;  /* Number of types memoized in this context.  */  int len;  /* Type being memoized; save this if we are saving     memoized contexts.  */  tree type;};/* Obstack used for memoizing member and member function lookup.  */static struct obstack type_obstack, type_obstack_entries;static struct type_level *type_stack;static tree _vptr_name;/* Make things that look like tree nodes, but allocate them   on type_obstack_entries.  */static int my_tree_node_counter;static tree my_tree_cons (), my_build_string ();extern int flag_memoize_lookups, flag_save_memoized_contexts;/* Variables for gathering statistics.  */static int my_memoized_entry_counter;static int memoized_fast_finds[2], memoized_adds[2], memoized_fast_rejects[2];static int memoized_fields_searched[2];static int n_fields_searched;static int n_calls_lookup_field, n_calls_lookup_field_1;static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1;static int n_calls_get_base_type;static int n_outer_fields_searched;static int n_contexts_saved;/* Local variables to help save memoization contexts.  */static tree prev_type_memoized;static struct type_level *prev_type_stack;/* This list is used by push_class_decls to know what decls need to   be pushed into class scope.  */static tree closed_envelopes = NULL_TREE;/* Allocate a level of type memoization context.  */static struct type_level *push_type_level (stack, obstack)     struct stack_level *stack;     struct obstack *obstack;{  struct type_level tem;  tem.base.prev = stack;  obstack_finish (&type_obstack_entries);  tem.entries = (char *) obstack_base (&type_obstack_entries);  tem.len = 0;  tem.type = NULL_TREE;  return (struct type_level *)push_stack_level (obstack, (char *)&tem, sizeof (tem));}/* Discard a level of type memoization context.  */static struct type_level *pop_type_level (stack)     struct type_level *stack;{  obstack_free (&type_obstack_entries, stack->entries);  return (struct type_level *)pop_stack_level ((struct stack_level *)stack);}/* Make something that looks like a TREE_LIST, but   do it on the type_obstack_entries obstack.  */static treemy_tree_cons (purpose, value, chain)     tree purpose, value, chain;{  tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_list));  ++my_tree_node_counter;  TREE_TYPE (p) = NULL_TREE;  ((HOST_WIDE_INT *)p)[3] = 0;  TREE_SET_CODE (p, TREE_LIST);  TREE_PURPOSE (p) = purpose;  TREE_VALUE (p) = value;  TREE_CHAIN (p) = chain;  return p;}static treemy_build_string (str)     char *str;{  tree p = (tree)obstack_alloc (&type_obstack_entries, sizeof (struct tree_string));  ++my_tree_node_counter;  TREE_TYPE (p) = 0;  ((int *)p)[3] = 0;  TREE_SET_CODE (p, STRING_CST);  TREE_STRING_POINTER (p) = str;  TREE_STRING_LENGTH (p) = strlen (str);  return p;}/* Memoizing machinery to make searches for multiple inheritance   reasonably efficient.  */#define MEMOIZE_HASHSIZE 8typedef struct memoized_entry{  struct memoized_entry *chain;  int uid;  tree data_members[MEMOIZE_HASHSIZE];  tree function_members[MEMOIZE_HASHSIZE];} *ME;#define MEMOIZED_CHAIN(ENTRY) (((ME)ENTRY)->chain)#define MEMOIZED_UID(ENTRY) (((ME)ENTRY)->uid)#define MEMOIZED_FIELDS(ENTRY,INDEX) (((ME)ENTRY)->data_members[INDEX])#define MEMOIZED_FNFIELDS(ENTRY,INDEX) (((ME)ENTRY)->function_members[INDEX])/* The following is probably a lousy hash function.  */#define MEMOIZED_HASH_FN(NODE) (((long)(NODE)>>4)&(MEMOIZE_HASHSIZE - 1))static struct memoized_entry *my_new_memoized_entry (chain)     struct memoized_entry *chain;{  struct memoized_entry *p =    (struct memoized_entry *)obstack_alloc (&type_obstack_entries,					    sizeof (struct memoized_entry));  bzero ((char *) p, sizeof (struct memoized_entry));  MEMOIZED_CHAIN (p) = chain;  MEMOIZED_UID (p) = ++my_memoized_entry_counter;  return p;}/* Make an entry in the memoized table for type TYPE   that the entry for NAME is FIELD.  */treemake_memoized_table_entry (type, name, function_p)     tree type, name;     int function_p;{  int index = MEMOIZED_HASH_FN (name);  tree entry, *prev_entry;  memoized_adds[function_p] += 1;  if (CLASSTYPE_MTABLE_ENTRY (type) == 0)    {      obstack_ptr_grow (&type_obstack, type);      obstack_blank (&type_obstack, sizeof (struct memoized_entry *));      CLASSTYPE_MTABLE_ENTRY (type) = (char *)my_new_memoized_entry ((struct memoized_entry *)0);      type_stack->len++;      if (type_stack->len * 2 >= type_stack->base.limit)	my_friendly_abort (88);    }  if (function_p)    prev_entry = &MEMOIZED_FNFIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);  else    prev_entry = &MEMOIZED_FIELDS (CLASSTYPE_MTABLE_ENTRY (type), index);  entry = my_tree_cons (name, NULL_TREE, *prev_entry);  *prev_entry = entry;  /* Don't know the error message to give yet.  */  TREE_TYPE (entry) = error_mark_node;  return entry;}/* When a new function or class context is entered, we build   a table of types which have been searched for members.   The table is an array (obstack) of types.  When a type is   entered into the obstack, its CLASSTYPE_MTABLE_ENTRY   field is set to point to a new record, of type struct memoized_entry.   A non-NULL TREE_TYPE of the entry contains an access control error message.   The slots for the data members are arrays of tree nodes.   These tree nodes are lists, with the TREE_PURPOSE   of this list the known member name, and the TREE_VALUE   as the FIELD_DECL for the member.   For member functions, the TREE_PURPOSE is again the   name of the member functions for that class,   and the TREE_VALUE of the list is a pairs   whose TREE_PURPOSE is a member functions of this name,   and whose TREE_VALUE is a list of known argument lists this   member function has been called with.  The TREE_TYPE of the pair,   if non-NULL, is an error message to print.  *//* Tell search machinery that we are entering a new context, and   to update tables appropriately.   TYPE is the type of the context we are entering, which can   be NULL_TREE if we are not in a class's scope.   USE_OLD, if nonzero tries to use previous context.  */voidpush_memoized_context (type, use_old)     tree type;     int use_old;{  int len;  tree *tem;  if (prev_type_stack)    {      if (use_old && prev_type_memoized == type)	{#ifdef GATHER_STATISTICS	  n_contexts_saved++;#endif	  type_stack = prev_type_stack;	  prev_type_stack = 0;	  tem = &type_stack->base.first[0];	  len = type_stack->len;	  while (len--)	    CLASSTYPE_MTABLE_ENTRY (tem[len*2]) = (char *)tem[len*2+1];	  return;	}      /* Otherwise, need to pop old stack here.  */      type_stack = pop_type_level (prev_type_stack);      prev_type_memoized = 0;      prev_type_stack = 0;    }  type_stack = push_type_level ((struct stack_level *)type_stack,				&type_obstack);  type_stack->type = type;}/* Tell search machinery that we have left a context.   We do not currently save these contexts for later use.   If we wanted to, we could not use pop_search_level, since   poping that level allows the data we have collected to   be clobbered; a stack of obstacks would be needed.  */voidpop_memoized_context (use_old)     int use_old;{  int len;  tree *tem = &type_stack->base.first[0];  if (! flag_save_memoized_contexts)    use_old = 0;  else if (use_old)    {      len = type_stack->len;      while (len--)	tem[len*2+1] = (tree)CLASSTYPE_MTABLE_ENTRY (tem[len*2]);      prev_type_stack = type_stack;      prev_type_memoized = type_stack->type;    }  if (flag_memoize_lookups)    {      len = type_stack->len;      while (len--)	CLASSTYPE_MTABLE_ENTRY (tem[len*2])	  = (char *)MEMOIZED_CHAIN (CLASSTYPE_MTABLE_ENTRY (tem[len*2]));    }  if (! use_old)    type_stack = pop_type_level (type_stack);  else    type_stack = (struct type_level *)type_stack->base.prev;}/* Get a virtual binfo that is found inside BINFO's hierarchy that is   the same type as the type given in PARENT.  To be optimal, we want   the first one that is found by going through the least number of   virtual bases.  DEPTH should be NULL_PTR.  */static treeget_vbase (parent, binfo, depth)     tree parent, binfo;     unsigned int *depth;{  tree binfos;  int i, n_baselinks;  tree rval = NULL_TREE;  if (depth == 0)    {      unsigned int d = (unsigned int)-1;      return get_vbase (parent, binfo, &d);    }  if (BINFO_TYPE (binfo) == parent && TREE_VIA_VIRTUAL (binfo))    {      *depth = 0;      return binfo;    }  *depth = *depth - 1;  binfos = BINFO_BASETYPES (binfo);  n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0;  /* Process base types.  */  for (i = 0; i < n_baselinks; i++)    {      tree base_binfo = TREE_VEC_ELT (binfos, i);      tree nrval;      if (*depth == 0)	break;      nrval = get_vbase (parent, base_binfo, depth);      if (nrval)	rval = nrval;    }  *depth = *depth+1;  return rval;}/* Convert EXPR to a virtual base class of type TYPE.  We know that   EXPR is a non-null POINTER_TYPE to RECORD_TYPE.  We also know that   the type of what expr points to has a virtual base of type TYPE.  */treeconvert_pointer_to_vbase (type, expr)     tree type;     tree expr;{  tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))), NULL_PTR);  return convert_pointer_to_real (vb, expr);}/* This is the newer recursive depth first search routine. */#if 0				/* unused *//* Return non-zero if PARENT is directly derived from TYPE.  By directly   we mean it's only one step up the inheritance lattice.  We check this   by walking horizontally across the types that TYPE directly inherits   from, to see if PARENT is among them.  This is used by get_binfo and   by compute_access.  */static intimmediately_derived (parent, type)     tree parent, type;{  if (TYPE_BINFO (type))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -