]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/rtti.c
* rtti.c (synthesize_tinfo_fn): Set DECL_DEFER_OUTPUT.
[gcc.git] / gcc / cp / rtti.c
index e0ce5cd8666661d75b2b60e402322ee8aee3c627..87d6df11ef645514c04879af3432609515f20047 100644 (file)
@@ -48,10 +48,6 @@ static void expand_ptr_desc PROTO((tree, tree));
 static void expand_generic_desc PROTO((tree, tree, const char *));
 static tree throw_bad_cast PROTO((void));
 static tree throw_bad_typeid PROTO((void));
-
-tree type_info_type_node;
-tree tinfo_fn_id;
-tree tinfo_fn_type;
 \f
 void
 init_rtti_processing ()
@@ -302,7 +298,7 @@ build_x_typeid (exp)
       tree bad = throw_bad_typeid ();
 
       bad = build_compound_expr
-       (expr_tree_cons (NULL_TREE, bad, build_expr_list
+       (tree_cons (NULL_TREE, bad, build_expr_list
                    (NULL_TREE, cp_convert (type, integer_zero_node))));
       exp = build (COND_EXPR, type, cond, exp, bad);
     }
@@ -355,8 +351,10 @@ get_tinfo_var (type)
   TREE_PUBLIC (tdecl) = 1;
   DECL_EXTERNAL (tdecl) = 1;
   DECL_ARTIFICIAL (tdecl) = 1;
-  pushdecl_top_level (tdecl);
+  push_to_top_level ();
+  pushdecl (tdecl);
   cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
+  pop_from_top_level ();
 
   pop_obstacks ();
 
@@ -389,7 +387,7 @@ get_tinfo_fn (type)
   DECL_ARTIFICIAL (d) = 1;
   DECL_NOT_REALLY_EXTERN (d) = 1;
   SET_DECL_TINFO_FN_P (d);
-  TREE_TYPE (name) = copy_to_permanent (type);
+  TREE_TYPE (name) = type;
 
   pushdecl_top_level (d);
   make_function_rtl (d);
@@ -426,9 +424,6 @@ get_typeid (type)
       return error_mark_node;
     }
   
-  if (! flag_rtti)
-    error ("requesting typeid with -fno-rtti");
-
   if (processing_template_decl)
     return build_min_nt (TYPEID_EXPR, type);
 
@@ -590,6 +585,7 @@ build_dynamic_cast_1 (type, expr)
        {
          tree retval;
           tree result, td1, td2, td3, elems, expr2;
+          tree static_type, target_type, boff;
 
          /* If we got here, we can't convert statically.  Therefore,
             dynamic_cast<D&>(b) (b an object) cannot succeed.  */
@@ -634,20 +630,23 @@ build_dynamic_cast_1 (type, expr)
            td1 = get_tinfo_fn_dynamic (expr);
          td1 = decay_conversion (td1);
          
-         td2 = decay_conversion
-           (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type))));
-         td3 = decay_conversion
-           (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype))));
+         target_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
+         static_type = TYPE_MAIN_VARIANT (TREE_TYPE (exprtype));
+         td2 = decay_conversion (get_tinfo_fn (target_type));
+         td3 = decay_conversion (get_tinfo_fn (static_type));
+
+          /* Determine how T and V are related.  */
+          boff = get_dynamic_cast_base_type (static_type, target_type);
 
           elems = tree_cons
            (NULL_TREE, td1, tree_cons
             (NULL_TREE, td2, tree_cons
-             (NULL_TREE, build_int_2 (1, 0), tree_cons
+             (NULL_TREE, boff, tree_cons
               (NULL_TREE, expr2, tree_cons
-               (NULL_TREE, td3, tree_cons
+               (NULL_TREE, td3, tree_cons
                 (NULL_TREE, expr1, NULL_TREE))))));
 
-         dcast_fn = get_identifier ("__dynamic_cast");
+         dcast_fn = get_identifier ("__dynamic_cast_2");
          if (IDENTIFIER_GLOBAL_VALUE (dcast_fn))
            dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn);
          else
@@ -658,7 +657,7 @@ build_dynamic_cast_1 (type, expr)
              tmp = tree_cons
                (NULL_TREE, TREE_TYPE (td1), tree_cons
                 (NULL_TREE, TREE_TYPE (td1), tree_cons
-                 (NULL_TREE, integer_type_node, tree_cons
+                 (NULL_TREE, integer_type_node, tree_cons
                   (NULL_TREE, ptr_type_node, tree_cons
                    (NULL_TREE, TREE_TYPE (td1), tree_cons
                     (NULL_TREE, ptr_type_node, void_list_node))))));
@@ -680,7 +679,7 @@ build_dynamic_cast_1 (type, expr)
            {
              expr1 = throw_bad_cast ();
              expr1 = build_compound_expr
-               (expr_tree_cons (NULL_TREE, expr1,
+               (tree_cons (NULL_TREE, expr1,
                            build_expr_list (NULL_TREE, cp_convert (type, integer_zero_node))));
              TREE_TYPE (expr1) = type;
              result = save_expr (result);
@@ -693,6 +692,9 @@ build_dynamic_cast_1 (type, expr)
        }
     }
 
+  cp_error ("dynamic_cast from non-polymorphic type `%#T'", exprtype);
+  return error_mark_node;
+
  fail:
   cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'",
            expr, exprtype, type);
@@ -707,7 +709,7 @@ build_dynamic_cast (type, expr)
     return error_mark_node;
   
   if (processing_template_decl)
-    return build_min (DYNAMIC_CAST_EXPR, copy_to_permanent (type), expr);
+    return build_min (DYNAMIC_CAST_EXPR, type, expr);
 
   return convert_from_reference (build_dynamic_cast_1 (type, expr));
 }
@@ -726,8 +728,6 @@ build_dynamic_cast (type, expr)
    Note: these constructors always return the address of the descriptor
    info, since that is simplest for their mutual interaction.  */
 
-extern tree const_string_type_node;
-
 /* Build an initializer for a __si_type_info node.  */
 
 static void
@@ -740,7 +740,7 @@ expand_si_desc (tdecl, type)
   tree name_string = combine_strings (build_string (strlen (name)+1, name));
 
   type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0));
