class.c (instantiate_type): Don't just return a known type if it's wrong.
[gcc.git] / gcc / cp / tree.c
index d212bb223d4c076a0be7248d0ed068f61d5125fb..16bcb1357351fc98a265e44b59c2ac70fed97d3a 100644 (file)
@@ -32,6 +32,25 @@ Boston, MA 02111-1307, USA.  */
 #include <varargs.h>
 #endif
 
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_DECLARATION_FREE
+extern void free       PROTO((void *));
+#endif
+
+extern void compiler_error ();
+
+static tree get_identifier_list PROTO((tree));
+static tree bot_manip PROTO((tree));
+static tree perm_manip PROTO((tree));
+static tree build_cplus_array_type_1 PROTO((tree, tree));
+static void list_hash_add PROTO((int, tree));
+static int list_hash PROTO((tree, tree, tree));
+static tree list_hash_lookup PROTO((int, int, int, int, tree, tree,
+                                   tree));
+
 #define CEIL(x,y) (((x) + (y) - 1) / (y))
 
 /* Return nonzero if REF is an lvalue valid for this language.
@@ -59,6 +78,9 @@ real_lvalue_p (ref)
     case PREDECREMENT_EXPR:
     case COMPONENT_REF:
     case SAVE_EXPR:
+    case UNSAVE_EXPR:
+    case TRY_CATCH_EXPR:
+    case WITH_CLEANUP_EXPR:
       return real_lvalue_p (TREE_OPERAND (ref, 0));
 
     case STRING_CST:
@@ -103,6 +125,9 @@ real_lvalue_p (ref)
     case MIN_EXPR:
       return (real_lvalue_p (TREE_OPERAND (ref, 0))
              && real_lvalue_p (TREE_OPERAND (ref, 1)));
+
+    default:
+      break;
     }
 
   return 0;
@@ -133,6 +158,9 @@ lvalue_p (ref)
     case IMAGPART_EXPR:
     case COMPONENT_REF:
     case SAVE_EXPR:
+    case UNSAVE_EXPR:
+    case TRY_CATCH_EXPR:
+    case WITH_CLEANUP_EXPR:
       return lvalue_p (TREE_OPERAND (ref, 0));
 
     case STRING_CST:
@@ -185,6 +213,9 @@ lvalue_p (ref)
     case MIN_EXPR:
       return (lvalue_p (TREE_OPERAND (ref, 0))
              && lvalue_p (TREE_OPERAND (ref, 1)));
+
+    default:
+      break;
     }
 
   return 0;
@@ -219,18 +250,36 @@ build_cplus_new (type, init)
   tree slot;
   tree rval;
 
-  if (TREE_CODE (init) == TARGET_EXPR || init == error_mark_node)
+  if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR)
     return init;
 
   slot = build (VAR_DECL, type);
+  DECL_ARTIFICIAL (slot) = 1;
   layout_decl (slot, 0);
-  rval = build (NEW_EXPR, type,
+  rval = build (AGGR_INIT_EXPR, type,
                TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot);
   TREE_SIDE_EFFECTS (rval) = 1;
-  TREE_ADDRESSABLE (rval) = 1;
   rval = build (TARGET_EXPR, type, slot, rval, NULL_TREE, NULL_TREE);
   TREE_SIDE_EFFECTS (rval) = 1;
-  TREE_ADDRESSABLE (rval) = 1;
+
+  return rval;
+}
+
+/* Encapsulate the expression INIT in a TARGET_EXPR.  */
+
+tree
+get_target_expr (init)
+     tree init;
+{
+  tree slot;
+  tree rval;
+
+  slot = build (VAR_DECL, TREE_TYPE (init));
+  DECL_ARTIFICIAL (slot) = 1;
+  layout_decl (slot, 0);
+  rval = build (TARGET_EXPR, TREE_TYPE (init), slot, init,
+               NULL_TREE, NULL_TREE);
+  TREE_SIDE_EFFECTS (rval) = 1;
 
   return rval;
 }
