]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/lex.c
Merge from pch-branch up to tag pch-commit-20020603.
[gcc.git] / gcc / cp / lex.c
index f295e7ca1925e47d87fc967cc26fc0e1c479c4c0..dad7df6d3b0c94c68d569637ca4f18165f2decdb 100644 (file)
@@ -1,6 +1,6 @@
 /* Separate lexical analyzer for GNU C++.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
 This file is part of GNU CC.
@@ -23,16 +23,12 @@ Boston, MA 02111-1307, USA.  */
 
 /* This file is the lexical analyzer for GNU C++.  */
 
-/* Cause the `yydebug' variable to be defined.  */
-#define YYDEBUG 1
-
 #include "config.h"
 #include "system.h"
 #include "input.h"
 #include "tree.h"
 #include "cp-tree.h"
 #include "cpplib.h"
-#include "c-lex.h"
 #include "lex.h"
 #include "parse.h"
 #include "flags.h"
@@ -53,7 +49,6 @@ extern void yyprint PARAMS ((FILE *, int, YYSTYPE));
 
 static int interface_strcmp PARAMS ((const char *));
 static int *init_cpp_parse PARAMS ((void));
-static void init_reswords PARAMS ((void));
 static void init_cp_pragma PARAMS ((void));
 
 static tree parse_strconst_pragma PARAMS ((const char *, int));
@@ -61,10 +56,7 @@ static void handle_pragma_vtable PARAMS ((cpp_reader *));
 static void handle_pragma_unit PARAMS ((cpp_reader *));
 static void handle_pragma_interface PARAMS ((cpp_reader *));
 static void handle_pragma_implementation PARAMS ((cpp_reader *));
-static void cxx_init PARAMS ((void));
-static void cxx_finish PARAMS ((void));
-static void cxx_init_options PARAMS ((void));
-static void cxx_post_options PARAMS ((void));
+static void handle_pragma_java_exceptions PARAMS ((cpp_reader *));
 
 #ifdef GATHER_STATISTICS
 #ifdef REDUCE_LENGTH
@@ -74,6 +66,7 @@ static int token_cmp PARAMS ((int *, int *));
 #endif
 static int is_global PARAMS ((tree));
 static void init_operators PARAMS ((void));
+static void copy_lang_type PARAMS ((tree));
 
 /* A constraint that can be tested at compile time.  */
 #ifdef __STDC__
@@ -84,10 +77,6 @@ static void init_operators PARAMS ((void));
 
 #include "cpplib.h"
 
-/* Pending language change.
-   Positive is push count, negative is pop count.  */
-int pending_lang_change = 0;
-
 extern int yychar;             /*  the lookahead symbol                */
 extern YYSTYPE yylval;         /*  the semantic value of the           */
                                /*  lookahead symbol                    */
@@ -149,7 +138,7 @@ make_pointer_declarator (cv_qualifiers, target)
   if (target && TREE_CODE (target) == IDENTIFIER_NODE
       && ANON_AGGRNAME_P (target))
     error ("type name expected before `*'");
-  target = build_parse_node (INDIRECT_REF, target);
+  target = build_nt (INDIRECT_REF, target);
   TREE_TYPE (target) = cv_qualifiers;
   return target;
 }
@@ -181,7 +170,7 @@ make_reference_declarator (cv_qualifiers, target)
       if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target))
          error ("type name expected before `&'");
     }
-  target = build_parse_node (ADDR_EXPR, target);
+  target = build_nt (ADDR_EXPR, target);
   TREE_TYPE (target) = cv_qualifiers;
   return target;
 }
@@ -190,11 +179,11 @@ tree
 make_call_declarator (target, parms, cv_qualifiers, exception_specification)
      tree target, parms, cv_qualifiers, exception_specification;
 {
-  target = build_parse_node (CALL_EXPR, target,
-                            tree_cons (parms, cv_qualifiers, NULL_TREE),
-                            /* The third operand is really RTL.  We
-                               shouldn't put anything there.  */
-                            NULL_TREE);
+  target = build_nt (CALL_EXPR, target,
+                    tree_cons (parms, cv_qualifiers, NULL_TREE),
+                    /* The third operand is really RTL.  We
+                       shouldn't put anything there.  */
+                    NULL_TREE);
   CALL_DECLARATOR_EXCEPTION_SPEC (target) = exception_specification;
   return target;
 }
