OSDN Git Service

* call.c (joust): Don't warn about "confusing" conversions to the
[pf3gnuchains/gcc-fork.git] / gcc / cp / decl2.c
index b498599..3a1e8fe 100644 (file)
@@ -43,6 +43,13 @@ Boston, MA 02111-1307, USA.  */
 #include "dwarf2out.h"
 #include "dwarfout.h"
 
+#if USE_CPPLIB
+#include "cpplib.h"
+extern cpp_reader  parse_in;
+extern cpp_options parse_options;
+static int cpp_initialized;
+#endif
+
 static tree get_sentry PROTO((tree));
 static void mark_vtable_entries PROTO((tree));
 static void import_export_template PROTO((tree));
@@ -55,6 +62,7 @@ static tree namespace_ancestor PROTO((tree, tree));
 static void add_using_namespace PROTO((tree, tree, int));
 static tree ambiguous_decl PROTO((tree, tree, tree));
 static tree build_anon_union_vars PROTO((tree, tree*, int, int));
+static void check_decl_namespace PROTO((void));
 
 extern int current_class_depth;
 
@@ -171,6 +179,10 @@ int flag_implicit_templates = 1;
 
 int warn_implicit = 1;
 
+/* Nonzero means warn about usage of long long when `-pedantic'.  */
+
+int warn_long_long = 1;
+
 /* Nonzero means warn when all ctors or dtors are private, and the class
    has no friends.  */
 
@@ -188,6 +200,11 @@ int flag_vtable_thunks = DEFAULT_VTABLE_THUNKS;
 
 int flag_use_repository;
 
+/* Nonzero if we want to issue diagnostics that the standard says are not
+   required.  */
+
+int flag_optional_diags = 1;
+
 /* Nonzero means give string constants the type `const char *'
    to get extra warnings from them.  These warnings will be too numerous
    to be useful, except in thoroughly ANSIfied programs.  */
@@ -199,11 +216,6 @@ int warn_write_strings;
 
 int warn_cast_qual;
 
-/* Nonzero means warn that dbx info for template class methods isn't fully
-   supported yet.  */
-
-int warn_template_debugging;
-
 /* Nonzero means warn about sizeof(function) or addition/subtraction
    of function pointers.  */
 
@@ -279,7 +291,11 @@ int warn_old_style_cast;
 
 /* Warn about #pragma directives that are not recognised.  */      
 
-int warn_unknown_pragmas = 0; /* Tri state variable.  */  
+int warn_unknown_pragmas; /* Tri state variable.  */  
+
+/* Nonzero means warn about use of multicharacter literals.  */
+
+int warn_multichar = 1;
 
 /* Nonzero means `$' can be in an identifier.  */
 
@@ -485,6 +501,7 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
   {"nonansi-builtins", &flag_no_nonansi_builtin, 0},
   {"gnu-keywords", &flag_no_gnu_keywords, 0},
   {"operator-names", &flag_operator_names, 1},
+  {"optional-diags", &flag_optional_diags, 1},
   {"check-new", &flag_check_new, 1},
   {"repo", &flag_use_repository, 1},
   {"for-scope", &flag_new_for_scope, 2},
@@ -492,13 +509,30 @@ static struct { char *string; int *variable; int on_value;} lang_f_options[] =
 };
 
 /* Decode the string P as a language-specific option.
-   Return 1 if it is recognized (and handle it);
-   return 0 if not recognized.  */
+   Return the number of strings consumed for a valid option.
+   Otherwise return 0.  */
 
 int   
