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

📄 cp-lex.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidstore_pending_inline (decl, t)     tree decl;     struct pending_inline *t;{  extern int processing_template_defn;  int delay_to_eof = 0;  struct pending_inline **inlines;  t->fndecl = decl;  /* Default: compile right away, and no extra bindings are needed.  */  t->parm_vec = t->bindings = 0;  if (processing_template_defn)    {      tree type = current_class_type;      /* Assumption: In this (possibly) nested class sequence, only	 one name will have template parms.  */      while (type && TREE_CODE_CLASS (TREE_CODE (type)) == 't')	{	  tree decl = TYPE_NAME (type);	  tree tmpl = IDENTIFIER_TEMPLATE (DECL_NAME (decl));	  if (tmpl)	    {	      t->parm_vec = DECL_TEMPLATE_INFO (TREE_PURPOSE (tmpl))->parm_vec;	      t->bindings = TREE_VALUE (tmpl);	    }	  type = DECL_CONTEXT (decl);	}      if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE	  || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)	{	  if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)	    my_friendly_assert (TYPE_MAX_VALUE (TREE_TYPE (decl)) == current_class_type,				233);	  /* Inline functions can be compiled immediately.  Other functions	     will be output separately, so if we're in interface-only mode,	     punt them now, or output them now if we're doing implementations	     and we know no overrides will exist.  Otherwise, we delay until	     end-of-file, to see if the definition is really required.  */	  if (DECL_INLINE (decl))	    /* delay_to_eof == 0 */;	  else if (current_class_type && !interface_unknown)	    {	      if (interface_only)		{#if 0		  print_node_brief (stderr, "\ndiscarding text for ", decl, 0);#endif		  if (t->can_free)		    obstack_free (&inline_text_obstack, t->buf);		  DECL_PENDING_INLINE_INFO (decl) = 0;		  return;		}	    }	  /* Don't delay the processing of virtual functions.  */	  else if (DECL_VINDEX (decl) == NULL_TREE)	    delay_to_eof = 1;	}      else	my_friendly_abort (58);    }  if (delay_to_eof)    {      extern struct pending_inline *pending_template_expansions;      if (t->can_free)	{	  char *free_to = t->buf;	  t->buf = (char *) obstack_copy (&permanent_obstack, t->buf,					  t->len + 1);	  t = (struct pending_inline *) obstack_copy (&permanent_obstack, 						      (char *)t, sizeof (*t));	  obstack_free (&inline_text_obstack, free_to);	}      inlines = &pending_template_expansions;      t->can_free = 0;    }  else    {      inlines = &pending_inlines;      DECL_PENDING_INLINE_INFO (decl) = t;    }  /* Because we use obstacks, we must process these in precise order.  */  t->next = *inlines;  *inlines = t;}void reinit_parse_for_block ();voidreinit_parse_for_method (yychar, decl)     int yychar;     tree decl;{  int len;  int starting_lineno = lineno;  char *starting_filename = input_filename;  reinit_parse_for_block (yychar, &inline_text_obstack, 0);  len = obstack_object_size (&inline_text_obstack);  current_base_init_list = NULL_TREE;  current_member_init_list = NULL_TREE;  if (decl == void_type_node      || (current_class_type && TYPE_REDEFINED (current_class_type)))    {      /* Happens when we get two declarations of the same	 function in the same scope.  */      char *buf = obstack_finish (&inline_text_obstack);      obstack_free (&inline_text_obstack, buf);      return;    }  else    {      struct pending_inline *t;      char *buf = obstack_finish (&inline_text_obstack);      t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,						   sizeof (struct pending_inline));      t->buf = buf;      t->len = len;      t->lineno = starting_lineno;      t->filename = starting_filename;      t->token = YYEMPTY;      t->can_free = 1;      t->deja_vu = 0;      t->interface = ((interface_unknown || processing_template_defn)		      ? 1		      : (interface_only ? 0 : 2));      store_pending_inline (decl, t);    }}/* Consume a block -- actually, a method or template definition beginning   with `:' or `{' -- and save it away on the specified obstack.   Argument IS_TEMPLATE indicates which set of error messages should be   output if something goes wrong.  This should really be cleaned up somehow,   without loss of clarity.  */voidreinit_parse_for_block (yychar, obstackp, is_template)     int yychar;     struct obstack *obstackp;     int is_template;{  register int c = 0;  int blev = 1;  int starting_lineno = lineno;  char *starting_filename = input_filename;  int len;  int look_for_semicolon = 0;  if (yychar == '{')    obstack_1grow (obstackp, '{');  else if (yychar == '=')    {      look_for_semicolon = 1;    }  else    {      if (yychar != ':' && (yychar != RETURN || is_template))	{	  yyerror (is_template		   ? "parse error in template specification"		   : "parse error in method specification");	  yychar = '{';	}      obstack_1grow (obstackp, yychar);      while (c >= 0)	{	  int this_lineno = lineno;	  c = yynextch ();	  /* Don't lose our cool if there are lots of comments.  */	  if (lineno == this_lineno)	    ;	  else if (lineno - this_lineno < 10 /* + strlen (input_filename) */)	    {	      int i;	      for (i = lineno - this_lineno; i > 0; i--)		obstack_1grow (obstackp, '\n');	    }	  else	    {	      char buf[12];	      sprintf (buf, "\n# %d \"", lineno);	      len = strlen (buf);	      obstack_grow (obstackp, buf, len);	      len = strlen (input_filename);	      obstack_grow (obstackp, input_filename, len);	      obstack_1grow (obstackp, '\"');	      obstack_1grow (obstackp, '\n');	    }	  /* strings must be read differently than text.  */	  if (c == '\"')	    {	      obstack_1grow (obstackp, c);	      consume_string (obstackp);	      c = yynextch ();	    }	  while (c > ' ')	/* ASCII dependent! */	    {	      obstack_1grow (obstackp, c);	      if (c == '{') goto main_loop;	      if (c == '\"')		consume_string (obstackp);	      if (c == ';')		{		  error (is_template			 ? "template body missing"			 : "function body for constructor missing");		  obstack_1grow (obstackp, '{');		  obstack_1grow (obstackp, '}');		  len += 2;		  goto done;		}	      c = getch ();	    }	  if (c == '\n')	    lineno++;	  obstack_1grow (obstackp, c);	}      if (c == EOF)	{	  error_with_file_and_line (starting_filename,				    starting_lineno,				    "end of file read inside definition");	}	      } main_loop:  while (c >= 0)    {      int this_lineno = lineno;      c = skip_white_space (getch ());      /* Don't lose our cool if there are lots of comments.  */      if (lineno - this_lineno)	if (lineno - this_lineno == 1)	  obstack_1grow (obstackp, '\n');	else	  {	    char buf[12];	    sprintf (buf, "\n# %d \"", lineno);	    len = strlen (buf);	    obstack_grow (obstackp, buf, len);	    len = strlen (input_filename);	    obstack_grow (obstackp, input_filename, len);	    obstack_1grow (obstackp, '\"');	    obstack_1grow (obstackp, '\n');	  }      while (c > ' ')	{	  obstack_1grow (obstackp, c);	  if (c == '{') blev++;	  else if (c == '}')	    {	      blev--;	      if (blev == 0 && !look_for_semicolon)		goto done;	    }	  else if (c == '\"')	    consume_string (obstackp);	  else if (c == ';' && look_for_semicolon && blev == 0)	    goto done;	  c = getch ();	}      if (c == '\n')	lineno++;      obstack_1grow (obstackp, c);    } done:  obstack_1grow (obstackp, '\0');}/* Build a default function named NAME for type TYPE.   KIND says what to build.   When KIND == 0, build default destructor.   When KIND == 1, build virtual destructor.   When KIND == 2, build default constructor.   When KIND == 3, build default X(const X&) constructor.   When KIND == 4, build default X(X&) constructor.  */treecons_up_default_function (type, name, kind)     tree type, name;     int kind;{  extern tree void_list_node, constructor_name ();  int len;  tree declspecs = NULL_TREE;  tree fn, args;  tree argtype;  name = constructor_name (name);  switch (kind)    {      /* Destructors.  */    case 1:      declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]);      /* Fall through...  */    case 0:      name = build_parse_node (BIT_NOT_EXPR, name);      /* Fall through...  */    case 2:      /* Default constructor.  */      args = void_list_node;      break;    case 3:      type = build_type_variant (type, 1, 0);      /* Fall through...  */    case 4:      argtype = build_reference_type (type);      args = tree_cons (NULL_TREE,			build_tree_list (hash_tree_chain (argtype, NULL_TREE),					 get_identifier ("arg")),			void_list_node);      break;    default:      my_friendly_abort (59);    }  fn = start_method (declspecs,		     build_parse_node (CALL_EXPR, name, args, NULL_TREE),		     NULL_TREE);  if (fn == void_type_node)    return fn;  current_base_init_list = NULL_TREE;  current_member_init_list = NULL_TREE;  len = 3;  {    struct pending_inline *t;    t = (struct pending_inline *) obstack_alloc (&inline_text_obstack,						 sizeof (struct pending_inline));    t->buf = default_def;    t->len = len;    t->lineno = lineno;    t->filename = input_filename;    t->token = YYEMPTY;    t->can_free = 0;    t->deja_vu = 0;    t->interface = ((interface_unknown || processing_template_defn)		    ? 1		    : (interface_only ? 0 : 2));    store_pending_inline (fn, t);    /* We make this declaration private (static in the C sense).  */    TREE_PUBLIC (fn) = 0;  }  finish_method (fn);  DECL_CLASS_CONTEXT (fn) = type;  /* Show that this function was generated by the compiler.  */  DECL_SOURCE_LINE (fn) = 0;  return fn;}/* Heuristic to tell whether the user is missing a semicolon   after a struct or enum declaration.  Emit an error message   if we know the user has blown it.  */voidcheck_for_missing_semicolon (type)     tree type;{  if (yychar < 0)    yychar = yylex ();  if (yychar > 255      && yychar != IDENTIFIER      && yychar != TYPENAME)    {      if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))	error ("semicolon missing after %s declaration",	       TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");      else	error ("semicolon missing after declaration of `%s'",	       TYPE_NAME_STRING (type));      shadow_tag (build_tree_list (0, type));    }  /* Could probably also hack cases where class { ... } f (); appears.  */  clear_anon_tags ();}voidnote_got_semicolon (type)     tree type;{  if (TREE_CODE_CLASS (TREE_CODE (type)) != 't')    my_friendly_abort (60);  if (IS_AGGR_TYPE (type))    CLASSTYPE_GOT_SEMICOLON (type) = 1;}voidnote_list_got_semicolon (declspecs)     tree declspecs;{  tree link;  for (link = declspecs; link; link = TREE_CHAIN (link))    {      tree type = TREE_VALUE (link);      if (TREE_CODE_CLASS (TREE_CODE (type)) == 't')	note_got_semicolon (type);    }  clear_anon_tags ();}/* If C is not whitespace, return C.   Otherwise skip whitespace and return first nonwhite char read.  */static intskip_white_space (c)     register int c;{  for (;;)    {      switch (c)	{	case '\n':	  c = check_newline ();	  break;	case ' ':	case '\t':	case '\f':

⌨️ 快捷键说明

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