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

📄 class.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Functions related to building classes and their related objects.   Copyright (C) 1996, 97-98, 1999 Free Software Foundation, Inc.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.Java and all Java-based marks are trademarks or registered trademarksof Sun Microsystems, Inc. in the United States and other countries.The Free Software Foundation is independent of Sun Microsystems, Inc.  *//* Written by Per Bothner <bothner@cygnus.com> */#include "config.h"#include "system.h"#include "tree.h"#include "rtl.h"#include "flags.h"#include "java-tree.h"#include "jcf.h"#include "obstack.h"#include "toplev.h"#include "output.h"#include "parse.h"static tree mangle_class_field PROTO ((tree class));static tree make_method_value PROTO ((tree));static tree build_java_method_type PROTO ((tree, tree, int));static int32 hashUtf8String PROTO ((const char *, int));static tree make_field_value PROTO ((tree));static tree get_dispatch_vector PROTO ((tree));static tree get_dispatch_table PROTO ((tree, tree));static void append_gpp_mangled_type PROTO ((struct obstack *, tree));static tree mangle_static_field PROTO ((tree));static rtx registerClass_libfunc;extern struct obstack permanent_obstack;extern struct obstack temporary_obstack;/* Return an IDENTIFIER_NODE the same as (OLD_NAME, OLD_LENGTH).   except that characters matching OLD_CHAR are substituted by NEW_CHAR.   Also, PREFIX is prepended, and SUFFIX is appended. */treeident_subst (old_name, old_length, prefix, old_char, new_char, suffix)     const char* old_name;     int old_length;     const char *prefix;     int old_char;     int new_char;     const char *suffix;{  int prefix_len = strlen (prefix);  int suffix_len = strlen (suffix);  int i = prefix_len + old_length + suffix_len + 1;#ifdef __GNUC__  char buffer[i];#else  char *buffer = (char *)alloca  (i);#endif  strcpy (buffer, prefix);  for (i = 0; i < old_length; i++)    {      char ch = old_name[i];      if (ch == old_char)	ch = new_char;      buffer[prefix_len + i] = ch;    }  strcpy (buffer + prefix_len + old_length, suffix);  return get_identifier (buffer);}/* Return an IDENTIFIER_NODE the same as OLD_ID,   except that characters matching OLD_CHAR are substituted by NEW_CHAR.   Also, PREFIX is prepended, and SUFFIX is appended. */treeidentifier_subst (old_id, prefix, old_char, new_char, suffix)     const tree old_id;     const char *prefix;     int old_char;     int new_char;     const char *suffix;{  return ident_subst (IDENTIFIER_POINTER (old_id), IDENTIFIER_LENGTH (old_id),		      prefix, old_char, new_char, suffix);}/* Generate a valid C identifier from the name of the class TYPE,   prefixed by PREFIX. */treemangled_classname (prefix, type)  const char *prefix;  tree type;{  tree ident = TYPE_NAME (type);  if (TREE_CODE (ident) != IDENTIFIER_NODE)    ident = DECL_NAME (ident);  return identifier_subst (ident, prefix, '.', '_', "");}treemake_class (){  tree type;  push_obstacks (&permanent_obstack, &permanent_obstack);  type = make_node (RECORD_TYPE);#ifdef JAVA_USE_HANDLES  tree field1 = build_decl (FIELD_DECL, get_identifier ("obj"),			    build_pointer_type (type));  tree field2 = build_decl (FIELD_DECL, get_identifier ("methods"),			    methodtable_ptr_type);  tree handle_type = make_node (RECORD_TYPE);  TREE_CHAIN (field1) = field2;  TYPE_FIELDS (handle_type) = field1;  TYPE_BINFO (type) = make_tree_vec (7);  TYPE_BINFO (handle_type) = make_tree_vec (7);  BINFO_HANDLE (TYPE_BINFO (handle_type)) = type;  BINFO_HANDLE (TYPE_BINFO (type)) = handle_type;#else  TYPE_BINFO (type) = make_tree_vec (6);#endif  pop_obstacks ();  return type;}/* Given a fully-qualified classname in NAME (whose length is NAME_LENGTH),   and where each of the constituents is separated by '/',   return a corresponding IDENTIFIER_NODE, except using '.' as separator. */treeunmangle_classname (name, name_length)     const char *name;  int name_length;{  tree to_return = ident_subst (name, name_length, "", '/', '.', "");  /* It's not sufficient to compare to_return and get_identifier     (name) to determine whether to_return is qualified. There are     cases in signature analysis where name will be stripped of a     trailing ';'. */  name = IDENTIFIER_POINTER (to_return);  while (*name)    if (*name++ == '.')       {	QUALIFIED_P (to_return) = 1;	break;      }    return to_return;}treepush_class (class_type, class_name)     tree class_type, class_name;{  tree decl, signature;  char *save_input_filename = input_filename;  int save_lineno = lineno;  tree source_name = identifier_subst (class_name, "", '.', '/', ".java");  push_obstacks (&permanent_obstack, &permanent_obstack);  CLASS_P (class_type) = 1;  input_filename = IDENTIFIER_POINTER (source_name);  lineno = 0;  decl = build_decl (TYPE_DECL, class_name, class_type);  input_filename = save_input_filename;  lineno = save_lineno;  signature = identifier_subst (class_name, "L", '.', '/', ";");  IDENTIFIER_SIGNATURE_TYPE (signature) = build_pointer_type (class_type);  /* Setting DECL_ARTIFICAL forces dbxout.c to specific the type is     both a typedef and in the struct name-space.  We may want to re-visit     this later, but for now it reduces the changes needed for gdb. */  DECL_ARTIFICIAL (decl) = 1;  pushdecl_top_level (decl);#ifdef JAVA_USE_HANDLES  {    tree handle_name = identifier_subst (class_name,					 "Handle$", '.', '.', "");    tree handle_decl = build_decl (TYPE_DECL, handle_name,				   CLASS_TO_HANDLE_TYPE (class_type));    pushdecl (handle_decl);  }#endif  pop_obstacks ();  return decl;}/* Finds the (global) class named NAME.  Creates the class if not found.   Also creates associated TYPE_DECL.   Does not check if the class actually exists, load the class,   fill in field or methods, or do layout_type. */treelookup_class (name)     tree name;{  tree decl = IDENTIFIER_CLASS_VALUE (name);  if (decl == NULL_TREE)    decl = push_class (make_class (), name);  return TREE_TYPE (decl);}voidset_super_info (access_flags, this_class, super_class, interfaces_count)     int access_flags;     tree this_class;     tree super_class;     int interfaces_count;{  int total_supers = interfaces_count;  tree class_decl = TYPE_NAME (this_class);  if (super_class)    total_supers++;  push_obstacks (&permanent_obstack, &permanent_obstack);  TYPE_BINFO_BASETYPES (this_class) = make_tree_vec (total_supers);  if (super_class)    {      tree super_binfo = make_tree_vec (6);      BINFO_TYPE (super_binfo) = super_class;      BINFO_OFFSET (super_binfo) = integer_zero_node;      TREE_VIA_PUBLIC (super_binfo) = 1;      TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (this_class)), 0)	= super_binfo;      CLASS_HAS_SUPER (this_class) = 1;    }  pop_obstacks ();    if (access_flags & ACC_PUBLIC)    CLASS_PUBLIC (class_decl) = 1;  if (access_flags & ACC_FINAL)     CLASS_FINAL (class_decl) = 1;  if (access_flags & ACC_SUPER)     CLASS_SUPER (class_decl) = 1;  if (access_flags & ACC_INTERFACE) CLASS_INTERFACE (class_decl) = 1;  if (access_flags & ACC_ABSTRACT)  CLASS_ABSTRACT (class_decl) = 1;}/* Return length of inheritance chain of CLAS, where java.lang.Object is 0,   direct sub-classes of Object are 1, and so on. */intclass_depth (clas)     tree clas;{  int depth = 0;  if (! CLASS_LOADED_P (clas))    load_class (clas, 1);  while (clas != object_type_node)    {      depth++;      clas = TYPE_BINFO_BASETYPE (clas, 0);    }  return depth;}/* Return true iff TYPE2 is an interface that extends interface TYPE1 */intinterface_of_p (type1, type2)     tree type1, type2;{  int n, i;  tree basetype_vec;  if (!(basetype_vec = TYPE_BINFO_BASETYPES (type2)))    return 0;  n = TREE_VEC_LENGTH (basetype_vec);  for (i = 0; i < n; i++)    {      tree vec_elt = TREE_VEC_ELT (basetype_vec, i);      if (vec_elt && BINFO_TYPE (vec_elt) == type1)	return 1;    }  for (i = 0; i < n; i++)    {      tree vec_elt = TREE_VEC_ELT (basetype_vec, i);      if (vec_elt && BINFO_TYPE (vec_elt) 	  && interface_of_p (type1, BINFO_TYPE (vec_elt)))	return 1;    }  return 0;}/* Return true iff TYPE1 inherits from TYPE2. */intinherits_from_p (type1, type2)     tree type1, type2;{  while (type1 != NULL_TREE && TREE_CODE (type1) == RECORD_TYPE)    {      if (type1 == type2)	return 1;      type1 = CLASSTYPE_SUPER (type1);    }  return 0;}static voidadd_interface_do (basetype_vec, interface_class, i)     tree basetype_vec, interface_class;     int i;{  tree interface_binfo = make_tree_vec (6);  BINFO_TYPE (interface_binfo) = interface_class;  BINFO_OFFSET (interface_binfo) = integer_zero_node;  TREE_VIA_VIRTUAL (interface_binfo) = 1;  TREE_VIA_PUBLIC (interface_binfo) = 1;  TREE_VEC_ELT (basetype_vec, i) = interface_binfo;}/* Add INTERFACE_CLASS to THIS_CLASS iff INTERFACE_CLASS can't be   found in THIS_CLASS. Returns NULL_TREE upon success, INTERFACE_CLASS   if attempt is made to add it twice. */treemaybe_add_interface (this_class, interface_class)     tree this_class, interface_class;{  tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);  int i;  int n = TREE_VEC_LENGTH (basetype_vec);  for (i = 0; ; i++)    {      if (i >= n)	{	  error ("internal error - too many interface type");	  return NULL_TREE;	}      else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)	break;      else if (BINFO_TYPE (TREE_VEC_ELT (basetype_vec, i)) == interface_class)	return interface_class;    }   add_interface_do (basetype_vec, interface_class, i);  return NULL_TREE;}/* Add the INTERFACE_CLASS as one of the interfaces of THIS_CLASS. */voidadd_interface (this_class, interface_class)     tree this_class, interface_class;{  tree basetype_vec = TYPE_BINFO_BASETYPES (this_class);  int i;  int n = TREE_VEC_LENGTH (basetype_vec);  for (i = 0; ; i++)    {      if (i >= n)	{	  error ("internal error - too many interface type");	  return;	}      else if (TREE_VEC_ELT (basetype_vec, i) == NULL_TREE)	break;    }  add_interface_do (basetype_vec, interface_class, i);}#if 0/* Return the address of a pointer to the first FUNCTION_DECL   in the list (*LIST) whose DECL_NAME is NAME. */static tree *find_named_method (list, name)     tree *list;     tree name;{  while (*list && DECL_NAME (*list) != name)    list = &TREE_CHAIN (*list);  return list;}#endifstatic treebuild_java_method_type (fntype, this_class, access_flags)     tree fntype;     tree this_class;     int access_flags;{  if (access_flags & ACC_STATIC)    return fntype;  return build_method_type (CLASS_TO_HANDLE_TYPE (this_class), fntype);}treeadd_method_1 (handle_class, access_flags, name, function_type)     tree handle_class;     int access_flags;     tree name;     tree function_type;{  tree method_type, fndecl;  push_obstacks (&permanent_obstack, &permanent_obstack);  method_type = build_java_method_type (function_type,					handle_class, access_flags);  fndecl = build_decl (FUNCTION_DECL, name, method_type);  DECL_CONTEXT (fndecl) = handle_class;  DECL_LANG_SPECIFIC (fndecl)    = (struct lang_decl *) permalloc (sizeof (struct lang_decl));  bzero ((PTR) DECL_LANG_SPECIFIC (fndecl), sizeof (struct lang_decl));  TREE_CHAIN (fndecl) = TYPE_METHODS (handle_class);  TYPE_METHODS (handle_class) = fndecl;  pop_obstacks ();  if (access_flags & ACC_PUBLIC) METHOD_PUBLIC (fndecl) = 1;  if (access_flags & ACC_PROTECTED) METHOD_PROTECTED (fndecl) = 1;  if (access_flags & ACC_PRIVATE) METHOD_PRIVATE (fndecl) = 1;  if (access_flags & ACC_NATIVE) METHOD_NATIVE (fndecl) = 1;  if (access_flags & ACC_STATIC) METHOD_STATIC (fndecl) = 1;  if (access_flags & ACC_FINAL) METHOD_FINAL (fndecl) = 1;  if (access_flags & ACC_SYNCHRONIZED) METHOD_SYNCHRONIZED (fndecl) = 1;  if (access_flags & ACC_ABSTRACT) METHOD_ABSTRACT (fndecl) = 1;  if (access_flags & ACC_TRANSIENT) METHOD_TRANSIENT (fndecl) = 1;  return fndecl;}/* Add a method to THIS_CLASS.   The method's name is NAME.   Its signature (mangled type) is METHOD_SIG (an IDENTIFIER_NODE). */

⌨️ 快捷键说明

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