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

📄 cp-decl2.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
      else if (!strcmp (p, "traditional"))	warn_traditional = setting;      else if (!strcmp (p, "char-subscripts"))	warn_char_subscripts = setting;      else if (!strcmp (p, "pointer-arith"))	warn_pointer_arith = setting;      else if (!strcmp (p, "strict-prototypes"))	warn_strict_prototypes = setting;      else if (!strcmp (p, "missing-prototypes"))	warn_missing_prototypes = setting;      else if (!strcmp (p, "redundant-decls"))	warn_redundant_decls = setting;      else if (!strcmp (p, "format"))	warn_format = setting;      else if (!strcmp (p, "conversion"))	warn_conversion = setting;      else if (!strcmp (p, "parentheses"))	warn_parentheses = setting;      else if (!strcmp (p, "comment"))	;			/* cpp handles this one.  */      else if (!strcmp (p, "comments"))	;			/* cpp handles this one.  */      else if (!strcmp (p, "trigraphs"))	;			/* cpp handles this one.  */      else if (!strcmp (p, "import"))	;			/* cpp handles this one.  */      else if (!strcmp (p, "all"))	{	  extra_warnings = setting;	  explicit_warn_return_type = setting;	  warn_unused = setting;	  warn_implicit = setting;	  warn_switch = setting;	  warn_uninitialized = setting;#if 0	  warn_enum_clash = setting;#endif	}      else if (!strcmp (p, "overloaded-virtual"))	warn_overloaded_virtual = setting;      else if (!strcmp (p, "enum-clash"))	warn_enum_clash = setting;      else return 0;    }  else if (!strcmp (p, "-ansi"))    flag_no_asm = 1, dollars_in_ident = 0, flag_ansi = 1;#ifdef SPEW_DEBUG  /* Undocumented, only ever used when you're invoking cc1plus by hand, since     it's probably safe to assume no sane person would ever want to use this     under normal circumstances.  */  else if (!strcmp (p, "-spew-debug"))    spew_debug = 1;#endif  else    return 0;  return 1;}/* Incorporate `const' and `volatile' qualifiers for member functions.   FUNCTION is a TYPE_DECL or a FUNCTION_DECL.   QUALS is a list of qualifiers.  */treegrok_method_quals (ctype, function, quals)     tree ctype, function, quals;{  tree fntype = TREE_TYPE (function);  tree raises = TYPE_RAISES_EXCEPTIONS (fntype);  do    {      extern tree ridpointers[];      if (TREE_VALUE (quals) == ridpointers[(int)RID_CONST])	{	  if (TYPE_READONLY (ctype))	    error ("duplicate `%s' %s",		   IDENTIFIER_POINTER (TREE_VALUE (quals)),		   (TREE_CODE (function) == FUNCTION_DECL		    ? "for member function" : "in type declaration"));	  ctype = build_type_variant (ctype, 1, TYPE_VOLATILE (ctype));	  build_pointer_type (ctype);	}      else if (TREE_VALUE (quals) == ridpointers[(int)RID_VOLATILE])	{	  if (TYPE_VOLATILE (ctype))	    error ("duplicate `%s' %s",		   IDENTIFIER_POINTER (TREE_VALUE (quals)),		   (TREE_CODE (function) == FUNCTION_DECL		    ? "for member function" : "in type declaration"));	  ctype = build_type_variant (ctype, TYPE_READONLY (ctype), 1);	  build_pointer_type (ctype);	}      else	my_friendly_abort (20);      quals = TREE_CHAIN (quals);    }  while (quals);  fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype),				    (TREE_CODE (fntype) == METHOD_TYPE				     ? TREE_CHAIN (TYPE_ARG_TYPES (fntype))				     : TYPE_ARG_TYPES (fntype)));  if (raises)    fntype = build_exception_variant (ctype, fntype, raises);  TREE_TYPE (function) = fntype;  return ctype;}/* This routine replaces cryptic DECL_NAMEs with readable DECL_NAMEs.   It leaves DECL_ASSEMBLER_NAMEs with the correct value.  *//* This does not yet work with user defined conversion operators   It should.  */static voidsubstitute_nice_name (decl)     tree decl;{  if (DECL_NAME (decl) && TREE_CODE (DECL_NAME (decl)) == IDENTIFIER_NODE)    {      extern char *decl_as_string ();      char *n = decl_as_string (DECL_NAME (decl));      if (n[strlen (n) - 1] == ' ')	n[strlen (n) - 1] = 0;      DECL_NAME (decl) = get_identifier (n);    }}/* Classes overload their constituent function names automatically.   When a function name is declared in a record structure,   its name is changed to it overloaded name.  Since names for   constructors and destructors can conflict, we place a leading   '$' for destructors.   CNAME is the name of the class we are grokking for.   FUNCTION is a FUNCTION_DECL.  It was created by `grokdeclarator'.   FLAGS contains bits saying what's special about today's   arguments.  1 == DESTRUCTOR.  2 == OPERATOR.   If FUNCTION is a destructor, then we must add the `auto-delete' field   as a second parameter.  There is some hair associated with the fact   that we must "declare" this variable in the manner consistent with the   way the rest of the arguments were declared.   If FUNCTION is a constructor, and we are doing SOS hacks for dynamic   classes, then the second hidden argument is the virtual function table   pointer with which to initialize the object.   QUALS are the qualifiers for the this pointer.  */voidgrokclassfn (ctype, cname, function, flags, quals)     tree ctype, cname, function;     enum overload_flags flags;     tree quals;{  tree fn_name = DECL_NAME (function);  tree arg_types;  tree parm;  char *name;  if (fn_name == NULL_TREE)    {      error ("name missing for member function");      fn_name = get_identifier ("<anonymous>");      DECL_NAME (function) = fn_name;    }  if (quals)    ctype = grok_method_quals (ctype, function, quals);  arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));  if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE)    {      /* Must add the class instance variable up front.  */      /* Right now we just make this a pointer.  But later	 we may wish to make it special.  */      tree type = TREE_VALUE (arg_types);      if (flags == DTOR_FLAG)	type = TYPE_MAIN_VARIANT (type);      else if (DECL_CONSTRUCTOR_P (function))	{	  if (TYPE_DYNAMIC (ctype))	    {	      parm = build_decl (PARM_DECL, get_identifier (AUTO_VTABLE_NAME), TYPE_POINTER_TO (ptr_type_node));	      TREE_USED (parm) = 1;	      TREE_READONLY (parm) = 1;	      DECL_ARG_TYPE (parm) = TYPE_POINTER_TO (ptr_type_node);	      TREE_CHAIN (parm) = last_function_parms;	      last_function_parms = parm;	    }	  if (TYPE_USES_VIRTUAL_BASECLASSES (ctype))	    {	      DECL_CONSTRUCTOR_FOR_VBASE_P (function) = 1;	      /* In this case we need "in-charge" flag saying whether		 this constructor is responsible for initialization		 of virtual baseclasses or not.  */	      parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node);	      DECL_ARG_TYPE (parm) = integer_type_node;	      DECL_REGISTER (parm) = 1;	      TREE_CHAIN (parm) = last_function_parms;	      last_function_parms = parm;	    }	}      parm = build_decl (PARM_DECL, this_identifier, type);      /* Mark the artificial `this' parameter as "artificial".  */      DECL_SOURCE_LINE (parm) = 0;      DECL_ARG_TYPE (parm) = type;      /* We can make this a register, so long as we don't	 accidentally complain if someone tries to take its address.  */      DECL_REGISTER (parm) = 1;#if 0      /* it is wrong to flag the object as readonly, when	 flag_this_is_variable is 0. */      if (flags != DTOR_FLAG	  && (flag_this_is_variable <= 0 || TYPE_READONLY (type)))#else      if (flags != DTOR_FLAG && TYPE_READONLY (type))#endif	TREE_READONLY (parm) = 1;      TREE_CHAIN (parm) = last_function_parms;      last_function_parms = parm;    }  if (flags == DTOR_FLAG)    {      char *buf, *dbuf;      tree const_integer_type = build_type_variant (integer_type_node, 1, 0);      int len = sizeof (DESTRUCTOR_DECL_PREFIX)-1;      arg_types = hash_tree_chain (const_integer_type, void_list_node);      /* Build the overload name.  It will look like e.g. 7Example.  */      if (IDENTIFIER_TYPE_VALUE (cname))	dbuf = build_overload_name (IDENTIFIER_TYPE_VALUE (cname), 1, 1);      else if (IDENTIFIER_LOCAL_VALUE (cname))	dbuf = build_overload_name (TREE_TYPE (IDENTIFIER_LOCAL_VALUE (cname)), 1, 1);      else	my_friendly_abort (346);      buf = (char *)alloca (strlen (dbuf) + sizeof (DESTRUCTOR_DECL_PREFIX));      bcopy (DESTRUCTOR_DECL_PREFIX, buf, len);      buf[len] = '\0';      strcat (buf, dbuf);      DECL_ASSEMBLER_NAME (function) = get_identifier (buf);      parm = build_decl (PARM_DECL, in_charge_identifier, const_integer_type);      TREE_USED (parm) = 1;      TREE_READONLY (parm) = 1;      DECL_ARG_TYPE (parm) = const_integer_type;      /* This is the same chain as DECL_ARGUMENTS (...).  */      TREE_CHAIN (last_function_parms) = parm;      TREE_TYPE (function) = build_cplus_method_type (ctype, void_type_node, arg_types);      TYPE_HAS_DESTRUCTOR (ctype) = 1;    }  else    {      tree these_arg_types;      if (TYPE_DYNAMIC (ctype) && DECL_CONSTRUCTOR_P (function))	{	  arg_types = hash_tree_chain (build_pointer_type (ptr_type_node),				       TREE_CHAIN (arg_types));	  TREE_TYPE (function)	    = build_cplus_method_type (ctype, TREE_TYPE (TREE_TYPE (function)), arg_types);	  arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));	}      if (DECL_CONSTRUCTOR_FOR_VBASE_P (function))	{	  arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types));	  TREE_TYPE (function)	    = build_cplus_method_type (ctype, TREE_TYPE (TREE_TYPE (function)), arg_types);	  arg_types = TYPE_ARG_TYPES (TREE_TYPE (function));	}      these_arg_types = arg_types;      if (TREE_CODE (TREE_TYPE (function)) == FUNCTION_TYPE)	/* Only true for static member functions.  */	these_arg_types = hash_tree_chain (TYPE_POINTER_TO (ctype), arg_types);      DECL_ASSEMBLER_NAME (function)	= build_decl_overload (fn_name, these_arg_types,			       1 + DECL_CONSTRUCTOR_P (function));#if 0      /* This code is going into the compiler, but currently, it makes	 libg++/src/Interger.cc not compile.  The problem is that the nice name	 winds up going into the symbol table, and conversion operations look	 for the manged name.  */      substitute_nice_name (function);#endif#if 0      if (flags == TYPENAME_FLAG)	/* Not exactly an IDENTIFIER_TYPE_VALUE.  */	TREE_TYPE (DECL_ASSEMBLER_NAME (function)) = TREE_TYPE (fn_name);#endif    }  DECL_ARGUMENTS (function) = last_function_parms;  /* First approximations.  */  DECL_CONTEXT (function) = ctype;  DECL_CLASS_CONTEXT (function) = ctype;}/* Sanity check: report error if this function FUNCTION is not   really a member of the class (CTYPE) it is supposed to belong to.   CNAME and FLAGS are the same here as they are for grokclassfn above.  */voidcheck_classfn (ctype, cname, function, flags)     tree ctype, cname, function;     int flags;{  tree fn_name = DECL_NAME (function);  tree fndecl;  int need_quotes = 0;  char *err_name;  tree method_vec = CLASSTYPE_METHOD_VEC (ctype);  tree *methods = 0;  tree *end = 0;  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 == cname)	goto got_it;      while (++methods != end)	{	  if (fn_name == DECL_NAME (*methods))	    {	    got_it:	      fndecl = *methods;	      while (fndecl)		{		  if (DECL_ASSEMBLER_NAME (function) == DECL_ASSEMBLER_NAME (fndecl))		    return;		  fndecl = DECL_CHAIN (fndecl);		}	      break;		/* loser */	    }	}    }  if (fn_name == ansi_opname[(int) TYPE_EXPR])    {      if (TYPE_HAS_CONVERSION (ctype))	err_name = "such type conversion operator";    }  else if (IDENTIFIER_OPNAME_P (fn_name))    {      err_name = (char *)alloca (1024);      sprintf (err_name, "`operator %s'", operator_name_string (fn_name));    }  else    {      err_name = IDENTIFIER_POINTER (fn_name);      need_quotes = 1;    }  if (methods != end)    if (need_quotes)      error ("argument list for `%s' does not match any in class", err_name);    else      error ("argument list for %s does not match any in class", err_name);  else    {      methods = 0;      if (need_quotes)	error ("no `%s' member function declared in class", err_name);      else	error ("no %s declared in class", err_name);    }  /* If we did not find the method in the class, add it to     avoid spurious errors.  */  add_method (ctype, methods, function);}/* 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, raises, init, asmspec_tree)     tree declarator, declspecs, raises, init;     tree asmspec_tree;{  register tree value;  char *asmspec = 0;  /* 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);    }  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, raises);  if (! value)    return NULL_TREE; /* friends went bad.  */  /* Pass friendly classes back.  */  if (TREE_CODE (value) == VOID_TYPE)    return void_type_node;  if (DECL_NAME (value) != NULL_TREE

⌨️ 快捷键说明

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