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

📄 cp-decl.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
	      || TYPE_SIZE (current_class_type) != NULL_TREE)	    {	      if (current_lang_name == lang_name_cplusplus)		d = lookup_nested_type (type, current_class_type ? TYPE_NAME (current_class_type) : NULL_TREE);	      else		d = NULL_TREE;	      if (d == NULL_TREE)		{#if 0 /* not yet, should get fixed properly later */		  d = make_type_decl (name, type);		  DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1));#else		  d = build_decl (TYPE_DECL, name, type);		  DECL_ASSEMBLER_NAME (d) = get_identifier (build_overload_name (type, 1, 1));#endif		  /* mark the binding layer marker as internal. (mrs) */		  DECL_SOURCE_LINE (d) = 0;		  set_identifier_type_value (name, type);		}	      else		d = TYPE_NAME (d);	      /* If it is anonymous, then we are called from pushdecl,		 and we don't want to infinitely recurse.  Also, if the		 name is already in scope, we don't want to push it		 again--pushdecl is only for pushing new decls.  */	      if (! ANON_AGGRNAME_P (name)		  && TYPE_NAME (type)		  && (TREE_CODE (TYPE_NAME (type)) != TYPE_DECL		      || lookup_name (name, 1) != TYPE_NAME (type)))		{		  if (class_binding_level)		    d = pushdecl_class_level (d);		  else		    d = pushdecl (d);		}	    }	  else	    {	      /* Make nested declarations go into class-level scope.  */	      d = build_lang_field_decl (TYPE_DECL, name, type);	      set_identifier_type_value (name, type);	      d = pushdecl_class_level (d);	    }	  if (ANON_AGGRNAME_P (name))	    DECL_IGNORED_P (d) = 1;	  TYPE_NAME (type) = d;	  if ((current_class_type == NULL_TREE	       && current_function_decl == NULL_TREE)	      || current_lang_name != lang_name_cplusplus)	    /* Non-nested class.  */	    DECL_NESTED_TYPENAME (d) = name;	  else if (current_function_decl != NULL_TREE)	    {	      /* Function-nested class.  */	      set_nested_typename (d, DECL_ASSEMBLER_NAME (current_function_decl),				   name, type);	      /* This builds the links for classes nested in fn scope.  */	      DECL_CONTEXT (d) = current_function_decl;	    }	  else if (TYPE_SIZE (current_class_type) == NULL_TREE)	    {	      /* Class-nested class.  */	      set_nested_typename (d, DECL_NESTED_TYPENAME (TYPE_NAME (current_class_type)),				   name, type);	      /* This builds the links for classes nested in type scope.  */	      DECL_CONTEXT (d) = current_class_type;	      DECL_CLASS_CONTEXT (d) = current_class_type;	    }        }      if (b->parm_flag == 2)	{	  TREE_NONLOCAL_FLAG (type) = 1;	  IDENTIFIER_CLASS_VALUE (name) = TYPE_NAME (type);	  if (TYPE_SIZE (current_class_type) == NULL_TREE)	    CLASSTYPE_TAGS (current_class_type) = b->tags;	}    }  if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)    /* Use the canonical TYPE_DECL for this node.  */    TYPE_STUB_DECL (type) = TYPE_NAME (type);  else    {      /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE	 will be the tagged type we just added to the current	 binding level.  This fake NULL-named TYPE_DECL node helps	 dwarfout.c to know when it needs to output a	 representation of a tagged type, and it also gives us a	 convenient place to record the "scope start" address for	 the tagged type.  */#if 0 /* not yet, should get fixed properly later */      TYPE_STUB_DECL (type) = pushdecl (make_type_decl (NULL, type));#else      TYPE_STUB_DECL (type) = pushdecl (build_decl (TYPE_DECL, NULL, type));#endif    }}/* Counter used to create anonymous type names.  */static int anon_cnt = 0;/* Return an IDENTIFIER which can be used as a name for   anonymous structs and unions.  */treemake_anon_name (){  char buf[32];  sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++);  return get_identifier (buf);}/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames.   This keeps dbxout from getting confused.  */voidclear_anon_tags (){  register struct binding_level *b;  register tree tags;  static int last_cnt = 0;  /* Fast out if no new anon names were declared.  */  if (last_cnt == anon_cnt)    return;  b = current_binding_level;  while (b->tag_transparent)    b = b->level_chain;  tags = b->tags;  while (tags)    {      /* A NULL purpose means we have already processed all tags	 from here to the end of the list.  */      if (TREE_PURPOSE (tags) == NULL_TREE)	break;      if (ANON_AGGRNAME_P (TREE_PURPOSE (tags)))	TREE_PURPOSE (tags) = NULL_TREE;      tags = TREE_CHAIN (tags);    }  last_cnt = anon_cnt;}/* Subroutine of duplicate_decls: return truthvalue of whether   or not types of these decls match.  */static intdecls_match (newdecl, olddecl)     tree newdecl, olddecl;{  int types_match;  if (TREE_CODE (newdecl) == FUNCTION_DECL && TREE_CODE (olddecl) == FUNCTION_DECL)    {      tree f1 = TREE_TYPE (newdecl);      tree f2 = TREE_TYPE (olddecl);      tree p1 = TYPE_ARG_TYPES (f1);      tree p2 = TYPE_ARG_TYPES (f2);      /* When we parse a static member function definition,	 we put together a FUNCTION_DECL which thinks its type	 is METHOD_TYPE.  Change that to FUNCTION_TYPE, and	 proceed.  */      if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl))	revert_static_member_fn (&f1, &newdecl, &p1);      else if (TREE_CODE (f2) == METHOD_TYPE	       && DECL_STATIC_FUNCTION_P (newdecl))	revert_static_member_fn (&f2, &olddecl, &p2);      /* Here we must take care of the case where new default	 parameters are specified.  Also, warn if an old	 declaration becomes ambiguous because default	 parameters may cause the two to be ambiguous.  */      if (TREE_CODE (f1) != TREE_CODE (f2))	{	  if (TREE_CODE (f1) == OFFSET_TYPE)	    compiler_error_with_decl (newdecl, "`%s' redeclared as member function");	  else	    compiler_error_with_decl (newdecl, "`%s' redeclared as non-member function");	  return 0;	}      if (comptypes (TYPE_MAIN_VARIANT (TREE_TYPE (f1)),		     TYPE_MAIN_VARIANT (TREE_TYPE (f2)), 1))	types_match = compparms (p1, p2, 1);      else types_match = 0;    }  else    {      if (TREE_TYPE (newdecl) == error_mark_node)	types_match = TREE_TYPE (olddecl) == error_mark_node;      else if (TREE_TYPE (olddecl) == NULL_TREE)	types_match = TREE_TYPE (newdecl) == NULL_TREE;      else	types_match = comptypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl), 1);    }  return types_match;}/* Handle when a new declaration NEWDECL has the same name as an old   one OLDDECL in the same binding contour.  Prints an error message   if appropriate.   If safely possible, alter OLDDECL to look like NEWDECL, and return 1.   Otherwise, return 0.  */static intduplicate_decls (newdecl, olddecl)     register tree newdecl, olddecl;{  extern struct obstack permanent_obstack;  unsigned olddecl_uid = DECL_UID (olddecl);  int olddecl_friend = 0, types_match;  int new_defines_function;  register unsigned saved_old_decl_uid;  register int saved_old_decl_friend_p;  if (TREE_CODE (olddecl) == TREE_LIST      && TREE_CODE (newdecl) == FUNCTION_DECL)    {      /* If a new decl finds a list of old decls, then	 we assume that the new decl has C linkage, and	 that the old decls have C++ linkage.  In this case,	 we must look through the list to see whether	 there is an ambiguity or not.  */      tree olddecls = olddecl;      /* If the overload list is empty, just install the decl.  */      if (TREE_VALUE (olddecls) == NULL_TREE)	{	  TREE_VALUE (olddecls) = newdecl;	  return 1;	}      while (olddecls)	{	  if (decls_match (newdecl, TREE_VALUE (olddecls)))	    {	      if (TREE_CODE (newdecl) == VAR_DECL)		;	      else if (DECL_LANGUAGE (newdecl)		       != DECL_LANGUAGE (TREE_VALUE (olddecls)))		{		  error_with_decl (newdecl, "declaration of `%s' with different language linkage");		  error_with_decl (TREE_VALUE (olddecls), "previous declaration here");		}	      types_match = 1;	      break;	    }	  olddecls = TREE_CHAIN (olddecls);	}      if (olddecls)	olddecl = TREE_VALUE (olddecl);      else	return 1;    }  else    {      if (TREE_CODE (olddecl) != TREE_LIST)	olddecl_friend = DECL_LANG_SPECIFIC (olddecl) && DECL_FRIEND_P (olddecl);      types_match = decls_match (newdecl, olddecl);    }  if ((TREE_TYPE (newdecl) && TREE_CODE (TREE_TYPE (newdecl)) == ERROR_MARK)      || (TREE_TYPE (olddecl) && TREE_CODE (TREE_TYPE (olddecl)) == ERROR_MARK))    types_match = 0;  /* If this decl has linkage, and the old one does too, maybe no error.  */  if (TREE_CODE (olddecl) != TREE_CODE (newdecl))    {      error_with_decl (newdecl, "`%s' redeclared as different kind of symbol");      if (TREE_CODE (olddecl) == TREE_LIST)	olddecl = TREE_VALUE (olddecl);      error_with_decl (olddecl, "previous declaration of `%s'");      /* New decl is completely inconsistent with the old one =>	 tell caller to replace the old one.  */      return 0;    }  if (TREE_CODE (newdecl) == FUNCTION_DECL)    {      /* Now that functions must hold information normally held	 by field decls, there is extra work to do so that	 declaration information does not get destroyed during	 definition.  */      if (DECL_VINDEX (olddecl))	DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl);      if (DECL_CONTEXT (olddecl))	DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);      if (DECL_CLASS_CONTEXT (olddecl))	DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl);#ifdef SOS      if (DECL_DINDEX (olddecl))	DECL_DINDEX (newdecl) = DECL_DINDEX (newdecl);#endif      if (DECL_CHAIN (newdecl) == 0)	DECL_CHAIN (newdecl) = DECL_CHAIN (olddecl);      if (DECL_PENDING_INLINE_INFO (newdecl) == 0)	DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl);    }  if (flag_traditional && TREE_CODE (newdecl) == FUNCTION_DECL      && IDENTIFIER_IMPLICIT_DECL (DECL_ASSEMBLER_NAME (newdecl)) == olddecl)    /* If -traditional, avoid error for redeclaring fcn       after implicit decl.  */    ;  else if (TREE_CODE (olddecl) == FUNCTION_DECL	   && DECL_BUILT_IN (olddecl))    {      if (!types_match)	{	  error_with_decl (newdecl, "declaration of `%s'");	  error_with_decl (olddecl, "conflicts with built-in declaration `%s'");	}    }  else if (!types_match)    {      tree oldtype = TREE_TYPE (olddecl);      tree newtype = TREE_TYPE (newdecl);      int give_error = 0;      /* Already complained about this, so don't do so again.  */      if (current_class_type == NULL_TREE	  || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type)	{	  give_error = 1;	  error_with_decl (newdecl, "conflicting types for `%s'");	}      /* Check for function type mismatch	 involving an empty arglist vs a nonempty one.  */      if (TREE_CODE (olddecl) == FUNCTION_DECL	  && comptypes (TREE_TYPE (oldtype),			TREE_TYPE (newtype), 1)	  && ((TYPE_ARG_TYPES (oldtype) == 0	       && DECL_INITIAL (olddecl) == 0)	      || (TYPE_ARG_TYPES (newtype) == 0		  && DECL_INITIAL (newdecl) == 0)))	{	  /* Classify the problem further.  */	  register tree t = TYPE_ARG_TYPES (oldtype);	  if (t == 0)	    t = TYPE_ARG_TYPES (newtype);	  for (; t; t = TREE_CHAIN (t))	    {	      register tree type = TREE_VALUE (t);	      if (TREE_CHAIN (t) == 0 && type != void_type_node)		{		  error ("A parameter list with an ellipsis can't match");		  error ("an empty parameter name list declaration.");		  break;		}	      if (TYPE_MAIN_VARIANT (type) == float_type_node		  || C_PROMOTING_INTEGER_TYPE_P (type))		{		  error ("An argument type that has a default promotion");		  error ("can't match an empty parameter name list declaration.");		  break;		}	    }	}      if (give_error)	error_with_decl (olddecl, "previous declaration of `%s'");      /* There is one thing GNU C++ cannot tolerate: a constructor	 which takes the type of object being constructed.	 Farm that case out here.  */      if (TREE_CODE (newdecl) == FUNCTION_DECL	  && DECL_CONSTRUCTOR_P (newdecl))	{	  tree tmp = TREE_CHAIN (TYPE_ARG_TYPES (newtype));	  if (tmp != NULL_TREE	      && (TYPE_MAIN_VARIANT (TREE_VALUE (tmp))		  == TYPE_METHOD_BASETYPE (newtype)))	    {	      tree parm = TREE_CHAIN (DECL_ARGUMENTS (newdecl));	      tree argtypes		= hash_tree_chain (build_reference_type (TREE_VALUE (tmp)),				   TREE_CHAIN (tmp));	      DECL_ARG_TYPE (parm)		= TREE_TYPE (parm)		  = TYPE_REFERENCE_TO (TREE_VALUE (tmp));	      TREE_TYPE (newdecl) = newtype		= build_cplus_method_type (TYPE_METHOD_BASETYPE (newtype),					   TREE_TYPE (newtype), argtypes);	      error ("constructor cannot take as argument the type being constructed");	      SET_IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl), current_class_type);	    }	}    }  else    {      char *errmsg = redeclaration_error_message (newdecl, olddecl);      if (errmsg)	{	  error_with_decl (newdecl, errmsg);	  if (DECL_NAME (olddecl) != NULL_TREE)	    error_with_decl (olddecl,			     (DECL_INITIAL (olddecl)			      && current_binding_level == global_binding_level)			        ? "`%s' previously defined here"			        : "`%s' previously declared here");	}      else if (TREE_CODE (olddecl) == FUNCTION_DECL	       && DECL_INITIAL (olddecl) != 0	       && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == 0	       && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != 0)	{	  /* Prototype decl follows defn w/o prototype.  */	  warning_with_decl (newdecl, "prototype for `%s'");	  warning_with_decl (olddecl,			     "follows non-prototype definition here");	}      /* These bits are logically part of the type.  */      if (pedantic	  && (TREE_READONLY (newdecl) != TREE_READONLY (olddecl)	      || TREE_THIS_VOLATILE (newdecl) != TREE_THIS_VOLATILE (olddecl)))	error_with_decl (newdecl, "type qualifiers for `%s' conflict with previous decl");    }  /* Deal with C++: must preserve virtual function table size.  */  if (TREE_CODE (olddecl) == TYPE_DECL)    {      if (TYPE_LANG_SPECIFIC (TREE_TYPE

⌨️ 快捷键说明

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