OSDN Git Service

2007-07-14 Rafael Avila de Espindola <espindola@google.com>
[pf3gnuchains/gcc-fork.git] / gcc / cp / lex.c
index e62887d..890640e 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, 2002, 2003, 2004, 2005, 2007
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
    Free Software Foundation, Inc.
    Hacked by Michael Tiemann (tiemann@cygnus.com)
 
@@ -89,9 +89,9 @@ cxx_finish (void)
 }
 
 /* A mapping from tree codes to operator name information.  */
-operator_name_info_t operator_name_info[(int) LAST_CPLUS_TREE_CODE];
+operator_name_info_t operator_name_info[(int) MAX_TREE_CODES];
 /* Similar, but for assignment operators.  */
-operator_name_info_t assignment_operator_name_info[(int) LAST_CPLUS_TREE_CODE];
+operator_name_info_t assignment_operator_name_info[(int) MAX_TREE_CODES];
 
 /* Initialize data structures that keep track of operator names.  */
 
@@ -163,188 +163,32 @@ init_operators (void)
     = "(round %=)";
 }
 
-/* The reserved keyword table.  */
-struct resword
-{
-  const char *const word;
-  ENUM_BITFIELD(rid) const rid : 16;
-  const unsigned int disable   : 16;
-};
-
-/* Disable mask.  Keywords are disabled if (reswords[i].disable & mask) is
-   _true_.  */
-#define D_EXT          0x01    /* GCC extension */
-#define D_ASM          0x02    /* in C99, but has a switch to turn it off */
-#define D_OBJC         0x04    /* Objective C++ only */
-#define D_CXX0X         0x08    /* C++0x only */
-
-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 },
-  { "__asm__",         RID_ASM,        0 },
-  { "__attribute",     RID_ATTRIBUTE,  0 },
-  { "__attribute__",   RID_ATTRIBUTE,  0 },
-  { "__builtin_offsetof", RID_OFFSETOF, 0 },
-  { "__builtin_va_arg",        RID_VA_ARG,     0 },
-  { "__complex",       RID_COMPLEX,    0 },
-  { "__complex__",     RID_COMPLEX,    0 },
-  { "__const",         RID_CONST,      0 },
-  { "__const__",       RID_CONST,      0 },
-  { "__decltype",       RID_DECLTYPE,   0 },
-  { "__extension__",   RID_EXTENSION,  0 },
-  { "__func__",                RID_C99_FUNCTION_NAME,  0 },
-  { "__has_nothrow_assign", RID_HAS_NOTHROW_ASSIGN, 0 },
-  { "__has_nothrow_constructor", RID_HAS_NOTHROW_CONSTRUCTOR, 0 },
-  { "__has_nothrow_copy", RID_HAS_NOTHROW_COPY, 0 },
-  { "__has_trivial_assign", RID_HAS_TRIVIAL_ASSIGN, 0 },
-  { "__has_trivial_constructor", RID_HAS_TRIVIAL_CONSTRUCTOR, 0 },
-  { "__has_trivial_copy", RID_HAS_TRIVIAL_COPY, 0 },
-  { "__has_trivial_destructor", RID_HAS_TRIVIAL_DESTRUCTOR, 0 },
-  { "__has_virtual_destructor", RID_HAS_VIRTUAL_DESTRUCTOR, 0 },
-  { "__is_abstract",   RID_IS_ABSTRACT, 0 },
-  { "__is_base_of",    RID_IS_BASE_OF, 0 },
-  { "__is_class",      RID_IS_CLASS,   0 },
-  { "__is_convertible_to", RID_IS_CONVERTIBLE_TO, 0 },
-  { "__is_empty",      RID_IS_EMPTY,   0 },
-  { "__is_enum",       RID_IS_ENUM,    0 },
-  { "__is_pod",                RID_IS_POD,     0 },
-  { "__is_polymorphic",        RID_IS_POLYMORPHIC, 0 },
-  { "__is_union",      RID_IS_UNION,   0 },
-  { "__imag",          RID_IMAGPART,   0 },
-  { "__imag__",                RID_IMAGPART,   0 },
-  { "__inline",                RID_INLINE,     0 },
-  { "__inline__",      RID_INLINE,     0 },
-  { "__label__",       RID_LABEL,      0 },
-  { "__null",          RID_NULL,       0 },
-  { "__real",          RID_REALPART,   0 },
-  { "__real__",                RID_REALPART,   0 },
-  { "__restrict",      RID_RESTRICT,   0 },
-  { "__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 },
-  { "__volatile__",    RID_VOLATILE,   0 },
-  { "asm",             RID_ASM,        D_ASM },
-  { "auto",            RID_AUTO,       0 },
-  { "bool",            RID_BOOL,       0 },
-  { "break",           RID_BREAK,      0 },
-  { "case",            RID_CASE,       0 },
-  { "catch",           RID_CATCH,      0 },
-  { "char",            RID_CHAR,       0 },
-  { "class",           RID_CLASS,      0 },
-  { "const",           RID_CONST,      0 },
-  { "const_cast",      RID_CONSTCAST,  0 },
-  { "continue",                RID_CONTINUE,   0 },
-  { "decltype",         RID_DECLTYPE,   D_CXX0X },
-  { "default",         RID_DEFAULT,    0 },
-  { "delete",          RID_DELETE,     0 },
-  { "do",              RID_DO,         0 },
-  { "double",          RID_DOUBLE,     0 },
-  { "dynamic_cast",    RID_DYNCAST,    0 },
-  { "else",            RID_ELSE,       0 },
-  { "enum",            RID_ENUM,       0 },
-  { "explicit",                RID_EXPLICIT,   0 },
-  { "export",          RID_EXPORT,     0 },
-  { "extern",          RID_EXTERN,     0 },
-  { "false",           RID_FALSE,      0 },
-  { "float",           RID_FLOAT,      0 },
-  { "for",             RID_FOR,        0 },
-  { "friend",          RID_FRIEND,     0 },
-  { "goto",            RID_GOTO,       0 },
-  { "if",              RID_IF,         0 },
-  { "inline",          RID_INLINE,     0 },
-  { "int",             RID_INT,        0 },
-  { "long",            RID_LONG,       0 },
-  { "mutable",         RID_MUTABLE,    0 },
-  { "namespace",       RID_NAMESPACE,  0 },
-  { "new",             RID_NEW,        0 },
-  { "operator",                RID_OPERATOR,   0 },
-  { "private",         RID_PRIVATE,    0 },
-  { "protected",       RID_PROTECTED,  0 },
-  { "public",          RID_PUBLIC,     0 },
-  { "register",                RID_REGISTER,   0 },
-  { "reinterpret_cast",        RID_REINTCAST,  0 },
-  { "return",          RID_RETURN,     0 },
-  { "short",           RID_SHORT,      0 },
-  { "signed",          RID_SIGNED,     0 },
-  { "sizeof",          RID_SIZEOF,     0 },
-  { "static",          RID_STATIC,     0 },
-  { "static_assert",    RID_STATIC_ASSERT, D_CXX0X },
-  { "static_cast",     RID_STATCAST,   0 },
-  { "struct",          RID_STRUCT,     0 },
-  { "switch",          RID_SWITCH,     0 },
-  { "template",                RID_TEMPLATE,   0 },
-  { "this",            RID_THIS,       0 },
-  { "throw",           RID_THROW,      0 },
-  { "true",            RID_TRUE,       0 },
-  { "try",             RID_TRY,        0 },
-  { "typedef",         RID_TYPEDEF,    0 },
-  { "typename",                RID_TYPENAME,   0 },
-  { "typeid",          RID_TYPEID,     0 },
-  { "typeof",          RID_TYPEOF,     D_ASM|D_EXT },
-  { "union",           RID_UNION,      0 },
-  { "unsigned",                RID_UNSIGNED,   0 },
-  { "using",           RID_USING,      0 },
-  { "virtual",         RID_VIRTUAL,    0 },
-  { "void",            RID_VOID,       0 },
-  { "volatile",                RID_VOLATILE,   0 },
-  { "wchar_t",         RID_WCHAR,      0 },
-  { "while",           RID_WHILE,      0 },
-
-  /* The remaining keywords are specific to Objective-C++.  NB:
-     All of them will remain _disabled_, since they are context-
-     sensitive.  */
-
-  /* These ObjC keywords are recognized only immediately after
-     an '@'.  NB: The following C++ keywords double as
-     ObjC keywords in this context: RID_CLASS, RID_PRIVATE,
-     RID_PROTECTED, RID_PUBLIC, RID_THROW, RID_TRY and RID_CATCH.  */
-  { "compatibility_alias", RID_AT_ALIAS,       D_OBJC },
-  { "defs",            RID_AT_DEFS,            D_OBJC },
-  { "encode",          RID_AT_ENCODE,          D_OBJC },
-  { "end",             RID_AT_END,             D_OBJC },
-  { "implementation",  RID_AT_IMPLEMENTATION,  D_OBJC },
-  { "interface",       RID_AT_INTERFACE,       D_OBJC },
-  { "protocol",                RID_AT_PROTOCOL,        D_OBJC },
-  { "selector",                RID_AT_SELECTOR,        D_OBJC },
-  { "finally",         RID_AT_FINALLY,         D_OBJC },
-  { "synchronized",    RID_AT_SYNCHRONIZED,    D_OBJC },
-  /* These are recognized only in protocol-qualifier context.  */
-  { "bycopy",          RID_BYCOPY,             D_OBJC },
-  { "byref",           RID_BYREF,              D_OBJC },
-  { "in",              RID_IN,                 D_OBJC },
-  { "inout",           RID_INOUT,              D_OBJC },
-  { "oneway",          RID_ONEWAY,             D_OBJC },
-  { "out",             RID_OUT,                D_OBJC },
-};
+/* Initialize the reserved words.  */
 
 void
 init_reswords (void)
 {
   unsigned int i;
   tree id;
-  int mask = ((flag_no_asm ? D_ASM : 0)
-             | D_OBJC
-             | (flag_no_gnu_keywords ? D_EXT : 0)
-              | ((cxx_dialect == cxx0x) ? 0 : D_CXX0X));
+  int mask = 0;
+
+  mask |= D_CONLY;
+  if (cxx_dialect != cxx0x)
+    mask |= D_CXX0X;
+  if (flag_no_asm)
+    mask |= D_ASM | D_EXT;
+  if (flag_no_gnu_keywords)
+    mask |= D_EXT;
+  if (!c_dialect_objc())
+    mask |= D_OBJC;
 
   ridpointers = GGC_CNEWVEC (tree, (int) RID_MAX);
-  for (i = 0; i < ARRAY_SIZE (reswords); i++)
+  for (i = 0; i < num_c_common_reswords; i++)
     {
-      id = get_identifier (reswords[i].word);
-      C_RID_CODE (id) = reswords[i].rid;
-      ridpointers [(int) reswords[i].rid] = id;
-      if (! (reswords[i].disable & mask))
+      id = get_identifier (c_common_reswords[i].word);
+      C_SET_RID_CODE (id, c_common_reswords[i].rid);
+      ridpointers [(int) c_common_reswords[i].rid] = id;
+      if (! (c_common_reswords[i].disable & mask))
        C_IS_RESERVED_WORD (id) = 1;
     }
 }