-lang_decode_option (p)
-     char *p;
+lang_decode_option (argc, argv)
+     int argc;
+     char **argv;
+
 {
+  int strings_processed;
+  char *p = argv[0];
+#if USE_CPPLIB
+  if (! cpp_initialized)
+    {
+      cpp_reader_init (&parse_in);
+      parse_in.data = &parse_options;
+      cpp_options_init (&parse_options);
+      cpp_initialized = 1;
+    }
+  strings_processed = cpp_handle_option (&parse_in, argc, argv);
+#else
+  strings_processed = 0;
+#endif /* ! USE_CPPLIB */
+
   if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional"))
     flag_writable_strings = 1,
     flag_this_is_variable = 1, flag_new_for_scope = 0;
@@ -657,6 +691,8 @@ lang_decode_option (p)
 
       if (!strcmp (p, "implicit"))
        warn_implicit = setting;
+      else if (!strcmp (p, "long-long"))
+       warn_long_long = setting;
       else if (!strcmp (p, "return-type"))
        warn_return_type = setting;
       else if (!strcmp (p, "ctor-dtor-privacy"))
@@ -699,6 +735,10 @@ lang_decode_option (p)
        warn_sign_promo = setting;
       else if (!strcmp (p, "old-style-cast"))
        warn_old_style_cast = setting;
+      else if (!strcmp (p, "overloaded-virtual"))
+       warn_overloaded_virtual = setting;
+      else if (!strcmp (p, "multichar"))
+       warn_multichar = setting;
       else if (!strcmp (p, "unknown-pragmas"))
        /* Set to greater than 1, so that even unknown pragmas in
           system headers will be warned about.  */  
@@ -724,22 +764,19 @@ lang_decode_option (p)
          warn_sign_compare = setting;
          warn_extern_inline = setting;
          warn_nonvdtor = setting;
+         warn_multichar = setting;
          /* We save the value of warn_uninitialized, since if they put
             -Wuninitialized on the command line, we need to generate a
             warning about not using it without also specifying -O.  */
          if (warn_uninitialized != 1)
            warn_uninitialized = (setting ? 2 : 0);
-         warn_template_debugging = setting;
          warn_reorder = setting;
          warn_sign_promo = setting;
          /* Only warn about unknown pragmas that are not in system
             headers.  */                                        
          warn_unknown_pragmas = 1;                  
        }
-
-      else if (!strcmp (p, "overloaded-virtual"))
-       warn_overloaded_virtual = setting;
-      else return 0;
+      else return strings_processed;
     }
   else if (!strcmp (p, "-ansi"))
     flag_no_nonansi_builtin = 1, flag_ansi = 1,
@@ -752,7 +789,7 @@ lang_decode_option (p)
     spew_debug = 1;
 #endif
   else
-    return 0;
+    return strings_processed;
 
   return 1;
 }
@@ -1302,8 +1339,8 @@ delete_sanity (exp, size, doing_vec, use_global_delete)
        {
          /* 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);
+         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;
        }
@@ -3089,6 +3126,8 @@ finish_file ()
   if (! global_bindings_p () || current_class_type)
     return;
 
+  check_decl_namespace ();
+
   start_time = get_run_time ();
 
   /* Otherwise, GDB can get confused, because in only knows
@@ -3233,6 +3272,8 @@ finish_file ()
       import_export_decl (decl);
     }
 
+  mark_all_runtime_matches ();
+
   /* Now write out inline functions which had their addresses taken and
      which were not declared virtual and which were not declared `extern
      inline'.  */
@@ -3442,13 +3483,13 @@ build_expr_from_tree (t)
   switch (TREE_CODE (t))
     {
     case IDENTIFIER_NODE:
-      return do_identifier (t, 0);
+      return do_identifier (t, 0, NULL_TREE);
 
     case LOOKUP_EXPR:
       if (LOOKUP_EXPR_GLOBAL (t))
        return do_scoped_id (TREE_OPERAND (t, 0), 0);
       else
-       return do_identifier (TREE_OPERAND (t, 0), 0);
+       return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE);
 
     case TEMPLATE_ID_EXPR:
       return (lookup_template_function
@@ -3613,12 +3654,21 @@ build_expr_from_tree (t)
       else
        {
          tree name = TREE_OPERAND (t, 0);
-         if (TREE_CODE (name) == TEMPLATE_ID_EXPR
+          tree id;
+          tree args = build_expr_from_tree (TREE_OPERAND (t, 1));
+          if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR
+              && !LOOKUP_EXPR_GLOBAL (name)
+              && TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE
+              && (!current_class_type
+                  || !lookup_member (current_class_type, id, 0, 0)))
+            {
+              /* Do Koenig lookup if there are no class members. */
+              name = do_identifier (id, 0, args);
+            }
+          else if (TREE_CODE (name) == TEMPLATE_ID_EXPR
              || ! really_overloaded_fn (name))
            name = build_expr_from_tree (name);
-         return build_x_function_call
-           (name, build_expr_from_tree (TREE_OPERAND (t, 1)),
-            current_class_ref);
+         return build_x_function_call (name, args, current_class_ref);
        }
 
     case COND_EXPR:
@@ -3782,7 +3832,7 @@ is_namespace_ancestor (root, child)
     return 1;
   if (child == global_namespace)
     return 0;
-  return is_namespace_ancestor (root, DECL_CONTEXT (child));
+  return is_namespace_ancestor (root, CP_DECL_CONTEXT (child));
 }
   
 
@@ -3902,32 +3952,24 @@ ambiguous_decl (name, old, new)
 }
 
 /* Add the bindings of name in used namespaces to val.
-   The using list is defined by current, and the lookup goes to scope.
+   The using list is defined by usings, and the lookup goes to scope.
    Returns zero on errors. */
 
 int
