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

📄 decl2.c

📁 gcc库的原代码,对编程有很大帮助.
💻 C
📖 第 1 页 / 共 5 页
字号:
      if (TREE_CHAIN (lengths))	error ("multiple length specifiers");      type_id = ridpointers[(int)RID_INT];      declspecs = chainon (lengths, quals);    }  else if (quals)    {      error ("no type given, defaulting to `operator int ...'");      type_id = ridpointers[(int)RID_INT];      declspecs = quals;    }  else    return NULL_TREE; found:  decl = grokdeclarator (build_parse_node (CALL_EXPR, type_id, parmlist, NULL_TREE),			 declspecs, FIELD, 0, NULL_TREE, NULL_TREE);  if (decl == NULL_TREE)    return NULL_TREE;  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CHAIN (decl) != NULL_TREE)    {      /* Need a fresh node here so that we don't get circularity	 when we link these together.  */      decl = copy_node (decl);    }  if (decl == void_type_node      || (TREE_CODE (decl) == FUNCTION_DECL	  && TREE_CODE (TREE_TYPE (decl)) != METHOD_TYPE))    /* bunch of friends.  */    return decl;  if (DECL_IN_AGGR_P (decl))    {      cp_error ("`%D' already defined in the class ", decl);      return void_type_node;    }  cp_finish_decl (decl, NULL_TREE, NULL_TREE, 0, 0);  /* If this declaration is common to another declaration     complain about such redundancy, and return NULL_TREE     so that we don't build a circular list.  */  if (DECL_CHAIN (decl))    {      cp_error ("function `%D' declared twice in class %T", decl,		  DECL_CONTEXT (decl));      return NULL_TREE;    }  DECL_IN_AGGR_P (decl) = 1;  return decl;}#endiftreegrokoptypename (declspecs, declarator)     tree declspecs, declarator;{  tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0,			   NULL_TREE, NULL_TREE);  return build_typename_overload (t);}/* When a function is declared with an initializer,   do the right thing.  Currently, there are two possibilities:   class B   {    public:     // initialization possibility #1.     virtual void f () = 0;     int g ();   };      class D1 : B   {    public:     int d1;     // error, no f ();   };      class D2 : B   {    public:     int d2;     void f ();   };      class D3 : B   {    public:     int d3;     // initialization possibility #2     void f () = B::f;   };*/intcopy_assignment_arg_p (parmtype, virtualp)     tree parmtype;     int virtualp;{  if (TREE_CODE (parmtype) == REFERENCE_TYPE)    parmtype = TREE_TYPE (parmtype);  if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type)      || (virtualp && DERIVED_FROM_P (parmtype, current_class_type)))    return 1;  return 0;}static voidgrok_function_init (decl, init)     tree decl;     tree init;{  /* An initializer for a function tells how this function should     be inherited.  */  tree type = TREE_TYPE (decl);  if (TREE_CODE (type) == FUNCTION_TYPE)    cp_error ("initializer specified for non-member function `%D'", decl);  else if (DECL_VINDEX (decl) == NULL_TREE)    cp_error ("initializer specified for non-virtual method `%D'", decl);  else if (integer_zerop (init))    {#if 0      /* Mark this function as being "defined".  */      DECL_INITIAL (decl) = error_mark_node;      /* pure virtual destructors must be defined. */      /* pure virtual needs to be defined (as abort) only when put in 	 vtbl. For wellformed call, it should be itself. pr4737 */      if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl)))	{	  extern tree abort_fndecl;	  /* Give this node rtl from `abort'.  */	  DECL_RTL (decl) = DECL_RTL (abort_fndecl);	}#endif      DECL_ABSTRACT_VIRTUAL_P (decl) = 1;      if (DECL_NAME (decl) == ansi_opname [(int) MODIFY_EXPR])	{	  tree parmtype	    = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))));	  if (copy_assignment_arg_p (parmtype, 1))	    TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1;	}    }  else if (TREE_CODE (init) == OFFSET_REF	   && TREE_OPERAND (init, 0) == NULL_TREE	   && TREE_CODE (TREE_TYPE (init)) == METHOD_TYPE)    {      tree basetype = DECL_CLASS_CONTEXT (init);      tree basefn = TREE_OPERAND (init, 1);      if (TREE_CODE (basefn) != FUNCTION_DECL)	cp_error ("non-method initializer invalid for method `%D'", decl);      else if (! BINFO_OFFSET_ZEROP (TYPE_BINFO (DECL_CLASS_CONTEXT (basefn))))	sorry ("base member function from other than first base class");      else	{	  tree binfo = get_binfo (basetype, TYPE_METHOD_BASETYPE (type), 1);	  if (binfo == error_mark_node)	    ;	  else if (binfo == 0)	    error_not_base_type (TYPE_METHOD_BASETYPE (TREE_TYPE (init)),				 TYPE_METHOD_BASETYPE (type));	  else	    {	      /* Mark this function as being defined,		 and give it new rtl.  */	      DECL_INITIAL (decl) = error_mark_node;	      DECL_RTL (decl) = DECL_RTL (basefn);	    }	}    }  else    cp_error ("invalid initializer for virtual method `%D'", decl);}/* When we get a declaration of the form   type cname::fname ...   the node for `cname::fname' gets built here in a special way.   Namely, we push into `cname's scope.  When this declaration is   processed, we pop back out.  */treebuild_push_scope (cname, name)     tree cname;     tree name;{  extern int current_class_depth;  tree ctype, rval;  int is_ttp = 0;  if (cname == error_mark_node)    return error_mark_node;  ctype = IDENTIFIER_TYPE_VALUE (cname);  if (TREE_CODE (ctype) == TEMPLATE_TYPE_PARM)    is_ttp = 1;  else if (ctype == NULL_TREE || ! IS_AGGR_TYPE (ctype))    {      cp_error ("`%T' not defined as aggregate type", cname);      return name;    }  else if (IS_SIGNATURE (ctype))    {      error ("cannot push into signature scope, scope resolution operator ignored");      return name;    }  rval = build_parse_node (SCOPE_REF, cname, name);  /* Don't need to push the scope if we're already in it.     We also don't need to push the scope for a ptr-to-member/method.  */  if (ctype == current_class_type || TREE_CODE (name) != IDENTIFIER_NODE      || is_ttp)    return rval;  /* We do need to push the scope in this case, since CTYPE helps     determine subsequent initializers (i.e., Foo::Bar x = foo_enum_1;).  */  push_nested_class (ctype, 3);  TREE_COMPLEXITY (rval) = current_class_depth;  return rval;}voidcplus_decl_attributes (decl, attributes, prefix_attributes)     tree decl, attributes, prefix_attributes;{  if (decl == NULL_TREE || decl == void_type_node)    return;  if (TREE_CODE (decl) == TEMPLATE_DECL)    decl = DECL_TEMPLATE_RESULT (decl);  decl_attributes (decl, attributes, prefix_attributes);  if (TREE_CODE (decl) == TYPE_DECL)    SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl));}/* CONSTRUCTOR_NAME:   Return the name for the constructor (or destructor) for the   specified class.  Argument can be RECORD_TYPE, TYPE_DECL, or   IDENTIFIER_NODE.  When given a template, this routine doesn't   lose the specialization.  */treeconstructor_name_full (thing)     tree thing;{  if (TREE_CODE (thing) == UNINSTANTIATED_P_TYPE)    return DECL_NAME (UPT_TEMPLATE (thing));  if (IS_AGGR_TYPE_CODE (TREE_CODE (thing)))    {      if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing))	thing = DECL_NAME (TREE_VEC_ELT (TYPE_METHODS (thing), 0));      else	thing = TYPE_NAME (thing);    }  if (TREE_CODE (thing) == TYPE_DECL      || (TREE_CODE (thing) == TEMPLATE_DECL	  && DECL_TEMPLATE_IS_CLASS (thing)))    thing = DECL_NAME (thing);  my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197);  return thing;}/* CONSTRUCTOR_NAME:   Return the name for the constructor (or destructor) for the   specified class.  Argument can be RECORD_TYPE, TYPE_DECL, or   IDENTIFIER_NODE.  When given a template, return the plain   unspecialized name.  */treeconstructor_name (thing)     tree thing;{  tree t;  thing = constructor_name_full (thing);  t = IDENTIFIER_TEMPLATE (thing);  if (!t)    return thing;  t = TREE_PURPOSE (t);  return DECL_NAME (t);}/* Cache the value of this class's main virtual function table pointer   in a register variable.  This will save one indirection if a   more than one virtual function call is made this function.  */voidsetup_vtbl_ptr (){  extern tree base_init_expr;  if (base_init_expr == 0      && DECL_CONSTRUCTOR_P (current_function_decl))    emit_base_init (current_class_type, 0);}/* Record the existence of an addressable inline function.  */voidmark_inline_for_output (decl)     tree decl;{  decl = DECL_MAIN_VARIANT (decl);  if (DECL_SAVED_INLINE (decl))    return;  my_friendly_assert (TREE_PERMANENT (decl), 363);  DECL_SAVED_INLINE (decl) = 1;#if 0  if (DECL_PENDING_INLINE_INFO (decl) != 0      && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu)    {      struct pending_inline *t = pending_inlines;      my_friendly_assert (DECL_SAVED_INSNS (decl) == 0, 198);      while (t)	{	  if (t == DECL_PENDING_INLINE_INFO (decl))	    break;	  t = t->next;	}      if (t == 0)	{	  t = DECL_PENDING_INLINE_INFO (decl);	  t->next = pending_inlines;	  pending_inlines = t;	}      DECL_PENDING_INLINE_INFO (decl) = 0;    }#endif  saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines);}voidclear_temp_name (){  temp_name_counter = 0;}/* Hand off a unique name which can be used for variable we don't really   want to know about anyway, for example, the anonymous variables which   are needed to make references work.  Declare this thing so we can use it.   The variable created will be of type TYPE.   STATICP is nonzero if this variable should be static.  */treeget_temp_name (type, staticp)     tree type;     int staticp;{  char buf[sizeof (AUTO_TEMP_FORMAT) + 20];  tree decl;  int toplev = toplevel_bindings_p ();  push_obstacks_nochange ();  if (toplev || staticp)    {      end_temporary_allocation ();      sprintf (buf, AUTO_TEMP_FORMAT, global_temp_name_counter++);      decl = pushdecl_top_level (build_decl (VAR_DECL, get_identifier (buf), type));    }  else    {      sprintf (buf, AUTO_TEMP_FORMAT, temp_name_counter++);      decl = pushdecl (build_decl (VAR_DECL, get_identifier (buf), type));    }  TREE_USED (decl) = 1;  TREE_STATIC (decl) = staticp;  /* If this is a local variable, then lay out its rtl now.     Otherwise, callers of this function are responsible for dealing     with this variable's rtl.  */  if (! toplev)    {      expand_decl (decl);      expand_decl_init (decl);    }  pop_obstacks ();  return decl;}/* Get a variable which we can use for multiple assignments.   It is not entered into current_binding_level, because   that breaks things when it comes time to do final cleanups   (which take place "outside" the binding contour of the function).  */treeget_temp_regvar (type, init)     tree type, init;{  static char buf[sizeof (AUTO_TEMP_FORMAT) + 20] = { '_' };  tree decl;  sprintf (buf+1, AUTO_TEMP_FORMAT, temp_name_counter++);  decl = build_decl (VAR_DECL, get_identifier (buf), type);  TREE_USED (decl) = 1;  DECL_REGISTER (decl) = 1;  if (init)    store_init_value (decl, init);  /* We can expand these without fear, since they cannot need     constructors or destructors.  */  expand_decl (decl);  expand_decl_init (decl);  if (type_needs_gc_entry (type))    DECL_GC_OFFSET (decl) = size_int (++current_function_obstack_index);  return decl;}/* Make the macro TEMP_NAME_P available to units which do not   include c-tree.h.  */inttemp_name_p (decl)     tree decl;{  return TEMP_NAME_P (decl);}/* Finish off the processing of a UNION_TYPE structure.   If there are static members, then all members are   static, and must be laid out together.  If the   union is an anonymous union, we arrange for that   as well.  PUBLIC_P is nonzero if this union is   not declared static.  */voidfinish_anon_union (anon_union_decl)     tree anon_union_decl;{  tree

⌨️ 快捷键说明

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