@@ -1250,12 +1299,14 @@ int
 is_overloaded_fn (x)
      tree x;
 {
-  if (TREE_CODE (x) == FUNCTION_DECL)
+  if (TREE_CODE (x) == FUNCTION_DECL
+      || TREE_CODE (x) == TEMPLATE_ID_EXPR
+      || DECL_FUNCTION_TEMPLATE_P (x))
     return 1;
 
   if (TREE_CODE (x) == TREE_LIST
       && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
-         || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
+         || DECL_FUNCTION_TEMPLATE_P (TREE_VALUE (x))))
     return 1;
 
   return 0;
@@ -1265,19 +1316,17 @@ int
 really_overloaded_fn (x)
      tree x;
 {     
-  if (TREE_CODE (x) == TREE_LIST
-      && (TREE_CODE (TREE_VALUE (x)) == FUNCTION_DECL
-         || TREE_CODE (TREE_VALUE (x)) == TEMPLATE_DECL))
-    return 1;
-
-  return 0;
+  return TREE_CODE (x) != FUNCTION_DECL 
+    && is_overloaded_fn (x);
 }
 
 tree
 get_first_fn (from)
      tree from;
 {
-  if (TREE_CODE (from) == FUNCTION_DECL)
+  if (TREE_CODE (from) == FUNCTION_DECL
+      || TREE_CODE (from) == TEMPLATE_ID_EXPR
+      || DECL_FUNCTION_TEMPLATE_P (from))
     return from;
 
   my_friendly_assert (TREE_CODE (from) == TREE_LIST, 9);
@@ -1293,25 +1342,6 @@ is_aggr_type_2 (t1, t2)
     return 0;
   return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2);
 }
-
-/* Give message using types TYPE1 and TYPE2 as arguments.
-   PFN is the function which will print the message;
-   S is the format string for PFN to use.  */
-
-void
-message_2_types (pfn, s, type1, type2)
-     void (*pfn) ();
-     char *s;
-     tree type1, type2;
-{
-  tree name1 = TYPE_NAME (type1);
-  tree name2 = TYPE_NAME (type2);
-  if (TREE_CODE (name1) == TYPE_DECL)
-    name1 = DECL_NAME (name1);
-  if (TREE_CODE (name2) == TYPE_DECL)
-    name2 = DECL_NAME (name2);
-  (*pfn) (s, IDENTIFIER_POINTER (name1), IDENTIFIER_POINTER (name2));
-}
 \f
 #define PRINT_RING_SIZE 4
 
@@ -1400,6 +1430,27 @@ build_exception_variant (type, raises)
   return v;
 }
 
+/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new one together with its 
+   lang_specific field and its corresponding TEMPLATE_DECL node */
+
+tree
+copy_template_template_parm (t)
+     tree t;
+{
+  tree template = TYPE_NAME (t);
+  tree t2 = make_lang_type (TEMPLATE_TEMPLATE_PARM);
+  template = copy_node (template);
+  copy_lang_decl (template);
+  TREE_TYPE (template) = t2;
+  TYPE_NAME (t2) = template;
+  TYPE_STUB_DECL (t2) = template;
+
+  /* No need to copy these */
+  TYPE_FIELDS (t2) = TYPE_FIELDS (t);
+  CLASSTYPE_TEMPLATE_INFO (t2) = CLASSTYPE_TEMPLATE_INFO (t);
+  return t2;
+}
+
 /* Subroutine of copy_to_permanent
 
    Assuming T is a node build bottom-up, make it all exist on
@@ -1408,7 +1459,7 @@ build_exception_variant (type, raises)
 tree
 mapcar (t, func)
      tree t;
-     tree (*func)();
+     tree (*func) PROTO((tree));
 {
   tree tmp;
 
@@ -1426,7 +1477,11 @@ mapcar (t, func)
     case VAR_DECL:
     case FUNCTION_DECL:
     case CONST_DECL:
-      break;
+      /* Rather than aborting, return error_mark_node.  This allows us
+        to report a sensible error message on code like this:
+
+        void g() { int i; f<i>(7); } */
+      return error_mark_node;
 
     case PARM_DECL:
       {
@@ -1466,7 +1521,7 @@ mapcar (t, func)
 
     case COND_EXPR:
     case TARGET_EXPR:
-    case NEW_EXPR:
+    case AGGR_INIT_EXPR:
       t = copy_node (t);
       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
       TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
@@ -1513,6 +1568,8 @@ mapcar (t, func)
     case POSTINCREMENT_EXPR:
     case ARRAY_REF:
     case SCOPE_REF:
+    case TRY_CATCH_EXPR:
+    case WITH_CLEANUP_EXPR:
       t = copy_node (t);
       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
       TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
@@ -1541,6 +1598,7 @@ mapcar (t, func)
     case TRUTH_NOT_EXPR:
     case NOP_EXPR:
     case COMPONENT_REF:
+    case CLEANUP_POINT_EXPR:
       t = copy_node (t);
       TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
       return t;
@@ -1584,6 +1642,9 @@ mapcar (t, func)
       CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func);
       return t;
 