@@ -212,88 +201,27 @@ int interface_only;               /* whether or not current file is only for
 int interface_unknown;         /* whether or not we know this class
                                   to behave according to #pragma interface.  */
 
-/* Tree code classes. */
-
-#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
-
-static char cplus_tree_code_type[] = {
-  'x',
-#include "cp-tree.def"
-};
-#undef DEFTREECODE
-
-/* Table indexed by tree code giving number of expression
-   operands beyond the fixed part of the node structure.
-   Not used for types or decls.  */
-
-#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
-
-static int cplus_tree_code_length[] = {
-  0,
-#include "cp-tree.def"
-};
-#undef DEFTREECODE
-
-/* Names of tree components.
-   Used for printing out the tree and error messages.  */
-#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
-
-static const char *cplus_tree_code_name[] = {
-  "@@dummy",
-#include "cp-tree.def"
-};
-#undef DEFTREECODE
 \f
-/* Each front end provides its own hooks, for toplev.c.  */
-struct lang_hooks lang_hooks = {cxx_init,
-                               cxx_finish,
-                               cxx_init_options,
-                               cxx_decode_option,
-                               cxx_post_options};
-
-/* Post-switch processing.  */
-static void
-cxx_post_options ()
-{
-  cpp_post_options (parse_in);
-}
-
-static void
+/* Initialization before switch parsing.  */
+void
 cxx_init_options ()
 {
-  parse_in = cpp_create_reader (CLK_GNUCXX);
+  c_common_init_options (clk_cplusplus);
 
   /* Default exceptions on.  */
   flag_exceptions = 1;
-  /* Mark as "unspecified".  */
-  flag_bounds_check = -1;
   /* By default wrap lines at 80 characters.  Is getenv ("COLUMNS")
      preferable?  */
-  diagnostic_message_length_per_line = 80;
+  diagnostic_line_cutoff (global_dc) = 80;
   /* By default, emit location information once for every
      diagnostic message.  */
-  set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_ONCE);
-}
-
-static void
-cxx_init ()
-{
-  c_common_lang_init ();
-
-  if (flag_gnu_xref) GNU_xref_begin (input_filename);
-  init_repo (input_filename);
+  diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
 }
 
-static void
+void
 cxx_finish ()
 {
-  if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount);
-}
-
-const char *
-lang_identify ()
-{
-  return "cplusplus";
+  c_common_finish ();
 }
 
 static int *
@@ -317,7 +245,7 @@ operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE];
 
 /* Initialize data structures that keep track of operator names.  */
 
-#define DEF_OPERATOR(NAME, C, NM, OM, AR, AP) \
+#define DEF_OPERATOR(NAME, C, M, AR, AP) \
  CONSTRAINT (C, sizeof "operator " + sizeof NAME <= 256);
 #include "operators.def"
 #undef DEF_OPERATOR
@@ -329,7 +257,7 @@ init_operators ()
   char buffer[256];
   struct operator_name_info_t *oni;
 
-#define DEF_OPERATOR(NAME, CODE, NEW_MANGLING, OLD_MANGLING, ARITY, ASSN_P) \
+#define DEF_OPERATOR(NAME, CODE, MANGLING, ARITY, ASSN_P)                  \
   sprintf (buffer, ISALPHA (NAME[0]) ? "operator %s" : "operator%s", NAME); \
   identifier = get_identifier (buffer);                                            \
   IDENTIFIER_OPNAME_P (identifier) = 1;                                            \
@@ -339,7 +267,7 @@ init_operators ()
         : &operator_name_info[(int) CODE]);                                \
   oni->identifier = identifier;                                                    \
   oni->name = NAME;                                                        \
-  oni->mangled_name = flag_new_abi ? NEW_MANGLING : OLD_MANGLING;
+  oni->mangled_name = MANGLING;
 
 #include "operators.def"
 #undef DEF_OPERATOR
