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

📄 decl.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 4 页
字号:
	  IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0;	  /* Put the labels into the "variables" of the	     top-level block, so debugger can see them.  */	  TREE_CHAIN (label) = BLOCK_VARS (block);	  BLOCK_VARS (block) = label;	}#endif    }  /* Pop the current level, and free the structure for reuse.  */  {    register struct binding_level *level = current_binding_level;    current_binding_level = current_binding_level->level_chain;    level->level_chain = free_binding_level;    free_binding_level = level;  }  /* Dispose of the block that we just made inside some higher level.  */  if (functionbody)    DECL_INITIAL (current_function_decl) = block;  else if (block)    {      if (!block_previously_created)        current_binding_level->blocks          = chainon (current_binding_level->blocks, block);    }  /* If we did not make a block for the level just exited,     any blocks made for inner levels     (since they cannot be recorded as subblocks in that level)     must be carried forward so they will later become subblocks     of something else.  */  else if (subblocks)    current_binding_level->blocks      = chainon (current_binding_level->blocks, subblocks);  /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this     binding contour so that they point to the appropriate construct, i.e.     either to the current FUNCTION_DECL node, or else to the BLOCK node     we just constructed.     Note that for tagged types whose scope is just the formal parameter     list for some function type specification, we can't properly set     their TYPE_CONTEXTs here, because we don't have a pointer to the     appropriate FUNCTION_TYPE node readily available to us.  For those     cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set     in `grokdeclarator' as soon as we have created the FUNCTION_TYPE     node which will represent the "scope" for these "parameter list local"     tagged types.  */  if (block)    TREE_USED (block) = 1;  return block;}voidmaybe_pushlevels (pc)     int pc;{  while (pending_local_decls != NULL_TREE &&	 DECL_LOCAL_START_PC (pending_local_decls) <= pc)    {      tree *ptr = &pending_local_decls;      tree decl = *ptr;      int end_pc = DECL_LOCAL_END_PC (decl);      while (*ptr != NULL_TREE	     && DECL_LOCAL_START_PC (*ptr) <= pc	     && DECL_LOCAL_END_PC (*ptr) == end_pc)	ptr = &TREE_CHAIN (*ptr);      pending_local_decls = *ptr;      *ptr = NULL_TREE;      /* Force non-nested range to be nested in current range. */      if (end_pc > current_binding_level->end_pc)	end_pc = current_binding_level->end_pc;      pushlevel (1);      expand_start_bindings (0);      current_binding_level->end_pc = end_pc;            current_binding_level->names = decl;      for ( ; decl != NULL_TREE;  decl = TREE_CHAIN (decl))	{	  push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl);	}    }}voidmaybe_poplevels (pc)     int pc;{  while (current_binding_level->end_pc <= pc)    {      expand_end_bindings (getdecls (), 1, 0);      poplevel (1, 0, 0);    }}/* Insert BLOCK at the end of the list of subblocks of the   current binding level.  This is used when a BIND_EXPR is expanded,   to handle the BLOCK node inside the BIND_EXPR.  */voidinsert_block (block)     tree block;{  TREE_USED (block) = 1;  abort ();  current_binding_level->blocks    = chainon (current_binding_level->blocks, block);}/* Set the BLOCK node for the innermost scope   (the one we are currently in).  */voidset_block (block)     register tree block;{  current_binding_level->this_block = block;}/* integrate_decl_tree calls this function. */voidcopy_lang_decl (node)     tree node;{  int lang_decl_size    = TREE_CODE (node) == VAR_DECL ? sizeof (struct lang_decl_var)    : sizeof (struct lang_decl);  struct lang_decl *x = (struct lang_decl *) oballoc (lang_decl_size);  bcopy ((PTR) DECL_LANG_SPECIFIC (node), (PTR) x, lang_decl_size);  DECL_LANG_SPECIFIC (node) = x;}/* If DECL has a cleanup, build and return that cleanup here.   This is a callback called by expand_expr.  */treemaybe_build_cleanup (decl)  tree decl ATTRIBUTE_UNUSED;{  /* There are no cleanups in Java (I think).  */  return NULL_TREE;}voidgive_name_to_locals (jcf)     JCF *jcf;{  int i, n = DECL_LOCALVARIABLES_OFFSET (current_function_decl);  tree parm;  pending_local_decls = NULL_TREE;  if (n == 0)    return;  JCF_SEEK (jcf, n);  n = JCF_readu2 (jcf);  for (i = 0; i < n; i++)    {      int start_pc = JCF_readu2 (jcf);      int length = JCF_readu2 (jcf);      int name_index = JCF_readu2 (jcf);      int signature_index = JCF_readu2 (jcf);      int slot = JCF_readu2 (jcf);      tree name = get_name_constant (jcf, name_index);      tree type = parse_signature (jcf, signature_index);      if (slot < DECL_ARG_SLOT_COUNT (current_function_decl)	  && start_pc == 0	  && length == DECL_CODE_LENGTH (current_function_decl))	{	  tree decl = TREE_VEC_ELT (decl_map, slot);	  DECL_NAME (decl) = name;	  DECL_ASSEMBLER_NAME (decl) = name;	  if (TREE_CODE (decl) != PARM_DECL || TREE_TYPE (decl) != type)	    warning ("bad type in parameter debug info");	}      else	{	  tree *ptr;	  int end_pc = start_pc + length;	  tree decl = build_decl (VAR_DECL, name, type);	  if (end_pc > DECL_CODE_LENGTH (current_function_decl))	    {	      warning_with_decl (decl,			 "bad PC range for debug info for local `%s'");	      end_pc = DECL_CODE_LENGTH (current_function_decl);	    }	  DECL_LANG_SPECIFIC (decl)	    = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var));	  DECL_LOCAL_SLOT_NUMBER (decl) = slot;	  DECL_LOCAL_START_PC (decl) = start_pc;	  DECL_LOCAL_END_PC (decl) = end_pc;	  /* Now insert the new decl in the proper place in	     pending_local_decls.  We are essentially doing an insertion sort,	     which works fine, since the list input will normally already	     be sorted. */	  ptr = &pending_local_decls;	  while (*ptr != NULL_TREE		 && (DECL_LOCAL_START_PC (*ptr) > start_pc		     || (DECL_LOCAL_START_PC (*ptr) == start_pc			 && DECL_LOCAL_END_PC (*ptr) < end_pc)))	    ptr = &TREE_CHAIN (*ptr);	  TREE_CHAIN (decl) = *ptr;	  *ptr = decl;	}    }  pending_local_decls = nreverse (pending_local_decls);  /* Fill in default names for the parameters. */   for (parm = DECL_ARGUMENTS (current_function_decl), i = 0;       parm != NULL_TREE;  parm = TREE_CHAIN (parm), i++)    {      if (DECL_NAME (parm) == NULL_TREE)	{	  int arg_i = METHOD_STATIC (current_function_decl) ? i+1 : i;	  if (arg_i == 0)	    DECL_NAME (parm) = get_identifier ("this");	  else	    {	      char buffer[12];	      sprintf (buffer, "ARG_%d", arg_i);	      DECL_NAME (parm) = get_identifier (buffer);	    }	  DECL_ASSEMBLER_NAME (parm) = DECL_NAME (parm);	}    }}treebuild_result_decl (fndecl)  tree fndecl;{  tree restype = TREE_TYPE (TREE_TYPE (fndecl));  /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */  if (INTEGRAL_TYPE_P (restype)      && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))    restype = integer_type_node;  return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));}voidcomplete_start_java_method (fndecl)  tree fndecl;{  if (! flag_emit_class_files)    {      /* Initialize the RTL code for the function.  */      init_function_start (fndecl, input_filename, lineno);      /* Set up parameters and prepare for return, for the function.  */      expand_function_start (fndecl, 0);    }  /* Allocate further tree nodes temporarily during compilation     of this function only.  */  temporary_allocation ();#if 0      /* If this fcn was already referenced via a block-scope `extern' decl (or         an implicit decl), propagate certain information about the usage. */      if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl)))        TREE_ADDRESSABLE (current_function_decl) = 1;#endif  if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl)      && ! flag_emit_class_files      && ! CLASS_INTERFACE (TYPE_NAME (current_class)))    {      tree clas = DECL_CONTEXT (fndecl);      tree 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;      expand_expr_stmt (init);    }  /* Push local variables. Function compiled from source code are     using a different local variables management, and for them,     pushlevel shouldn't be called from here.  */  if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))    {      pushlevel (2);      if (! flag_emit_class_files)	expand_start_bindings (1);    }  if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files)    {      /* Warp function body with a monitorenter plus monitorexit cleanup. */      tree enter, exit, lock;      if (METHOD_STATIC (fndecl))	lock = build_class_ref (DECL_CONTEXT (fndecl));      else	lock = DECL_ARGUMENTS (fndecl);      BUILD_MONITOR_ENTER (enter, lock);      BUILD_MONITOR_EXIT (exit, lock);      if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl)))	{	  expand_expr_stmt (enter);	  expand_decl_cleanup (NULL_TREE, exit);	}      else	{	  tree function_body = DECL_FUNCTION_BODY (fndecl);	  tree body = BLOCK_EXPR_BODY (function_body);	  lock = build (WITH_CLEANUP_EXPR, void_type_node,			enter,  NULL_TREE, exit);	  TREE_SIDE_EFFECTS (lock) = 1;	  lock = build (COMPOUND_EXPR, TREE_TYPE (body), lock, body);	  TREE_SIDE_EFFECTS (lock) = 1;	  lock = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (body), lock);	  TREE_SIDE_EFFECTS (lock) = 1;	  BLOCK_EXPR_BODY (function_body) = lock;	}    }}voidstart_java_method (fndecl)     tree fndecl;{  tree tem, *ptr;  int i;  current_function_decl = fndecl;  announce_function (fndecl);  i = DECL_MAX_LOCALS(fndecl) + DECL_MAX_STACK(fndecl);  decl_map = make_tree_vec (i);  type_map = (tree *) oballoc (i * sizeof (tree));  pushlevel (1);  /* Push parameters. */  ptr = &DECL_ARGUMENTS (fndecl);  for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0;       tem != end_params_node; tem = TREE_CHAIN (tem), i++)    {      tree parm_name = NULL_TREE, parm_decl;      tree parm_type = TREE_VALUE (tem);      if (i >= DECL_MAX_LOCALS(fndecl))	fatal ("function has more parameters than local slots");      parm_decl = build_decl (PARM_DECL, parm_name, parm_type);      DECL_CONTEXT (parm_decl) = fndecl;#ifdef PROMOTE_PROTOTYPES      if (TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node)	  && INTEGRAL_TYPE_P (parm_type))	parm_type = integer_type_node;#endif      DECL_ARG_TYPE (parm_decl) = parm_type;      *ptr = parm_decl;      ptr = &TREE_CHAIN (parm_decl);      /* Add parm_decl to the decl_map. */      push_jvm_slot (i, parm_decl);      type_map[i] = TREE_TYPE (parm_decl);      if (TYPE_IS_WIDE (TREE_TYPE (parm_decl)))	{	  i++;	  type_map[i] = void_type_node;	}    }  *ptr = NULL_TREE;  DECL_ARG_SLOT_COUNT (current_function_decl) = i;  while (i < DECL_MAX_LOCALS(fndecl))    type_map[i++] = NULL_TREE;  build_result_decl (fndecl);  complete_start_java_method (fndecl);}voidend_java_method (){  tree fndecl = current_function_decl;  int flag_asynchronous_exceptions = asynchronous_exceptions;  expand_end_bindings (getdecls (), 1, 0);  /* pop out of function */  poplevel (1, 1, 0);  /* pop out of its parameters */  poplevel (1, 0, 1);  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;  emit_handlers ();  /* Generate rtl for function exit.  */  expand_function_end (input_filename, lineno, 0);  /* FIXME: If the current method contains any exception handlers,     force asynchronous_exceptions: this is necessary because signal     handlers in libjava may throw exceptions.  This is far from being     a perfect solution, but it's better than doing nothing at all.*/  if (catch_clauses)    asynchronous_exceptions = 1;  /* Run the optimizers and output assembler code for this function. */  rest_of_compilation (fndecl);  current_function_decl = NULL_TREE;  permanent_allocation (1);  asynchronous_exceptions = flag_asynchronous_exceptions;}

⌨️ 快捷键说明

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