OSDN Git Service

* attribs.c (strip_attrs): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / cp / semantics.c
index 5974a7a..cadb5a7 100644 (file)
@@ -45,6 +45,7 @@
 #include "cgraph.h"
 #include "tree-iterator.h"
 #include "vec.h"
+#include "target.h"
 
 /* There routines provide a modular interface to perform many parsing
    operations.  They may therefore be used during actual parsing, or
@@ -306,7 +307,7 @@ perform_or_defer_access_check (tree binfo, tree decl)
   if (deferred_access_no_check)
     return;
   
-  my_friendly_assert (TREE_CODE (binfo) == TREE_VEC, 20030623);
+  gcc_assert (TREE_CODE (binfo) == TREE_BINFO);
 
   ptr = VEC_last (deferred_access, deferred_access_stack);
   
@@ -703,13 +704,15 @@ finish_return_stmt (tree expr)
   expr = check_return_expr (expr);
   if (!processing_template_decl)
     {
-      if (DECL_DESTRUCTOR_P (current_function_decl))
+      if (DECL_DESTRUCTOR_P (current_function_decl)
+         || (DECL_CONSTRUCTOR_P (current_function_decl) 
+             && targetm.cxx.cdtor_returns_this ()))
        {
          /* Similarly, all destructors must run destructors for
             base-classes before returning.  So, all returns in a
             destructor get sent to the DTOR_LABEL; finish_function emits
             code to return a value there.  */
-         return finish_goto_stmt (dtor_label);
+         return finish_goto_stmt (cdtor_label);
        }
     }
 
@@ -1066,7 +1069,7 @@ begin_compound_stmt (unsigned int flags)
      processing templates.  */
   if (processing_template_decl)
     {
-      r = build (BIND_EXPR, NULL, NULL, r, NULL);
+      r = build3 (BIND_EXPR, NULL, NULL, r, NULL);
       BIND_EXPR_TRY_BLOCK (r) = (flags & BCS_TRY_BLOCK) != 0;
       BIND_EXPR_BODY_BLOCK (r) = (flags & BCS_FN_BODY) != 0;
       TREE_SIDE_EFFECTS (r) = 1;
@@ -1231,7 +1234,7 @@ finish_parenthesized_expr (tree expr)
 {
   if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr))))
     /* This inhibits warnings in c_common_truthvalue_conversion.  */
-    C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK); 
+    TREE_NO_WARNING (expr) = 1;
 
   if (TREE_CODE (expr) == OFFSET_REF)
     /* [expr.unary.op]/3 The qualified id of a pointer-to-member must not be
@@ -1246,7 +1249,7 @@ finish_parenthesized_expr (tree expr)
 tree
 finish_non_static_data_member (tree decl, tree object, tree qualifying_scope)
 {
-  my_friendly_assert (TREE_CODE (decl) == FIELD_DECL, 20020909);
+  gcc_assert (TREE_CODE (decl) == FIELD_DECL);
 
   if (!object)
     {
@@ -1337,6 +1340,10 @@ check_accessibility_of_qualified_id (tree decl,
 {
   tree scope;
   tree qualifying_type = NULL_TREE;
+
+  /* If we're not checking, return imediately.  */
+  if (deferred_access_no_check)
+    return;
   
   /* Determine the SCOPE of DECL.  */
   scope = context_for_name_lookup (decl);
@@ -1377,7 +1384,9 @@ check_accessibility_of_qualified_id (tree decl,
        its bases.  */
     qualifying_type = currently_open_derived_class (scope);
 
-  if (qualifying_type)
+  if (qualifying_type && IS_AGGR_TYPE_CODE (TREE_CODE (qualifying_type)))
+    /* It is possible for qualifying type to be a TEMPLATE_TYPE_PARM
+       or similar in a default argument value.  */
     perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
 }
 
@@ -1486,9 +1495,9 @@ finish_stmt_expr_expr (tree expr, tree stmt_expr)
              expr = build_special_member_call
                (NULL_TREE, complete_ctor_identifier,
                 build_tree_list (NULL_TREE, expr),
-                TYPE_BINFO (type), LOOKUP_NORMAL);
+                type, LOOKUP_NORMAL);
              expr = build_cplus_new (type, expr);
-             my_friendly_assert (TREE_CODE (expr) == TARGET_EXPR, 20030729);
+             gcc_assert (TREE_CODE (expr) == TARGET_EXPR);
            }
        }
 
@@ -1554,7 +1563,7 @@ finish_stmt_expr (tree stmt_expr, bool has_no_scope)
              result_stmt_p = &TREE_OPERAND (t, 0);
              break;
            default:
-             abort ();
+             gcc_unreachable ();
            }
        }
       type = TREE_TYPE (EXPR_STMT_EXPR (result_stmt));