@@ -390,9 +318,9 @@ init_operators ()
 /* The reserved keyword table.  */
 struct resword
 {
-  const char *word;
-  ENUM_BITFIELD(rid) rid : 16;
-  unsigned int disable   : 16;
+  const char *const word;
+  const ENUM_BITFIELD(rid) rid : 16;
+  const unsigned int disable   : 16;
 };
 
 /* Disable mask.  Keywords are disabled if (reswords[i].disable & mask) is
@@ -406,6 +334,8 @@ CONSTRAINT(ridbits_fit, RID_LAST_MODIFIER < sizeof(unsigned long) * CHAR_BIT);
 static const struct resword reswords[] =
 {
   { "_Complex",                RID_COMPLEX,    0 },
+  { "__FUNCTION__",    RID_FUNCTION_NAME, 0 },
+  { "__PRETTY_FUNCTION__", RID_PRETTY_FUNCTION_NAME, 0 },
   { "__alignof",       RID_ALIGNOF,    0 },
   { "__alignof__",     RID_ALIGNOF,    0 },
   { "__asm",           RID_ASM,        0 },
@@ -418,6 +348,7 @@ static const struct resword reswords[] =
   { "__const",         RID_CONST,      0 },
   { "__const__",       RID_CONST,      0 },
   { "__extension__",   RID_EXTENSION,  0 },
+  { "__func__",                RID_C99_FUNCTION_NAME,  0 },
   { "__imag",          RID_IMAGPART,   0 },
   { "__imag__",                RID_IMAGPART,   0 },
   { "__inline",                RID_INLINE,     0 },
@@ -430,6 +361,7 @@ static const struct resword reswords[] =
   { "__restrict__",    RID_RESTRICT,   0 },
   { "__signed",                RID_SIGNED,     0 },
   { "__signed__",      RID_SIGNED,     0 },
+  { "__thread",                RID_THREAD,     0 },
   { "__typeof",                RID_TYPEOF,     0 },
   { "__typeof__",      RID_TYPEOF,     0 },
   { "__volatile",      RID_VOLATILE,   0 },
@@ -511,7 +443,6 @@ static const struct resword reswords[] =
   { "xor_eq",          RID_XOR_EQ,     D_OPNAME },
 
 };
-#define N_reswords (sizeof reswords / sizeof (struct resword))
 
 /* Table mapping from RID_* constants to yacc token numbers.
    Unfortunately we have to have entries for all the keywords in all
@@ -536,6 +467,7 @@ const short rid_to_yy[RID_MAX] =
   /* RID_BOUNDED */    0,
   /* RID_UNBOUNDED */  0,
   /* RID_COMPLEX */    TYPESPEC,
+  /* RID_THREAD */     SCSPEC,
 
   /* C++ */
   /* RID_FRIEND */     SCSPEC,
@@ -588,6 +520,12 @@ const short rid_to_yy[RID_MAX] =
   /* RID_PTRBASE */    0,
   /* RID_PTREXTENT */  0,
   /* RID_PTRVALUE */   0,
+  /* RID_CHOOSE_EXPR */        0,
+  /* RID_TYPES_COMPATIBLE_P */ 0,
+
+  /* RID_FUNCTION_NAME */      VAR_FUNC_NAME,
+  /* RID_PRETTY_FUNCTION_NAME */ VAR_FUNC_NAME,
+  /* RID_c99_FUNCTION_NAME */  VAR_FUNC_NAME,
 
   /* C++ */
   /* RID_BOOL */       TYPESPEC,
@@ -647,7 +585,7 @@ const short rid_to_yy[RID_MAX] =
   /* RID_AT_IMPLEMENTATION */  0
 };
 