@@ -372,6 +216,7 @@ bool statement_code_p[MAX_TREE_CODES];
 bool
 cxx_init (void)
 {
+  location_t saved_loc;
   unsigned int i;
   static const enum tree_code stmt_codes[] = {
    CTOR_INITIALIZER,   TRY_BLOCK,      HANDLER,
@@ -385,14 +230,8 @@ cxx_init (void)
   for (i = 0; i < ARRAY_SIZE (stmt_codes); i++)
     statement_code_p[stmt_codes[i]] = true;
 
-  /* We cannot just assign to input_filename because it has already
-     been initialized and will be used later as an N_BINCL for stabs+
-     debugging.  */
-#ifdef USE_MAPPED_LOCATION
-  push_srcloc (BUILTINS_LOCATION);
-#else
-  push_srcloc ("<built-in>", 0);
-#endif
+  saved_loc = input_location;
+  input_location = BUILTINS_LOCATION;
 
   init_reswords ();
   init_tree ();
@@ -420,7 +259,7 @@ cxx_init (void)
 
   if (c_common_init () == false)
     {
-      pop_srcloc();
+      input_location = saved_loc;
       return false;
     }
 
@@ -428,7 +267,7 @@ cxx_init (void)
 
   init_repo ();
 
-  pop_srcloc();
+  input_location = saved_loc;
   return true;
 }
 \f
@@ -523,7 +362,7 @@ handle_pragma_interface (cpp_reader* dfile ATTRIBUTE_UNUSED )
   else if (fname == 0)
     filename = lbasename (input_filename);
   else
-    filename = ggc_strdup (TREE_STRING_POINTER (fname));
+    filename = TREE_STRING_POINTER (fname);
 
   finfo = get_fileinfo (input_filename);
 
@@ -571,18 +410,10 @@ handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
     }
   else
     {
-      filename = ggc_strdup (TREE_STRING_POINTER (fname));
-#if 0
-      /* We currently cannot give this diagnostic, as we reach this point
-        only after cpplib has scanned the entire translation unit, so
-        cpp_included always returns true.  A plausible fix is to compare
-        the current source-location cookie with the first source-location
-        cookie (if any) of the filename, but this requires completing the
-        --enable-mapped-location project first.  See PR 17577.  */
-      if (cpp_included (parse_in, filename))
+      filename = TREE_STRING_POINTER (fname);
+      if (cpp_included_before (parse_in, filename, input_location))
        warning (0, "#pragma implementation for %qs appears after "
                 "file is included", filename);
-#endif
     }
 
   for (; ifiles; ifiles = ifiles->next)