-  expand_expr_stmt (get_typeid_1 (type));
+  finish_expr_stmt (get_typeid_1 (type));
   t = decay_conversion (get_tinfo_var (type));
   elems = tree_cons
     (NULL_TREE, decay_conversion (tdecl), tree_cons
@@ -772,7 +772,7 @@ expand_si_desc (tdecl, type)
 
   mark_used (fn);
   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
-  expand_expr_stmt (fn);
+  finish_expr_stmt (fn);
 }
 
 /* Build an initializer for a __class_type_info node.  */
@@ -808,23 +808,23 @@ expand_class_desc (tdecl, type)
       base_info_type_node = make_lang_type (RECORD_TYPE);
 
       /* Actually const __user_type_info * */
-      fields [0] = build_lang_field_decl
+      fields [0] = build_lang_decl
        (FIELD_DECL, NULL_TREE,
         build_pointer_type (build_qualified_type
                             (type_info_type_node,
                              TYPE_QUAL_CONST)));
-      fields [1] = build_lang_field_decl
+      fields [1] = build_lang_decl
        (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node);
       DECL_BIT_FIELD (fields[1]) = 1;
       DECL_FIELD_SIZE (fields[1]) = 29;
 
-      fields [2] = build_lang_field_decl
+      fields [2] = build_lang_decl
        (FIELD_DECL, NULL_TREE, boolean_type_node);
       DECL_BIT_FIELD (fields[2]) = 1;
       DECL_FIELD_SIZE (fields[2]) = 1;
 
       /* Actually enum access */
-      fields [3] = build_lang_field_decl
+      fields [3] = build_lang_decl
        (FIELD_DECL, NULL_TREE, integer_type_node);
       DECL_BIT_FIELD (fields[3]) = 1;
       DECL_FIELD_SIZE (fields[3]) = 2;
@@ -838,7 +838,7 @@ expand_class_desc (tdecl, type)
     {
       tree binfo = TREE_VEC_ELT (binfos, i);
 
-      expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
+      finish_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo)));
       base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo)));
 
       if (TREE_VIA_VIRTUAL (binfo))
@@ -874,7 +874,7 @@ expand_class_desc (tdecl, type)
           (NULL_TREE, isvir, tree_cons
            (NULL_TREE, access, NULL_TREE)))));
       TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1;
-      elts = expr_tree_cons (NULL_TREE, elt, elts);
+      elts = tree_cons (NULL_TREE, elt, elts);
       base_cnt++;
     }
 #if 0
@@ -901,10 +901,10 @@ expand_class_desc (tdecl, type)
       offset = BINFO_OFFSET (vb);
       isvir = build_int_2 (1, 0);
 
-      base_list = expr_tree_cons (NULL_TREE, base, base_list);
-      isvir_list = expr_tree_cons (NULL_TREE, isvir, isvir_list);
-      acc_list = expr_tree_cons (NULL_TREE, access, acc_list);
-      off_list = expr_tree_cons (NULL_TREE, offset, off_list);
+      base_list = tree_cons (NULL_TREE, base, base_list);
+      isvir_list = tree_cons (NULL_TREE, isvir, isvir_list);
+      acc_list = tree_cons (NULL_TREE, access, acc_list);
+      off_list = tree_cons (NULL_TREE, offset, off_list);
 
       base_cnt++;
       vb = TREE_CHAIN (vb);
@@ -953,7 +953,7 @@ expand_class_desc (tdecl, type)
 
   mark_used (fn);
   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
-  expand_expr_stmt (fn);
+  finish_expr_stmt (fn);
 }
 
 /* Build an initializer for a __pointer_type_info node.  */