-static void
+void
 init_reswords ()
 {
   unsigned int i;
@@ -660,7 +598,7 @@ init_reswords ()
      all the trees it points to are permanently interned in the
      get_identifier hash anyway.  */
   ridpointers = (tree *) xcalloc ((int) RID_MAX, sizeof (tree));
-  for (i = 0; i < N_reswords; i++)
+  for (i = 0; i < ARRAY_SIZE (reswords); i++)
     {
       id = get_identifier (reswords[i].word);
       C_RID_CODE (id) = reswords[i].rid;
@@ -680,42 +618,27 @@ init_cp_pragma ()
   cpp_register_pragma (parse_in, 0, "implementation",
                       handle_pragma_implementation);
 
-  cpp_register_pragma_space (parse_in, "GCC");
   cpp_register_pragma (parse_in, "GCC", "interface", handle_pragma_interface);
   cpp_register_pragma (parse_in, "GCC", "implementation",
                       handle_pragma_implementation);
+  cpp_register_pragma (parse_in, "GCC", "java_exceptions",
+                      handle_pragma_java_exceptions);
 }
 
+/* Initialize the C++ front end.  This function is very sensitive to
+   the exact order that things are done here.  It would be nice if the
+   initialization done by this routine were moved to its subroutines,
+   and the ordering dependencies clarified and reduced.  */
 const char *
-init_parse (filename)
+cxx_init (filename)
      const char *filename;
 {
-  /* Make identifier nodes long enough for the language-specific slots.  */
-  set_identifier_size (sizeof (struct lang_identifier));
-  decl_printable_name = lang_printable_name;
-
   input_filename = "<internal>";
 
   init_reswords ();
-  init_pragma ();
-  init_cp_pragma ();
   init_spew ();
   init_tree ();
-  init_cplus_expand ();
   init_cp_semantics ();
-
-  add_c_tree_codes ();
-
-  memcpy (tree_code_type + (int) LAST_C_TREE_CODE,
-         cplus_tree_code_type,
-         (int)LAST_CPLUS_TREE_CODE - (int)LAST_C_TREE_CODE);
-  memcpy (tree_code_length + (int) LAST_C_TREE_CODE,
-         cplus_tree_code_length,
-         (LAST_CPLUS_TREE_CODE - (int)LAST_C_TREE_CODE) * sizeof (int));
-  memcpy (tree_code_name + (int) LAST_C_TREE_CODE,
-         cplus_tree_code_name,
-         (LAST_CPLUS_TREE_CODE - (int)LAST_C_TREE_CODE) * sizeof (char *));
-
   init_operators ();
   init_method ();
   init_error ();
@@ -738,24 +661,25 @@ init_parse (filename)
   TREE_TYPE (enum_type_node) = enum_type_node;
   ridpointers[(int) RID_ENUM] = enum_type_node;
 
-  /* Create the built-in __null node.  Note that we can't yet call for
-     type_for_size here because integer_type_node and so forth are not
-     set up.  Therefore, we don't set the type of these nodes until
-     init_decl_processing.  */
+  cxx_init_decl_processing ();
+
+  /* Create the built-in __null node.  */
   null_node = build_int_2 (0, 0);
+  TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0);
   ridpointers[RID_NULL] = null_node;
 
   token_count = init_cpp_parse ();
   interface_unknown = 1;
 
-  return init_c_lex (filename);
-}
+  filename = c_common_init (filename);
+  if (filename == NULL)
+    return NULL;
 
-void
-finish_parse ()
-{
-  cpp_finish (parse_in);
-  errorcount += parse_in->errors;
+  init_cp_pragma ();
+
+  init_repo (filename);
+
+  return filename;
 }
 \f
 inline void
@@ -798,7 +722,7 @@ yyprint (file, yychar, yylval)
       else if (yylval.ttype == enum_type_node)
        fprintf (file, " `enum'");
       else
-       my_friendly_abort (80);
+       abort ();
       break;
 
     case CONSTANT:
@@ -834,8 +758,8 @@ static int *reduce_count;
 int *token_count;
 
 #if 0
-#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0]))
-#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0]))
+#define REDUCE_LENGTH ARRAY_SIZE (yyr2)
+#define TOKEN_LENGTH (256 + ARRAY_SIZE (yytname))
 #endif
 
 #ifdef GATHER_STATISTICS
@@ -913,22 +837,6 @@ print_parse_statistics ()
 #endif
 }
 