@@ -1573,7 +1582,7 @@ finish_stmt_expr (tree stmt_expr, bool has_no_scope)
         the statement expression itself as the target's init
         expr. Finally, return the target expression.  */
       tree init, target_expr = EXPR_STMT_EXPR (result_stmt);
-      my_friendly_assert (TREE_CODE (target_expr) == TARGET_EXPR, 20030729);
+      gcc_assert (TREE_CODE (target_expr) == TARGET_EXPR);
 
       /* The initializer will be void if the initialization is done by
         AGGR_INIT_EXPR; propagate that out to the statement-expression as
@@ -1592,10 +1601,8 @@ finish_stmt_expr (tree stmt_expr, bool has_no_scope)
             returning a value directly, give it the appropriate type.  */
          if (VOID_TYPE_P (TREE_TYPE (result)))
            TREE_TYPE (result) = type;
-         else if (same_type_p (TREE_TYPE (result), type))
-           ;
          else
-           abort ();
+           gcc_assert (same_type_p (TREE_TYPE (result), type));
        }
       else if (TREE_CODE (result) == STATEMENT_LIST)
        /* We need to wrap a STATEMENT_LIST in a BIND_EXPR so it can have a
@@ -1673,8 +1680,7 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
     return error_mark_node;
 
   /* ARGS should be a list of arguments.  */
-  my_friendly_assert (!args || TREE_CODE (args) == TREE_LIST,
-                     20020712);
+  gcc_assert (!args || TREE_CODE (args) == TREE_LIST);
 
   orig_fn = fn;
   orig_args = args;
@@ -1792,8 +1798,8 @@ finish_call_expr (tree fn, tree args, bool disallow_virtual, bool koenig_p)
 
   if (processing_template_decl)
     {
-      result = build (CALL_EXPR, TREE_TYPE (result), orig_fn,
-                     orig_args, NULL_TREE);
+      result = build3 (CALL_EXPR, TREE_TYPE (result), orig_fn,
+                      orig_args, NULL_TREE);
       KOENIG_LOOKUP_P (result) = koenig_p;
     }
   return result;
@@ -1849,7 +1855,7 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
   if (destructor == error_mark_node)
     return error_mark_node;
 
-  my_friendly_assert (TYPE_P (destructor), 20010905);
+  gcc_assert (TYPE_P (destructor));
 
   if (!processing_template_decl)
     {
@@ -1880,7 +1886,7 @@ finish_pseudo_destructor_expr (tree object, tree scope, tree destructor)
        }
     }
 
-  return build (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
+  return build3 (PSEUDO_DTOR_EXPR, void_type_node, object, scope, destructor);
 }
 
 /* Finish an expression of the form CODE EXPR.  */
@@ -1989,7 +1995,7 @@ finish_template_template_parm (tree aggr, tree identifier)
   DECL_ARTIFICIAL (decl) = 1;
   end_template_decl ();
 
-  my_friendly_assert (DECL_TEMPLATE_PARMS (tmpl), 20010110);
+  gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
 
   return finish_template_type_parm (aggr, tmpl);
 }
@@ -2119,7 +2125,7 @@ finish_member_declaration (tree decl)
     return;
 
   /* We should see only one DECL at a time.  */
-  my_friendly_assert (TREE_CHAIN (decl) == NULL_TREE, 0);
+  gcc_assert (TREE_CHAIN (decl) == NULL_TREE);
 
   /* Set up access control for DECL.  */
   TREE_PRIVATE (decl) 
@@ -2150,7 +2156,7 @@ finish_member_declaration (tree decl)
     {
       /* We also need to add this function to the
         CLASSTYPE_METHOD_VEC.  */
-      add_method (current_class_type, decl, /*error_p=*/0);
+      add_method (current_class_type, decl);
 
       TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
       TYPE_METHODS (current_class_type) = decl;
@@ -2228,7 +2234,8 @@ finish_template_type (tree name, tree args, int entering_scope)
    Return a TREE_LIST containing the ACCESS_SPECIFIER and the
    BASE_CLASS, or NULL_TREE if an error occurred.  The
    ACCESS_SPECIFIER is one of
-   access_{default,public,protected_private}[_virtual]_node.*/
+   access_{default,public,protected_private}_node.  For a virtual base
+   we set TREE_TYPE.  */
 
 tree 
 finish_base_specifier (tree base, tree access, bool virtual_p)
@@ -2250,7 +2257,8 @@ finish_base_specifier (tree base, tree access, bool virtual_p)
           base = TYPE_MAIN_VARIANT (base);
         }
       result = build_tree_list (access, base);