@@ -968,7 +968,7 @@ expand_ptr_desc (tdecl, type)
   tree name_string = combine_strings (build_string (strlen (name)+1, name));
 
   type = TREE_TYPE (type);
-  expand_expr_stmt (get_typeid_1 (type));
+  finish_expr_stmt (get_typeid_1 (type));
   t = decay_conversion (get_tinfo_var (type));
   elems = tree_cons
     (NULL_TREE, decay_conversion (tdecl), tree_cons
@@ -1000,7 +1000,7 @@ expand_ptr_desc (tdecl, type)
 
   mark_used (fn);
   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
-  expand_expr_stmt (fn);
+  finish_expr_stmt (fn);
 }
 
 /* Build an initializer for a __attr_type_info node.  */
@@ -1015,12 +1015,12 @@ expand_attr_desc (tdecl, type)
   tree name_string = combine_strings (build_string (strlen (name)+1, name));
   tree attrval = build_int_2 (TYPE_QUALS (type), 0);
 
-  expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
+  finish_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type)));
   t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type)));
   elems = tree_cons
     (NULL_TREE, decay_conversion (tdecl), tree_cons
      (NULL_TREE, decay_conversion (name_string), tree_cons
-      (NULL_TREE, attrval, expr_tree_cons (NULL_TREE, t, NULL_TREE))));
+      (NULL_TREE, attrval, tree_cons (NULL_TREE, t, NULL_TREE))));
 
   fn = get_identifier ("__rtti_attr");
   if (IDENTIFIER_GLOBAL_VALUE (fn))
@@ -1048,7 +1048,7 @@ expand_attr_desc (tdecl, type)
 
   mark_used (fn);
   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
-  expand_expr_stmt (fn);
+  finish_expr_stmt (fn);
 }
 
 /* Build an initializer for a type_info node that just has a name.  */
@@ -1088,7 +1088,7 @@ expand_generic_desc (tdecl, type, fnname)
 
   mark_used (fn);
   fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems);
-  expand_expr_stmt (fn);
+  finish_expr_stmt (fn);
 }
 
 /* Generate the code for a type_info initialization function.
@@ -1110,6 +1110,9 @@ synthesize_tinfo_fn (fndecl)
 {
   tree type = TREE_TYPE (DECL_NAME (fndecl));
   tree tmp, addr, tdecl;
+  tree compound_stmt;
+  tree if_stmt;
+  tree then_clause;
 
   if (at_eof)
     {
@@ -1118,6 +1121,7 @@ synthesize_tinfo_fn (fndecl)
        return;
     }
 
+  /* Declare the static typeinfo variable.  */
   tdecl = get_tinfo_var (type);
   DECL_EXTERNAL (tdecl) = 0;
   TREE_STATIC (tdecl) = 1;
@@ -1126,18 +1130,28 @@ synthesize_tinfo_fn (fndecl)
   DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node);
   cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0);
 
-  start_function (NULL_TREE, fndecl, NULL_TREE, 1);
+  /* Begin processing the function.  */
+  start_function (NULL_TREE, fndecl, NULL_TREE, 
+                 SF_DEFAULT | SF_PRE_PARSED);
+  DECL_DEFER_OUTPUT (fndecl) = 1;
   store_parm_decls ();
   clear_last_expr ();
-  push_momentary ();
+
+  /* Begin the body of the function.  */
+  compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
+
+  /* For convenience, we save away the address of the static
+     variable.  */
+  addr = decay_conversion (tdecl);
 
   /* If the first word of the array (the vtable) is non-zero, we've already
      initialized the object, so don't do it again.  */
-  addr = decay_conversion (tdecl);
+  if_stmt = begin_if_stmt ();
   tmp = cp_convert (build_pointer_type (ptr_type_node), addr);
   tmp = build_indirect_ref (tmp, 0);
   tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node);
-  expand_start_cond (tmp, 0);
+  finish_if_stmt_cond (tmp, if_stmt);
+  then_clause = begin_compound_stmt (/*has_no_scope=*/0);
 
   if (TREE_CODE (type) == FUNCTION_TYPE)
     expand_generic_desc (tdecl, type, "__rtti_func");
@@ -1172,11 +1186,15 @@ synthesize_tinfo_fn (fndecl)
   else
     my_friendly_abort (252);
 
-  expand_end_cond ();
+  finish_compound_stmt (/*has_no_scope=*/0, then_clause);
+  finish_then_clause (if_stmt);
+  finish_if_stmt ();
 
   /* OK, now return the type_info object.  */
   tmp = cp_convert (build_pointer_type (type_info_type_node), addr);
   tmp = build_indirect_ref (tmp, 0);
-  c_expand_return (tmp);
-  finish_function (lineno, 0, 0);
+  finish_return_stmt (tmp);
+  /* Finish the function body.  */
+  finish_compound_stmt (/*has_no_scope=*/0, compound_stmt);
+  expand_body (finish_function (lineno, 0));
 }
This page took 0.035877 seconds and 5 git commands to generate.