-/* Sets the value of the 'yydebug' variable to VALUE.
-   This is a function so we don't have to have YYDEBUG defined
-   in order to build the compiler.  */
-
-void
-set_yydebug (value)
-     int value;
-{
-#if YYDEBUG != 0
-  extern int yydebug;
-  yydebug = value;
-#else
-  warning ("YYDEBUG not defined.");
-#endif
-}
-
 /* Helper function to load global variables with interface
    information.  */
 
@@ -949,9 +857,6 @@ extract_interface_info ()
 
   interface_only = finfo->interface_only;
   interface_unknown = finfo->interface_unknown;
-
-  /* This happens to be a convenient place to put this.  */
-  if (flag_gnu_xref) GNU_xref_file (input_filename);
 }
 
 /* Return nonzero if S is not considered part of an
@@ -1014,11 +919,11 @@ check_for_missing_semicolon (type)
        && yychar != SELFNAME)
       || yychar == 0  /* EOF */)
     {
-      if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type)))
+      if (TYPE_ANONYMOUS_P (type))
        error ("semicolon missing after %s declaration",
               TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct");
       else
-       cp_error ("semicolon missing after declaration of `%T'", type);
+       error ("semicolon missing after declaration of `%T'", type);
       shadow_tag (build_tree_list (0, type));
     }
   /* Could probably also hack cases where class { ... } f (); appears.  */
@@ -1030,7 +935,7 @@ note_got_semicolon (type)
      tree type;
 {
   if (!TYPE_P (type))
-    my_friendly_abort (60);
+    abort ();
   if (CLASS_TYPE_P (type))
     CLASSTYPE_GOT_SEMICOLON (type) = 1;
 }
@@ -1044,7 +949,7 @@ note_list_got_semicolon (declspecs)
   for (link = declspecs; link; link = TREE_CHAIN (link))
     {
       tree type = TREE_VALUE (link);
-      if (TYPE_P (type))
+      if (type && TYPE_P (type))
        note_got_semicolon (type);
     }
   clear_anon_tags ();
@@ -1081,12 +986,8 @@ static void
 handle_pragma_vtable (dfile)
      cpp_reader *dfile ATTRIBUTE_UNUSED;
 {
-  tree vtbl = parse_strconst_pragma ("vtable", 0);
-
-  if (vtbl && vtbl != (tree)-1)
-    pending_vtables = tree_cons (NULL_TREE,
-                                get_identifier (TREE_STRING_POINTER (vtbl)),
-                                pending_vtables);
+  parse_strconst_pragma ("vtable", 0);
+  sorry ("#pragma vtable no longer supported");
 }
 
 static void
@@ -1108,7 +1009,7 @@ handle_pragma_interface (dfile)
   if (fname == (tree)-1)
     return;
   else if (fname == 0)
-    main_filename = file_name_nondirectory (input_filename);
+    main_filename = lbasename (input_filename);
   else
     main_filename = TREE_STRING_POINTER (fname);
 
@@ -1157,7 +1058,7 @@ handle_pragma_implementation (dfile)
        main_filename = main_input_filename;
       else
        main_filename = input_filename;
-      main_filename = file_name_nondirectory (main_filename);
+      main_filename = lbasename (main_filename);
     }
   else
     {
@@ -1181,6 +1082,18 @@ handle_pragma_implementation (dfile)
     }
 }
 