+    case TEMPLATE_TEMPLATE_PARM:
+      return copy_template_template_parm (t);
+
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
        return build_ptrmemfunc_type
@@ -1650,11 +1711,9 @@ extern int depth_reached;
 void
 print_lang_statistics ()
 {
-  extern struct obstack maybepermanent_obstack, decl_obstack;
+  extern struct obstack decl_obstack;
   print_obstack_statistics ("class_obstack", &class_obstack);
   print_obstack_statistics ("decl_obstack", &decl_obstack);
-  print_obstack_statistics ("permanent_obstack", &permanent_obstack);
-  print_obstack_statistics ("maybepermanent_obstack", &maybepermanent_obstack);
   print_search_statistics ();
   print_class_statistics ();
 #ifdef GATHER_STATISTICS
@@ -1728,7 +1787,7 @@ bot_manip (t)
     return t;
   else if (TREE_CODE (t) == TARGET_EXPR)
     {
-      if (TREE_CODE (TREE_OPERAND (t, 1)) == NEW_EXPR)
+      if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
        {
          mark_used (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 1), 0), 0));
          return build_cplus_new
@@ -1757,8 +1816,6 @@ break_out_target_exprs (t)
 /* Obstack used for allocating nodes in template function and variable
    definitions.  */
 
-extern struct obstack *expression_obstack;
-
 /* Similar to `build_nt', except we build
    on the permanent_obstack, regardless.  */
 
@@ -1858,8 +1915,6 @@ tree
 get_type_decl (t)
      tree t;
 {
-  if (TREE_CODE (t) == IDENTIFIER_NODE)
-    return identifier_typedecl_value (t);
   if (TREE_CODE (t) == TYPE_DECL)
     return t;
   if (TREE_CODE_CLASS (TREE_CODE (t)) == 't')
@@ -2015,14 +2070,19 @@ cp_tree_equal (t1, t2)
       return 0;
 
     case TEMPLATE_CONST_PARM:
-      return TEMPLATE_CONST_IDX (t1) == TEMPLATE_CONST_IDX (t2);
+      return TEMPLATE_CONST_IDX (t1) == TEMPLATE_CONST_IDX (t2)
+       && TEMPLATE_CONST_LEVEL (t1) == TEMPLATE_CONST_LEVEL (t2);
 
     case SIZEOF_EXPR:
+    case ALIGNOF_EXPR:
       if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
        return 0;
       if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t1, 0))) == 't')
        return comptypes (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0), 1);
       break;
+
+    default:
+      break;
     }
 
   switch (TREE_CODE_CLASS (code1))
@@ -2054,13 +2114,20 @@ make_temp_vec (len)
      int len;
 {
   register tree node;
-  push_obstacks_nochange ();
-  resume_temporary_allocation ();
+  register struct obstack *ambient_obstack = current_obstack;
+  current_obstack = expression_obstack;
   node = make_tree_vec (len);
-  pop_obstacks ();
+  current_obstack = ambient_obstack;
   return node;
 }
 
+void
+push_expression_obstack ()
+{
+  push_obstacks_nochange ();
+  current_obstack = expression_obstack;
+}
+
 /* The type of ARG when used as an lvalue.  */
 
 tree