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

📄 decl2.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      error ("cannot delete a function");      return error_mark_node;    }  /* Deleting ptr to void is undefined behaviour [expr.delete/3].  */  if (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE)    cp_warning ("`%T' is not a pointer-to-object type", type);    /* An array can't have been allocated by new, so complain.  */  if (TREE_CODE (t) == ADDR_EXPR      && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL      && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE)    cp_warning ("deleting array `%#D'", TREE_OPERAND (t, 0));  /* Deleting a pointer with the value zero is valid and has no effect.  */  if (integer_zerop (t))    return build1 (NOP_EXPR, void_type_node, t);  if (doing_vec)    return build_vec_delete (t, maxindex, integer_one_node,			     integer_zero_node, use_global_delete);  else    {      if (IS_AGGR_TYPE (TREE_TYPE (type))	  && TYPE_GETS_REG_DELETE (TREE_TYPE (type)))	{	  /* Only do access checking here; we'll be calling op delete	     from the destructor.  */	  tree tmp = build_op_delete_call (DELETE_EXPR, t, size_zero_node,					   LOOKUP_NORMAL, NULL_TREE);	  if (tmp == error_mark_node)	    return error_mark_node;	}      return build_delete (type, t, integer_three_node,			   LOOKUP_NORMAL, use_global_delete);    }}/* Report an error if the indicated template declaration is not the   sort of thing that should be a member template.  */voidcheck_member_template (tmpl)     tree tmpl;{  tree decl;  my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);  decl = DECL_TEMPLATE_RESULT (tmpl);  if (TREE_CODE (decl) == FUNCTION_DECL      || (TREE_CODE (decl) == TYPE_DECL	  && IS_AGGR_TYPE (TREE_TYPE (decl))))    {      if (current_function_decl)	/* 14.5.2.2 [temp.mem]	   	   A local class shall not have member templates. */	cp_error ("declaration of member template `%#D' in local class",		  decl);            if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl))	{	  /* 14.5.2.3 [temp.mem]	     A member function template shall not be virtual.  */	  cp_error 	    ("invalid use of `virtual' in template declaration of `%#D'",	     decl);	  DECL_VIRTUAL_P (decl) = 0;	}      /* The debug-information generating code doesn't know what to do	 with member templates.  */       DECL_IGNORED_P (tmpl) = 1;    }   else    cp_error ("template declaration of `%#D'", decl);}/* Return true iff TYPE is a valid Java parameter or return type. */static intacceptable_java_type (type)     tree type;{  if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type))    return 1;  if (TREE_CODE (type) == POINTER_TYPE)    {      type = TREE_TYPE (type);      if (TREE_CODE (type) == RECORD_TYPE)	{	  tree args;  int i;	  if (! TYPE_FOR_JAVA (type))	    return 0;	  if (! CLASSTYPE_TEMPLATE_INFO (type))	    return 1;	  args = CLASSTYPE_TI_ARGS (type);	  i = TREE_VEC_LENGTH (args);	  while (--i >= 0)	    {	      type = TREE_VEC_ELT (args, i);	      if (TREE_CODE (type) == POINTER_TYPE)		type = TREE_TYPE (type);	      if (! TYPE_FOR_JAVA (type))		return 0;	    }	  return 1;	}    }  return 0;}/* For a METHOD in a Java class CTYPE, return 1 if   the parameter and return types are valid Java types.   Otherwise, print appropriate error messages, and return 0.  */intcheck_java_method (method)     tree method;{  int jerr = 0;  tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method));  tree ret_type = TREE_TYPE (TREE_TYPE (method));  if (! acceptable_java_type (ret_type))    {      cp_error ("Java method '%D' has non-Java return type `%T'",		method, ret_type);      jerr++;    }  for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types))    {      tree type = TREE_VALUE (arg_types);      if (! acceptable_java_type (type))	{	  cp_error ("Java method '%D' has non-Java parameter type `%T'",		    method, type);	  jerr++;	}    }  return jerr ? 0 : 1;}/* Sanity check: report error if this function FUNCTION is not   really a member of the class (CTYPE) it is supposed to belong to.   CNAME is the same here as it is for grokclassfn above.  */treecheck_classfn (ctype, function)     tree ctype, function;{  tree fn_name = DECL_NAME (function);  tree fndecl, fndecls;  tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype));  tree *methods = 0;  tree *end = 0;    if (DECL_USE_TEMPLATE (function)      && is_member_template (DECL_TI_TEMPLATE (function)))    /* Since this is a specialization of a member template,       we're not going to find the declaration in the class.       For example, in:                struct S { template <typename T> void f(T); };         template <> void S::f(int);              we're not going to find `S::f(int)', but there's no       reason we should, either.  We let our callers know we didn't       find the method, but we don't complain.  */    return NULL_TREE;        if (method_vec != 0)    {      methods = &TREE_VEC_ELT (method_vec, 0);      end = TREE_VEC_END (method_vec);      /* First suss out ctors and dtors.  */      if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))	  && DECL_CONSTRUCTOR_P (function))	goto got_it;      if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods))	  && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function)))	goto got_it;      while (++methods != end && *methods)	{	  fndecl = *methods;	  if (fn_name == DECL_NAME (OVL_CURRENT (*methods)))	    {	    got_it:	      for (fndecls = *methods; fndecls != NULL_TREE;		   fndecls = OVL_NEXT (fndecls))		{		  fndecl = OVL_CURRENT (fndecls);		  /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or		     for a for member function of a template class, is		     not mangled, so the check below does not work		     correctly in that case.  Since mangled destructor		     names do not include the type of the arguments,		     we can't use this short-cut for them, either.		     (It's not legal to declare arguments for a		     destructor, but some people try.)  */		  if (!DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))		      && (DECL_ASSEMBLER_NAME (function)			  != DECL_NAME (function))		      && (DECL_ASSEMBLER_NAME (fndecl)			  != DECL_NAME (fndecl))		      && (DECL_ASSEMBLER_NAME (function) 			  == DECL_ASSEMBLER_NAME (fndecl)))		    return fndecl;		  /* We cannot simply call decls_match because this		     doesn't work for static member functions that are                      pretending to be methods, and because the name		     may have been changed by asm("new_name").  */ 		  if (DECL_NAME (function) == DECL_NAME (fndecl))		    {		      tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function));		      tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl));		      /* Get rid of the this parameter on functions that become			 static.  */		      if (DECL_STATIC_FUNCTION_P (fndecl)			  && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)			p1 = TREE_CHAIN (p1);		      if (same_type_p (TREE_TYPE (TREE_TYPE (function)),				       TREE_TYPE (TREE_TYPE (fndecl)))			  && compparms (p1, p2)			  && (DECL_TEMPLATE_SPECIALIZATION (function)			      == DECL_TEMPLATE_SPECIALIZATION (fndecl))			  && (!DECL_TEMPLATE_SPECIALIZATION (function)			      || (DECL_TI_TEMPLATE (function) 				  == DECL_TI_TEMPLATE (fndecl))))			return fndecl;		    }		}	      break;		/* loser */	    }	}    }  if (methods != end && *methods)    {      tree fndecl = *methods;      cp_error ("prototype for `%#D' does not match any in class `%T'",		function, ctype);      cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is",		   OVL_CURRENT (fndecl));      while (fndecl = OVL_NEXT (fndecl), fndecl)	cp_error_at ("                %#D", OVL_CURRENT(fndecl));    }  else    {      methods = 0;      if (TYPE_SIZE (ctype) == 0)        incomplete_type_error (function, ctype);      else        cp_error ("no `%#D' member function declared in class `%T'",		  function, ctype);    }  /* If we did not find the method in the class, add it to avoid     spurious errors (unless the CTYPE is not yet defined, in which     case we'll only confuse ourselves when the function is declared     properly within the class.  */  if (TYPE_SIZE (ctype))    add_method (ctype, methods, function);  return NULL_TREE;}/* We have just processed the DECL, which is a static data member.   Its initializer, if present, is INIT.  The ASMSPEC_TREE, if   present, is the assembly-language name for the data member.   NEED_POP and FLAGS are as for cp_finish_decl.  */voidfinish_static_data_member_decl (decl, init, asmspec_tree, need_pop, flags)     tree decl;     tree init;     tree asmspec_tree;     int need_pop;     int flags;{  char* asmspec = 0;  if (asmspec_tree)    asmspec = TREE_STRING_POINTER (asmspec_tree);  my_friendly_assert (TREE_PUBLIC (decl), 0);  /* We cannot call pushdecl here, because that would fill in the     decl of our TREE_CHAIN.  Instead, we modify cp_finish_decl to do     the right thing, namely, to put this decl out straight away.  */  /* current_class_type can be NULL_TREE in case of error.  */  if (!asmspec && current_class_type)    {      DECL_INITIAL (decl) = error_mark_node;      DECL_ASSEMBLER_NAME (decl)	= build_static_name (current_class_type, DECL_NAME (decl));    }  if (! processing_template_decl)    {      if (!pending_statics)	VARRAY_TREE_INIT (pending_statics, 32, "pending_statics");	      if (pending_statics_used == pending_statics->num_elements)	VARRAY_GROW (pending_statics, 		     2 * pending_statics->num_elements);      VARRAY_TREE (pending_statics, pending_statics_used) = decl;      ++pending_statics_used;    }  /* Static consts need not be initialized in the class definition.  */  if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))    {      static int explanation = 0;	        error ("initializer invalid for static member with constructor");      if (explanation++ == 0)	error ("(you really want to initialize it separately)");      init = 0;    }  /* Force the compiler to know when an uninitialized static const     member is being used.  */  if (CP_TYPE_CONST_P (TREE_TYPE (decl)) && init == 0)    TREE_USED (decl) = 1;  DECL_INITIAL (decl) = init;  DECL_IN_AGGR_P (decl) = 1;  DECL_CONTEXT (decl) = current_class_type;  DECL_CLASS_CONTEXT (decl) = current_class_type;  cp_finish_decl (decl, init, asmspec_tree, need_pop, flags);}/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted)   of a structure component, returning a FIELD_DECL node.   QUALS is a list of type qualifiers for this decl (such as for declaring   const member functions).   This is done during the parsing of the struct declaration.   The FIELD_DECL nodes are chained together and the lot of them   are ultimately passed to `build_struct' to make the RECORD_TYPE node.   C++:   If class A defines that certain functions in class B are friends, then   the way I have set things up, it is B who is interested in permission   granted by A.  However, it is in A's context that these declarations   are parsed.  By returning a void_type_node, class A does not attempt   to incorporate the declarations of the friends within its structure.   DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING   CHANGES TO CODE IN `start_method'.  */treegrokfield (declarator, declspecs, init, asmspec_tree, attrlist)     tree declarator, declspecs, init, asmspec_tree, attrlist;{  register tree value;  char *asmspec = 0;  int flags = LOOKUP_ONLYCONVERTING;  /* Convert () initializers to = initializers.  */  if (init == NULL_TREE && declarator != NULL_TREE      && TREE_CODE (declarator) == CALL_EXPR      && TREE_OPERAND (declarator, 0)      && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE	  || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF)      && parmlist_is_exprlist (TREE_OPERAND (declarator, 1)))    {      init = TREE_OPERAND (declarator, 1);      declarator = TREE_OPERAND (declarator, 0);      flags = 0;    }  if (declspecs == NULL_TREE      && TREE_CODE (declarator) == SCOPE_REF      && TREE_CODE (TREE_OPERAND (declarator, 1)) == IDENTIFIER_NODE)    {      /* Access declaration */      if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0))))	;      else if (TREE_COMPLEXITY (declarator) == current_class_depth)	pop_nested_class ();      return do_class_using_decl (declarator);    }  if (init      && TREE_CODE (init) == TREE_LIST      && TREE_VALUE (init) == error_mark_node      && TREE_CHAIN (init) == NULL_TREE)    init = NULL_TREE;  value = grokdeclarator (declarator, declspecs, FIELD, init != 0, attrlist);  if (! value || value == error_mark_node)    /* friend or constructor went bad.  */    return value;  /* Pass friendly classes back.  */  if (TREE_CODE (value) == VOID_TYPE)    return void_type_node;  if (DECL_NAME (value) != NULL_TREE      && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_'      && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr"))    cp_error ("member `%D' conflicts with virtual function table field name",	      value);  /* Stash away type declarations.  */  if (TREE_CODE (value) == TYPE_DECL)    {      DECL_NONLOCAL (value) = 1;      DECL_CONTEXT (value) = current_class_type;      DECL_CLASS_CONTEXT (value) = current_class_type;      /* Now that we've updated the context, we need to remangle the	 name for this TYPE_DECL.  */      DECL_ASSEMBLER_NAME (value) = DECL_NAME (value);      if (!uses_template_parms (value))	DECL_ASSEMBLER_NAME (value) =	  get_identifier (build_overload_name (TREE_TYPE (value), 1, 1));      return value;    }  if (IS_SIGNATURE (current_class_type)      && TREE_CODE (value) != FUNCTION_DECL)    {

⌨️ 快捷键说明

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