+/* Indicate that this file uses Java-personality exception handling.  */
+static void
+handle_pragma_java_exceptions (dfile)
+     cpp_reader *dfile ATTRIBUTE_UNUSED;
+{
+  tree x;
+  if (c_lex (&x) != CPP_EOF)
+    warning ("junk at end of #pragma GCC java_exceptions");
+
+  choose_personality_routine (lang_java);
+}
+
 void
 do_pending_lang_change ()
 {
@@ -1225,6 +1138,9 @@ do_identifier (token, parsing, args)
   else
     id = lastiddecl;
 
+  if (lexing && id && TREE_DEPRECATED (id))
+    warn_deprecated_use (id);
+
   /* Do Koenig lookup if appropriate (inside templates we build lookup
      expressions instead).
 
@@ -1255,15 +1171,18 @@ do_identifier (token, parsing, args)
     {
       if (current_template_parms)
        return build_min_nt (LOOKUP_EXPR, token);
+      else if (IDENTIFIER_TYPENAME_P (token))
+       /* A templated conversion operator might exist.  */
+       return token;
       else if (IDENTIFIER_OPNAME_P (token))
        {
          if (token != ansi_opname (ERROR_MARK))
-           cp_error ("`%D' not defined", token);
+           error ("`%D' not defined", token);
          id = error_mark_node;
        }
       else if (current_function_decl == 0)
        {
-         cp_error ("`%D' was not declared in this scope", token);
+         error ("`%D' was not declared in this scope", token);
          id = error_mark_node;
        }
       else
@@ -1273,7 +1192,7 @@ do_identifier (token, parsing, args)
            {
              static int undeclared_variable_notice;
 
-             cp_error ("`%D' undeclared (first use this function)", token);
+             error ("`%D' undeclared (first use this function)", token);
 
              if (! undeclared_variable_notice)
                {
@@ -1379,7 +1298,8 @@ do_scoped_id (token, parsing)
     id = IDENTIFIER_GLOBAL_VALUE (token);
   if (parsing && yychar == YYEMPTY)
     yychar = yylex ();
-  if (! id)
+  if (!id || (TREE_CODE (id) == FUNCTION_DECL
+             && DECL_ANTICIPATED (id)))
     {
       if (processing_template_decl)
        {
@@ -1388,7 +1308,7 @@ do_scoped_id (token, parsing)
          return id;
        }
       if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node)
-        cp_error ("`::%D' undeclared (first use here)", token);
+        error ("`::%D' undeclared (first use here)", token);
       id = error_mark_node;
       /* Prevent repeated error messages.  */
       SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node);
@@ -1514,14 +1434,20 @@ retrofit_lang_decl (t)
 
   ld = (struct lang_decl *) ggc_alloc_cleared (size);
 
+  ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;
+  ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;
+  ld->decl_flags.u2sel = 0;
+  if (ld->decl_flags.can_be_full)
+    ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;
+
   DECL_LANG_SPECIFIC (t) = ld;
   if (current_lang_name == lang_name_cplusplus)
-    DECL_LANGUAGE (t) = lang_cplusplus;
+    SET_DECL_LANGUAGE (t, lang_cplusplus);
   else if (current_lang_name == lang_name_c)
-    DECL_LANGUAGE (t) = lang_c;
+    SET_DECL_LANGUAGE (t, lang_c);
   else if (current_lang_name == lang_name_java)
-    DECL_LANGUAGE (t) = lang_java;
-  else my_friendly_abort (64);
+    SET_DECL_LANGUAGE (t, lang_java);
+  else abort ();
 
 #ifdef GATHER_STATISTICS
   tree_node_counts[(int)lang_decl] += 1;
@@ -1530,7 +1456,7 @@ retrofit_lang_decl (t)
 }
 
 void
-copy_lang_decl (node)
+cxx_dup_lang_specific_decl (node)
      tree node;
 {
   int size;
@@ -1546,6 +1472,11 @@ copy_lang_decl (node)
   ld = (struct lang_decl *) ggc_alloc (size);
   memcpy (ld, DECL_LANG_SPECIFIC (node), size);
   DECL_LANG_SPECIFIC (node) = ld;
+
+#ifdef GATHER_STATISTICS
+  tree_node_counts[(int)lang_decl] += 1;
+  tree_node_sizes[(int)lang_decl] += size;
+#endif
 }
 
 /* Copy DECL, including any language-specific parts.  */
@@ -1557,18 +1488,58 @@ copy_decl (decl)
   tree copy;
 
   copy = copy_node (decl);
-  copy_lang_decl (copy);
+  cxx_dup_lang_specific_decl (copy);
+  return copy;
+}
+
+/* Replace the shared language-specific parts of NODE with a new copy.  */
+
+static void
+copy_lang_type (node)
+     tree node;
+{
+  int size;
+  struct lang_type *lt;
+
+  if (! TYPE_LANG_SPECIFIC (node))
+    return;
+
+  if (TYPE_LANG_SPECIFIC (node)->u.h.is_lang_type_class)
+    size = sizeof (struct lang_type);
+  else
+    size = sizeof (struct lang_type_ptrmem);
+  lt = (struct lang_type *) ggc_alloc (size);
+  memcpy (lt, TYPE_LANG_SPECIFIC (node), size);
+  TYPE_LANG_SPECIFIC (node) = lt;
+
+#ifdef GATHER_STATISTICS
+  tree_node_counts[(int)lang_type] += 1;
+  tree_node_sizes[(int)lang_type] += size;
+#endif
+}
+
+/* Copy TYPE, including any language-specific parts.  */
+
+tree
+copy_type (type)
+     tree type;
+{
+  tree copy;
+
+  copy = copy_node (type);
+  copy_lang_type (copy);
   return copy;
 }
 
 tree