-      TREE_VIA_VIRTUAL (result) = virtual_p;
+      if (virtual_p)
+       TREE_TYPE (result) = integer_type_node;
     }
 
   return result;
@@ -2281,15 +2289,21 @@ check_multiple_declarators (void)
     error ("multiple declarators in template declaration");
 }
 
-/* Issue a diagnostic that NAME cannot be found in SCOPE.  */
+/* Issue a diagnostic that NAME cannot be found in SCOPE.  DECL is
+   what we found when we tried to do the lookup.  */
 
 void
-qualified_name_lookup_error (tree scope, tree name)
+qualified_name_lookup_error (tree scope, tree name, tree decl)
 {
   if (TYPE_P (scope))
     {
       if (!COMPLETE_TYPE_P (scope))
        error ("incomplete type `%T' used in nested name specifier", scope);
+      else if (TREE_CODE (decl) == TREE_LIST)
+       {
+         error ("reference to `%T::%D' is ambiguous", scope, name);
+         print_candidates (decl);
+       }
       else
        error ("`%D' is not a member of `%T'", name, scope);
     }
@@ -2365,7 +2379,7 @@ finish_id_expression (tree id_expression,
              /* If the qualifying type is non-dependent (and the name
                 does not name a conversion operator to a dependent
                 type), issue an error.  */
-             qualified_name_lookup_error (scope, id_expression);
+             qualified_name_lookup_error (scope, id_expression, decl);
              return error_mark_node;
            }
          else if (!scope)
@@ -2531,8 +2545,8 @@ finish_id_expression (tree id_expression,
              if (TYPE_P (scope) && dependent_type_p (scope))
                return build_nt (SCOPE_REF, scope, id_expression);
              else if (TYPE_P (scope) && DECL_P (decl))
-               return build (SCOPE_REF, TREE_TYPE (decl), scope,
-                             id_expression);
+               return build2 (SCOPE_REF, TREE_TYPE (decl), scope,
+                              id_expression);
              else
                return decl;
            }
@@ -2558,25 +2572,15 @@ finish_id_expression (tree id_expression,
       /* Only certain kinds of names are allowed in constant
        expression.  Enumerators and template parameters 
        have already been handled above.  */
-      if (integral_constant_expression_p)
+      if (integral_constant_expression_p
+         && !DECL_INTEGRAL_CONSTANT_VAR_P (decl))
        {
-           /* Const variables or static data members of integral or
-             enumeration types initialized with constant expressions
-             are OK.  */
-         if (TREE_CODE (decl) == VAR_DECL
-             && CP_TYPE_CONST_P (TREE_TYPE (decl))
-             && INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (decl))
-             && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
-           ;
-         else
+         if (!allow_non_integral_constant_expression_p)
            {
-             if (!allow_non_integral_constant_expression_p)
-               {
-                 error ("`%D' cannot appear in a constant-expression", decl);
-                 return error_mark_node;
-               }
-             *non_integral_constant_expression_p = true;
+             error ("`%D' cannot appear in a constant-expression", decl);
+             return error_mark_node;
            }
+         *non_integral_constant_expression_p = true;
        }
       
       if (TREE_CODE (decl) == NAMESPACE_DECL)
@@ -2618,7 +2622,7 @@ finish_id_expression (tree id_expression,
          else if (!processing_template_decl)
            decl = convert_from_reference (decl);
          else if (TYPE_P (scope))
-           decl = build (SCOPE_REF, TREE_TYPE (decl), scope, decl);
+           decl = build2 (SCOPE_REF, TREE_TYPE (decl), scope, decl);
        }
       else if (TREE_CODE (decl) == FIELD_DECL)
        decl = finish_non_static_data_member (decl, current_class_ref,
@@ -2765,12 +2769,11 @@ simplify_aggr_init_expr (tree *tp)
   else if (1)
     style = pcc;
 #endif
-  else if (TREE_ADDRESSABLE (type))
-    style = arg;
   else
-    /* We shouldn't build an AGGR_INIT_EXPR if we don't need any special
-       handling.  See build_cplus_new.  */
-    abort ();
+    {
+      gcc_assert (TREE_ADDRESSABLE (type));
+      style = arg;
+    }
 
   if (style == ctor || style == arg)
     {
@@ -2787,20 +2790,18 @@ simplify_aggr_init_expr (tree *tp)
        {
          /* The return type might have different cv-quals from the slot.  */
          tree fntype = TREE_TYPE (TREE_TYPE (fn));
-#ifdef ENABLE_CHECKING
-         if (TREE_CODE (fntype) != FUNCTION_TYPE
-             && TREE_CODE (fntype) != METHOD_TYPE)
-           abort ();
-#endif
+         
+         gcc_assert (TREE_CODE (fntype) == FUNCTION_TYPE
+                     || TREE_CODE (fntype) == METHOD_TYPE);
          addr = convert (build_pointer_type (TREE_TYPE (fntype)), addr);
        }
 
       args = tree_cons (NULL_TREE, addr, args);
     }
 
-  call_expr = build (CALL_EXPR, 
-                    TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
-                    fn, args, NULL_TREE);
+  call_expr = build3 (CALL_EXPR, 
+                     TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))),
+                     fn, args, NULL_TREE);
 
   if (style == arg)
     /* Tell the backend that we've added our return slot to the argument
@@ -2849,7 +2850,7 @@ emit_associated_thunks (tree fn)
                }
            }
          else
-           my_friendly_assert (!DECL_THUNKS (thunk), 20031023);
+           gcc_assert (!DECL_THUNKS (thunk));
        }
     }
 }
@@ -2886,18 +2887,6 @@ expand_body (tree fn)
 
   extract_interface_info ();
 
-  /* If this function is marked with the constructor attribute, add it
-     to the list of functions to be called along with constructors
-     from static duration objects.  */
-  if (DECL_STATIC_CONSTRUCTOR (fn))
-    static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
-
-  /* If this function is marked with the destructor attribute, add it
-     to the list of functions to be called along with destructors from
-     static duration objects.  */
-  if (DECL_STATIC_DESTRUCTOR (fn))
-    static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
-
   if (DECL_CLONED_FUNCTION_P (fn))
     {
       /* If this is a clone, go through the other clones now and mark
@@ -2951,15 +2940,45 @@ expand_or_defer_fn (tree fn)
       return;
     }
 
+  /* If this function is marked with the constructor attribute, add it
+     to the list of functions to be called along with constructors
+     from static duration objects.  */
+  if (DECL_STATIC_CONSTRUCTOR (fn))
+    static_ctors = tree_cons (NULL_TREE, fn, static_ctors);
+
+  /* If this function is marked with the destructor attribute, add it
+     to the list of functions to be called along with destructors from
+     static duration objects.  */
+  if (DECL_STATIC_DESTRUCTOR (fn))
+    static_dtors = tree_cons (NULL_TREE, fn, static_dtors);
+
+  /* We make a decision about linkage for these functions at the end
+     of the compilation.  Until that point, we do not want the back
+     end to output them -- but we do want it to see the bodies of
+     these functions so that it can inline them as appropriate.  */
+  if (DECL_DECLARED_INLINE_P (fn) || DECL_IMPLICIT_INSTANTIATION (fn))
+    {
+      if (!at_eof)
+       {
+         DECL_EXTERNAL (fn) = 1;
+         DECL_NOT_REALLY_EXTERN (fn) = 1;
+         note_vague_linkage_fn (fn);
+       }
+      else
+       import_export_decl (fn);
+
+      /* If the user wants us to keep all inline functions, then mark
+        this function as needed so that finish_file will make sure to
+        output it later.  */
+      if (flag_keep_inline_functions && DECL_DECLARED_INLINE_P (fn))
+       mark_needed (fn);
+    }
+
   /* There's no reason to do any of the work here if we're only doing
      semantic analysis; this code just generates RTL.  */
   if (flag_syntax_only)
     return;
 
-  /* Compute the appropriate object-file linkage for inline functions.  */
-  if (DECL_DECLARED_INLINE_P (fn))
-    import_export_decl (fn);
-
   function_depth++;
 
   /* Expand or defer, at the whim of the compilation unit manager.  */
@@ -3006,8 +3025,8 @@ finalize_nrv_r (tree* tp, int* walk_subtrees, void* data)
       if (DECL_INITIAL (dp->var)
          && DECL_INITIAL (dp->var) != error_mark_node)
        {
-         init = build (INIT_EXPR, void_type_node, dp->result,
-                       DECL_INITIAL (dp->var));
+         init = build2 (INIT_EXPR, void_type_node, dp->result,
+                        DECL_INITIAL (dp->var));
          DECL_INITIAL (dp->var) = error_mark_node;
        }
       else
@@ -3044,6 +3063,8 @@ finalize_nrv (tree *tp, tree var, tree result)
 
   /* Copy debugging information from VAR to RESULT.  */
   DECL_NAME (result) = DECL_NAME (var);
+  DECL_ARTIFICIAL (result) = DECL_ARTIFICIAL (var);
+  DECL_IGNORED_P (result) = DECL_IGNORED_P (var);
   DECL_SOURCE_LOCATION (result) = DECL_SOURCE_LOCATION (var);
   DECL_ABSTRACT_ORIGIN (result) = DECL_ABSTRACT_ORIGIN (var);
   /* Don't forget that we take its address.  */