-lookup_using_namespace (name, val, current, scope)
-     tree name, val, current, scope;
+lookup_using_namespace (name, val, usings, scope)
+     tree name, val, usings, scope;
 {
   tree iter;
   tree val1;
-  /* Iterate over all namespaces from current to scope. */
-  while (val != error_mark_node)
-    {
-      /* Iterate over all used namespaces in current, searching for
-        using directives of scope. */
-      for (iter = DECL_NAMESPACE_USING (current); 
-          iter; iter = TREE_CHAIN (iter))
-       if (TREE_VALUE (iter) == scope)
-         {
-           val1 = binding_for_name (name, TREE_PURPOSE (iter));
-           /* Resolve ambiguities. */
-           val = ambiguous_decl (name, val, val1);
-         }
-      if (current == scope)
-       break;
-      current = DECL_CONTEXT (current);
-    }
+  /* Iterate over all used namespaces in current, searching for using
+     directives of scope. */
+  for (iter = usings; iter; iter = TREE_CHAIN (iter))
+    if (TREE_VALUE (iter) == scope)
+      {
+       val1 = binding_for_name (name, TREE_PURPOSE (iter));
+       /* Resolve ambiguities. */
+       val = ambiguous_decl (name, val, val1);
+      }
   return val != error_mark_node;
 }
 
@@ -3957,7 +3999,7 @@ qualified_lookup_using_namespace (name, scope, result)
             usings = TREE_CHAIN (usings))
          /* If this was a real directive, and we have not seen it. */
          if (!TREE_INDIRECT_USING (usings)
-             && !purpose_member (seen, TREE_PURPOSE (usings)))
+             && !purpose_member (TREE_PURPOSE (usings), seen))
            todo = temp_tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo);
       if (todo)
        {
@@ -3989,7 +4031,7 @@ set_decl_namespace (decl, scope)
   if (!is_namespace_ancestor (current_namespace, scope))
     cp_error ("declaration of `%D' not in a namespace surrounding `%D'",
              decl, scope);
-  DECL_CONTEXT (decl) = scope;
+  DECL_CONTEXT (decl) = FROB_CONTEXT (scope);
   if (scope != current_namespace)
     {
       /* See whether this has been declared in the namespace. */
@@ -4032,9 +4074,7 @@ decl_namespace (decl)
       my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 390);
     }
 
-  /* We should always find the namespace. */
-  my_friendly_abort (390);
-  return NULL_TREE;
+  return global_namespace;
 }
 
 /* Return the namespace where the current declaration is declared. */