-cp_make_lang_type (code)
+cxx_make_type (code)
      enum tree_code code;
 {
   register tree t = make_node (code);
 
-  /* Set up some flags that give proper default behavior.  */
-  if (IS_AGGR_TYPE_CODE (code))
+  /* Create lang_type structure.  */
+  if (IS_AGGR_TYPE_CODE (code)
+      || code == BOUND_TEMPLATE_TEMPLATE_PARM)
     {
       struct lang_type *pi;
 
@@ -1576,6 +1547,17 @@ cp_make_lang_type (code)
            ggc_alloc_cleared (sizeof (struct lang_type)));
 
       TYPE_LANG_SPECIFIC (t) = pi;
+      pi->u.c.h.is_lang_type_class = 1;
+
+#ifdef GATHER_STATISTICS
+      tree_node_counts[(int)lang_type] += 1;
+      tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
+#endif
+    }
+
+  /* Set up some flags that give proper default behavior.  */
+  if (IS_AGGR_TYPE_CODE (code))
+    {
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown);
       CLASSTYPE_INTERFACE_ONLY (t) = interface_only;
 
@@ -1583,11 +1565,6 @@ cp_make_lang_type (code)
         presence of parse errors, the normal was of assuring this
         might not ever get executed, so we lay it out *immediately*.  */
       build_pointer_type (t);
-
-#ifdef GATHER_STATISTICS
-      tree_node_counts[(int)lang_type] += 1;
-      tree_node_sizes[(int)lang_type] += sizeof (struct lang_type);
-#endif
     }
   else
     /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits.  But,
@@ -1599,7 +1576,9 @@ cp_make_lang_type (code)
      since they can be virtual base types, and we then need a
      canonical binfo for them.  Ideally, this would be done lazily for
      all types.  */
-  if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM)
+  if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM
+      || code == BOUND_TEMPLATE_TEMPLATE_PARM
+      || code == TYPENAME_TYPE)
     TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);
 
   return t;
@@ -1609,7 +1588,7 @@ tree
 make_aggr_type (code)
      enum tree_code code;
 {
-  tree t = cp_make_lang_type (code);
+  tree t = cxx_make_type (code);
 
   if (IS_AGGR_TYPE_CODE (code))
     SET_IS_AGGR_TYPE (t, 1);
@@ -1620,20 +1599,14 @@ make_aggr_type (code)
 void
 compiler_error VPARAMS ((const char *msg, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msg;
-#endif
   char buf[1024];
-  va_list ap;
 
-  VA_START (ap, msg);
-
-#ifndef ANSI_PROTOTYPES
-  msg = va_arg (ap, const char *);
-#endif
+  VA_OPEN (ap, msg);
+  VA_FIXEDARG (ap, const char *, msg);
 
   vsprintf (buf, msg, ap);
-  va_end (ap);
+  VA_CLOSE (ap);
+
   error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf);
 }
 
@@ -1651,6 +1624,6 @@ cp_type_qual_from_rid (rid)
   else if (rid == ridpointers[(int) RID_RESTRICT])
     return TYPE_QUAL_RESTRICT;
 
-  my_friendly_abort (0);
+  abort ();
   return TYPE_UNQUALIFIED;
 }
This page took 0.047066 seconds and 5 git commands to generate.