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

📄 expr.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
     enum tree_code condition;     tree type;     int target_pc;{  tree value1, value2;  flush_quick_stack ();  /* note: pop values in opposite order */  value2 = pop_value (type);  value1 = pop_value (type);  /* Maybe should check value1 and value2 for type compatibility ??? */  expand_compare (condition, value1, value2, target_pc);}static voidexpand_java_goto (target_pc)     int target_pc;{  tree target_label = lookup_label (target_pc);  flush_quick_stack ();  expand_goto (target_label);}#if 0static voidexpand_java_call (target_pc, return_address)     int target_pc, return_address;{  tree target_label = lookup_label (target_pc);  tree value = build_int_2 (return_address, return_address < 0 ? -1 : 0);  push_value (value);  flush_quick_stack ();  expand_goto (target_label);}static voidexpand_java_ret (return_address)     tree return_address ATTRIBUTE_UNUSED;{  warning ("ret instruction not implemented");#if 0  tree target_label = lookup_label (target_pc);  flush_quick_stack ();  expand_goto (target_label);#endif}#endif/* Recursive helper function to pop argument types during verifiation. */voidpop_argument_types (arg_types)     tree arg_types;{  if (arg_types == end_params_node)    return;  if (TREE_CODE (arg_types) == TREE_LIST)    {      pop_argument_types (TREE_CHAIN (arg_types));      pop_type (TREE_VALUE (arg_types));      return;    }  abort ();}static treepop_arguments (arg_types)     tree arg_types;{  if (arg_types == end_params_node)    return NULL_TREE;  if (TREE_CODE (arg_types) == TREE_LIST)    {      tree tail = pop_arguments (TREE_CHAIN (arg_types));      tree type = TREE_VALUE (arg_types);      tree arg = pop_value (type);#ifdef PROMOTE_PROTOTYPES      if (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)	  && INTEGRAL_TYPE_P (type))	arg = convert (integer_type_node, arg);#endif      return tree_cons (NULL_TREE, arg, tail);    }  abort ();}/* Build an expression to initialize the class CLAS.   if EXPR is non-NULL, returns an expression to first call the initializer   (if it is needed) and then calls EXPR. */treebuild_class_init (clas, expr)     tree clas, expr;{  tree init;  if (inherits_from_p (current_class, clas))    return expr;  init = build (CALL_EXPR, void_type_node,		build_address_of (soft_initclass_node),		build_tree_list (NULL_TREE, build_class_ref (clas)),		NULL_TREE);  TREE_SIDE_EFFECTS (init) = 1;  if (expr != NULL_TREE)    {      expr = build (COMPOUND_EXPR, TREE_TYPE (expr), init, expr);      TREE_SIDE_EFFECTS (expr) = 1;      return expr;    }  return init;}static tree methods_ident = NULL_TREE;static tree ncode_ident = NULL_TREE;tree dtable_ident = NULL_TREE;treebuild_known_method_ref (method, method_type, self_type, method_signature, arg_list)     tree method, method_type ATTRIBUTE_UNUSED, self_type,          method_signature ATTRIBUTE_UNUSED, arg_list ATTRIBUTE_UNUSED;{  tree func;  if (is_compiled_class (self_type))    {      make_decl_rtl (method, NULL, 1);      func = build1 (ADDR_EXPR, method_ptr_type_node, method);    }  else    {      /* We don't know whether the method has been (statically) compiled.	 Compile this code to get a reference to the method's code:	 	 SELF_TYPE->methods[METHOD_INDEX].ncode	 	 This is guaranteed to work (assuming SELF_TYPE has	 been initialized), since if the method is not compiled yet,	 its ncode points to a trampoline that forces compilation. */            int method_index = 0;      tree meth;      tree ref = build_class_ref (self_type);      ref = build1 (INDIRECT_REF, class_type_node, ref);      if (ncode_ident == NULL_TREE)	ncode_ident = get_identifier ("ncode");      if (methods_ident == NULL_TREE)	methods_ident = get_identifier ("methods");      ref = build (COMPONENT_REF, method_ptr_type_node, ref,		   lookup_field (&class_type_node, methods_ident));      for (meth = TYPE_METHODS (CLASS_TO_HANDLE_TYPE (self_type));	   ; meth = TREE_CHAIN (meth))	{	  if (method == meth)	    break;	  if (meth == NULL_TREE)	    fatal ("method '%s' not found in class",		   IDENTIFIER_POINTER (DECL_NAME (method)));	  method_index++;	}      method_index *= int_size_in_bytes (method_type_node);      ref = fold (build (PLUS_EXPR, method_ptr_type_node,			 ref, build_int_2 (method_index, 0)));      ref = build1 (INDIRECT_REF, method_type_node, ref);      func = build (COMPONENT_REF, nativecode_ptr_type_node,		    ref,		    lookup_field (&method_type_node, ncode_ident));    }  return func;}treeinvoke_build_dtable (is_invoke_interface, arg_list)     int is_invoke_interface;     tree arg_list;{  tree dtable, objectref;  TREE_VALUE (arg_list) = save_expr (TREE_VALUE (arg_list));  /* If we're dealing with interfaces and if the objectref     argument is an array then get the dispatch table of the class     Object rather than the one from the objectref.  */  objectref = (is_invoke_interface 	       && is_array_type_p (TREE_TYPE (TREE_VALUE (arg_list))) ?	       object_type_node : TREE_VALUE (arg_list));    if (dtable_ident == NULL_TREE)    dtable_ident = get_identifier ("vtable");  dtable = build1 (INDIRECT_REF, object_type_node, objectref );  dtable = build (COMPONENT_REF, dtable_ptr_type, dtable,		  lookup_field (&object_type_node, dtable_ident));  return dtable;}tree build_invokevirtual (dtable, method)     tree dtable, method;{  tree func;  tree nativecode_ptr_ptr_type_node    = build_pointer_type (nativecode_ptr_type_node);  int method_index = TREE_INT_CST_LOW (DECL_VINDEX (method));  /* Add one to skip "class" field of dtable, and one to skip unused     vtable entry (for C++ compatibility). */  method_index += 2;  method_index    *= int_size_in_bytes (nativecode_ptr_ptr_type_node);  func = fold (build (PLUS_EXPR, nativecode_ptr_ptr_type_node,		      dtable, build_int_2 (method_index, 0)));  func = build1 (INDIRECT_REF, nativecode_ptr_type_node, func);  return func;}treebuild_invokeinterface (dtable, method_name, method_signature)     tree dtable, method_name, method_signature;{  static tree class_ident = NULL_TREE;  tree lookup_arg;  /* We expand invokeinterface here.  _Jv_LookupInterfaceMethod() will     ensure that the selected method exists, is public and not     abstract nor static.  */	      if (class_ident == NULL_TREE)    class_ident = get_identifier ("class");    dtable = build1 (INDIRECT_REF, dtable_type, dtable);  dtable = build (COMPONENT_REF, class_ptr_type, dtable,		  lookup_field (&dtable_type, class_ident));  lookup_arg = build_tree_list (NULL_TREE, 				(build_utf8_ref 				 (unmangle_classname				  (IDENTIFIER_POINTER(method_signature),				   IDENTIFIER_LENGTH(method_signature)))));  lookup_arg = tree_cons (NULL_TREE, dtable,			  tree_cons (NULL_TREE, build_utf8_ref (method_name),				     lookup_arg));  return build (CALL_EXPR, ptr_type_node, 		build_address_of (soft_lookupinterfacemethod_node),		lookup_arg, NULL_TREE);}  /* Expand one of the invoke_* opcodes.   OCPODE is the specific opcode.   METHOD_REF_INDEX is an index into the constant pool.   NARGS is the number of arguments, or -1 if not specified. */static voidexpand_invoke (opcode, method_ref_index, nargs)     int opcode;     int method_ref_index;     int nargs ATTRIBUTE_UNUSED;{  tree method_signature = COMPONENT_REF_SIGNATURE(&current_jcf->cpool, method_ref_index);  tree method_name = COMPONENT_REF_NAME (&current_jcf->cpool, method_ref_index);  tree self_type = get_class_constant    (current_jcf, COMPONENT_REF_CLASS_INDEX(&current_jcf->cpool, method_ref_index));  char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));  tree call, func, method, arg_list, method_type;  if (! CLASS_LOADED_P (self_type))    {      load_class (self_type, 1);      if (TREE_CODE (TYPE_SIZE (self_type)) == ERROR_MARK)	fatal ("failed to find class '%s'", self_name);    }  layout_class_methods (self_type);  if (method_name == init_identifier_node)    method = lookup_java_constructor (CLASS_TO_HANDLE_TYPE (self_type),				      method_signature);  else    method = lookup_java_method (CLASS_TO_HANDLE_TYPE (self_type),				 method_name, method_signature);  if (method == NULL_TREE)    {      error ("Class '%s' has no method named '%s' matching signature '%s'",	     self_name,	     IDENTIFIER_POINTER (method_name),	     IDENTIFIER_POINTER (method_signature));    }  /* Invoke static can't invoke static/abstract method */  else if (opcode == OPCODE_invokestatic)    {      if (!METHOD_STATIC (method))	{	  error ("invokestatic on non static method");	  method = NULL_TREE;	}      else if (METHOD_ABSTRACT (method))	{	  error ("invokestatic on abstract method");	  method = NULL_TREE;	}    }  else    {      if (METHOD_STATIC (method))	{	  error ("invoke[non-static] on static method");	  method = NULL_TREE;	}    }  if (method == NULL_TREE)    {      method_type = get_type_from_signature (method_signature);      pop_arguments (TYPE_ARG_TYPES (method_type));      if (opcode != OPCODE_invokestatic) 	pop_type (self_type);      method_type = promote_type (TREE_TYPE (method_type));      push_value (convert (method_type, integer_zero_node));      return;    }  method_type = TREE_TYPE (method);  arg_list = pop_arguments (TYPE_ARG_TYPES (method_type));  flush_quick_stack ();  func = NULL_TREE;  if (opcode == OPCODE_invokestatic || opcode == OPCODE_invokespecial      || (opcode == OPCODE_invokevirtual	  && (METHOD_PRIVATE (method)	      || METHOD_FINAL (method) 	      || CLASS_FINAL (TYPE_NAME (self_type)))))    func = build_known_method_ref (method, method_type, self_type,				   method_signature, arg_list);  else    {      tree dtable = invoke_build_dtable (opcode == OPCODE_invokeinterface, 					 arg_list);      if (opcode == OPCODE_invokevirtual)	func = build_invokevirtual (dtable, method);      else	func = build_invokeinterface (dtable, method_name, method_signature);    }  func = build1 (NOP_EXPR, build_pointer_type (method_type), func);  call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);  TREE_SIDE_EFFECTS (call) = 1;  if (TREE_CODE (TREE_TYPE (method_type)) == VOID_TYPE)    expand_expr_stmt (call);  else    {      push_value (call);      flush_quick_stack ();    }}/* Expand an operation to extract from or store into a field.   IS_STATIC is 1 iff the field is static.   IS_PUTTING is 1 for putting into a field;  0 for getting from the field.   FIELD_REF_INDEX is an index into the constant pool.  */static voidexpand_java_field_op (is_static, is_putting, field_ref_index)     int is_static;     int is_putting;     int field_ref_index;{  tree self_type =       get_class_constant (current_jcf, 			  COMPONENT_REF_CLASS_INDEX (&current_jcf->cpool, 						     field_ref_index));  char *self_name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (self_type)));  tree field_name = COMPONENT_REF_NAME (&current_jcf->cpool, field_ref_index);  tree field_signature = COMPONENT_REF_SIGNATURE (&current_jcf->cpool, 						  field_ref_index);  tree field_type = get_type_from_signature (field_signature);  tree new_value = is_putting ? pop_value (field_type) : NULL_TREE;  tree field_ref;  int is_error = 0;  tree field_decl = lookup_field (&self_type, field_name);  if (field_decl == error_mark_node)    {      is_error = 1;    }  else if (field_decl == NULL_TREE)    {      error ("Missing field '%s' in '%s'",	     IDENTIFIER_POINTER (field_name), self_name);      is_error = 1;    }  else if (build_java_signature (TREE_TYPE (field_decl)) != field_signature)    {      error ("Mismatching signature for field '%s' in '%s'",	     IDENTIFIER_POINTER (field_name), self_name);      is_error = 1;    }  field_ref = is_static ? NULL_TREE : pop_value (self_type);  if (is_error)    {      if (! is_putting)	push_value (convert (field_type, integer_zero_node));      flush_quick_stack ();      return;    }  /* Inline references to java.lang.PRIMTYPE.TYPE.     In addition to being a useful (minor) optimization,     this is also needed to avoid circularities in the implementation     of these fields in libjava. */  if (field_name == TYPE_identifier_node && ! is_putting      && ! flag_emit_class_files && field_type == class_ptr_type      && strncmp (self_name, "java.lang.", 10) == 0)    {      tree typ = build_primtype_type_ref (self_name);      if (typ)	{	  push_value (typ);	  return;	}    }  field_ref = build_field_ref (field_ref, self_type, field_name);  if (is_static)    field_ref = build_class_init (self_type, field_ref);  if (is_putting)    {      flush_quick_stack ();      if (FIELD_FINAL (field_decl))	{	  if (DECL_CONTEXT (field_decl) != current_class)	    error_with_decl (field_decl,		     "assignment to final field `%s' not in field's class");	  else if (FIELD_STATIC (field_decl))	    {	      if (!IS_CLINIT (current_function_decl))		error_with_decl (field_decl,              "assignment to final static field `%s' not in class initializer");	    }	  else	    {	      if (! DECL_CONSTRUCTOR_P (current_function_decl))		error_with_decl (field_decl, "assignment to final field `%s' "				 "not in constructor");	    }	}

⌨️ 快捷键说明

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