@@ -4079,6 +4119,12 @@ pop_decl_namespace ()
   decl_namespace_list = TREE_CHAIN (decl_namespace_list);
 }
 
+static void 
+check_decl_namespace ()
+{
+  my_friendly_assert (decl_namespace_list == NULL_TREE, 980711);
+}
+
 /* [basic.lookup.koenig] */
 /* A non-zero return value in the functions below indicates an error.
    All nodes allocated in the procedure are on the scratch obstack. */
@@ -4301,6 +4347,13 @@ arg_assoc (k, n)
          if (arg_assoc_type (k, DECL_CLASS_CONTEXT (n)))
            return 1;
        return 0;
+      case TEMPLATE_DECL:
+        /* XXX Type of a function template in the context of Koenig lookup?
+           Assume that template parameters are non-deduced for the moment. */
+        n = DECL_RESULT (n);
+        continue;
+      case ERROR_MARK:
+        return 0;
       default:
        cp_error ("sorry, Koenig lookup for `%s' of type `%T' failed",
                  tree_code_name [(int)TREE_CODE (n)], TREE_TYPE (n));
@@ -4364,44 +4417,54 @@ do_namespace_alias (alias, namespace)
       /* Build the alias. */
       alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node);     
       DECL_NAMESPACE_ALIAS (alias) = namespace;
-      DECL_CONTEXT (alias) = current_namespace;
+      DECL_CONTEXT (alias) = FROB_CONTEXT (current_namespace);
       BINDING_VALUE (binding) = alias;
     }
 }
 
-/* Process a using-declaration not appearing in class or local scope. */
+/* Check a non-member using-declaration. Return the name and scope
+   being used, and the USING_DECL, or NULL_TREE on failure. */
 
-void
-do_toplevel_using_decl (decl)
+static tree
+validate_nonmember_using_decl (decl, scope, name)
      tree decl;
+     tree *scope;
+     tree *name;
 {
-  tree scope, name, binding, decls, newval, newtype;
-  struct tree_binding _decls;
-
   if (TREE_CODE (decl) == SCOPE_REF
       && TREE_OPERAND (decl, 0) == std_node)
-    return;
+    return NULL_TREE;
   if (TREE_CODE (decl) == SCOPE_REF)
     {
-      scope = TREE_OPERAND (decl, 0);
-      name = TREE_OPERAND (decl, 1);
+      *scope = TREE_OPERAND (decl, 0);
+      *name = TREE_OPERAND (decl, 1);
     }
   else if (TREE_CODE (decl) == IDENTIFIER_NODE
            || TREE_CODE (decl) == TYPE_DECL)
     {
-      scope = global_namespace;
-      name = decl;
+      *scope = global_namespace;
+      *name = decl;
     }
   else
     my_friendly_abort (382);
-  if (TREE_CODE_CLASS (TREE_CODE (name)) == 'd')
-    name = DECL_NAME (name);
+  if (TREE_CODE_CLASS (TREE_CODE (*name)) == 'd')
+    *name = DECL_NAME (*name);
   /* Make a USING_DECL. */
-  decl = push_using_decl (scope, name);
-  if (!decl)
-    return;
-  
-  binding = binding_for_name (name, current_namespace);
+  return push_using_decl (*scope, *name);
+}
+
+/* Process local and global using-declarations. */
+
+static void
+do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype)
+     tree scope, name;
+     tree oldval, oldtype;
+     tree *newval, *newtype;
+{
+  tree decls;
+  struct tree_binding _decls;
+
+  *newval = *newtype = NULL_TREE;
   decls = binding_init (&_decls);
   if (!qualified_lookup_using_namespace (name, scope, decls))
     /* Lookup error */
@@ -4412,14 +4475,12 @@ do_toplevel_using_decl (decl)
       cp_error ("`%D' not declared", name);
       return;
     }