@@ -593,7 +424,7 @@ handle_pragma_implementation (cpp_reader* dfile ATTRIBUTE_UNUSED )
   if (ifiles == 0)
     {
       ifiles = XNEW (struct impl_files);
-      ifiles->filename = filename;
+      ifiles->filename = xstrdup (filename);
       ifiles->next = impl_file_chain;
       impl_file_chain = ifiles;
     }
@@ -660,16 +491,16 @@ unqualified_fn_lookup_error (tree name)
         Note that we have the exact wording of the following message in
         the manual (trouble.texi, node "Name lookup"), so they need to
         be kept in synch.  */
-      pedwarn ("there are no arguments to %qD that depend on a template "
-              "parameter, so a declaration of %qD must be available",
-              name, name);
+      permerror ("there are no arguments to %qD that depend on a template "
+                "parameter, so a declaration of %qD must be available",
+                name, name);
 
       if (!flag_permissive)
        {
          static bool hint;
          if (!hint)
            {
-             error ("(if you use %<-fpermissive%>, G++ will accept your "
+             inform ("(if you use %<-fpermissive%>, G++ will accept your "
                     "code, but allowing the use of an undeclared name is "
                     "deprecated)");
              hint = true;
@@ -814,7 +645,7 @@ cxx_make_type (enum tree_code code)
   tree t = make_node (code);
 
   /* Create lang_type structure.  */
-  if (IS_AGGR_TYPE_CODE (code)
+  if (RECORD_OR_UNION_CODE_P (code)
       || code == BOUND_TEMPLATE_TEMPLATE_PARM)
     {
       struct lang_type *pi = GGC_CNEW (struct lang_type);
@@ -829,7 +660,7 @@ cxx_make_type (enum tree_code code)
     }
 
   /* Set up some flags that give proper default behavior.  */
-  if (IS_AGGR_TYPE_CODE (code))
+  if (RECORD_OR_UNION_CODE_P (code))
     {
       struct c_fileinfo *finfo = get_fileinfo (input_filename);
       SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, finfo->interface_unknown);
@@ -840,13 +671,10 @@ cxx_make_type (enum tree_code code)
 }
 
 tree
-make_aggr_type (enum tree_code code)
+make_class_type (enum tree_code code)
 {
   tree t = cxx_make_type (code);
-
-  if (IS_AGGR_TYPE_CODE (code))
-    SET_IS_AGGR_TYPE (t, 1);
-
+  SET_CLASS_TYPE_P (t, 1);
   return t;
 }
 
@@ -856,11 +684,11 @@ make_aggr_type (enum tree_code code)
 bool
 in_main_input_context (void)
 {
-  tree tl = outermost_tinst_level();
+  struct tinst_level *tl = outermost_tinst_level();
 
   if (tl)
     return strcmp (main_input_filename,
-                  LOCATION_FILE (TINST_LOCATION (tl))) == 0;
+                  LOCATION_FILE (tl->locus)) == 0;
   else
     return strcmp (main_input_filename, input_filename) == 0;
 }