-  newval = newtype = NULL_TREE;
 
   /* Check for using functions. */
   if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls)))
     {
-      tree oldval = BINDING_VALUE (binding);
       tree tmp, tmp1;
-      newval = oldval;
+      *newval = oldval;
       for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp))
        {
 
@@ -4437,27 +4498,48 @@ do_toplevel_using_decl (decl)
          if (tmp1)
            continue;
            
-         newval = build_overload (OVL_CURRENT (tmp), newval);
-         if (TREE_CODE (newval) != OVERLOAD)
-           newval = ovl_cons (newval, NULL_TREE);
-         OVL_USED (newval) = 1;
+         *newval = build_overload (OVL_CURRENT (tmp), *newval);
+         if (TREE_CODE (*newval) != OVERLOAD)
+           *newval = ovl_cons (*newval, NULL_TREE);
+         OVL_USED (*newval) = 1;
        }
     }
   else 
     {
-      tree oldval = BINDING_VALUE (binding);
-      newval = BINDING_VALUE (decls);
-      if (oldval && oldval != newval && !duplicate_decls (newval, oldval))
-       newval = oldval;
+      *newval = BINDING_VALUE (decls);
+      if (oldval && oldval != *newval && !duplicate_decls (*newval, oldval))
+       *newval = oldval;
     } 
 
-  newtype = BINDING_TYPE (decls);
-  if (BINDING_TYPE (binding) && newtype && BINDING_TYPE (binding) != newtype)
+  *newtype = BINDING_TYPE (decls);
+  if (oldtype && *newtype && oldtype != *newtype)
     {
       cp_error ("using directive `%D' introduced ambiguous type `%T'",
-               name, BINDING_TYPE (decls));
+               name, oldtype);
       return;
     }
+}
+
+/* Process a using-declaration not appearing in class or local scope. */
+
+void
+do_toplevel_using_decl (decl)
+     tree decl;
+{
+  tree scope, name, binding;
+  tree oldval, oldtype, newval, newtype;
+
+  decl = validate_nonmember_using_decl (decl, &scope, &name);
+  if (decl == NULL_TREE)
+    return;
+  
+  binding = binding_for_name (name, current_namespace);
+
+  oldval = BINDING_VALUE (binding);
+  oldtype = BINDING_TYPE (binding);
+
+  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+
   /* Copy declarations found. */
   if (newval)
     BINDING_VALUE (binding) = newval;
@@ -4466,6 +4548,29 @@ do_toplevel_using_decl (decl)
   return;
 }
 
+void
+do_local_using_decl (decl)
+     tree decl;
+{
+  tree scope, name;
+  tree oldval, oldtype, newval, newtype;
+  decl = validate_nonmember_using_decl (decl, &scope, &name);
+  if (decl == NULL_TREE)
+    return;
+
+  /* XXX nested values */
+  oldval = IDENTIFIER_LOCAL_VALUE (name);
+  /* XXX get local type */
+  oldtype = NULL_TREE;
+
+  do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype);
+
+  if (newval)
+    /* XXX update bindings */
+    IDENTIFIER_LOCAL_VALUE (name) = newval;
+  /* XXX type */
+}
+
 tree
 do_class_using_decl (decl)
      tree decl;
@@ -4498,11 +4603,6 @@ do_using_directive (namespace)
 {
   if (namespace == std_node)
     return;
-  if (!toplevel_bindings_p ())
-    {
-      sorry ("using directives inside functions");
-      return;
-    }
   /* using namespace A::B::C; */
   if (TREE_CODE (namespace) == SCOPE_REF)
       namespace = TREE_OPERAND (namespace, 1);
@@ -4518,8 +4618,13 @@ do_using_directive (namespace)
       return;
     }
   namespace = ORIGINAL_NAMESPACE (namespace);
-  /* direct usage */
-  add_using_namespace (current_namespace, namespace, 0);
+  if (!toplevel_bindings_p ())
+    push_using_directive
+      (namespace, namespace_ancestor (current_decl_namespace(), 
+                                     current_namespace));
+  else
+    /* direct usage */
+    add_using_namespace (current_namespace, namespace, 0);
 }
 
 void