c++: rtti cleanups
authorNathan Sidwell <nathan@acm.org>
Tue, 3 Nov 2020 13:08:18 +0000 (05:08 -0800)
committerNathan Sidwell <nathan@acm.org>
Tue, 3 Nov 2020 13:16:31 +0000 (05:16 -0800)
Here are a few cleanups from the modules branch.  Generally some RAII,
and a bit of lazy namespace pushing.

gcc/cp/
* rtti.c (init_rtti_processing): Move var decl to its init.
(get_tinfo_decl): Likewise.  Break out creation to called helper
...
(get_tinfo_decl_direct): ... here.
(build_dynamic_cast_1): Move var decls to their initializers.
(tinfo_base_init): Set decl's location to BUILTINS_LOCATION.
(get_tinfo_desc): Only push ABI namespace when needed.  Set type's
context.

gcc/cp/rtti.c

index 7c4bff76e8c9765da6d56b61d906cfeefc78e005..887aae31bf641f1dffc12caedc41aa1c94124735 100644 (file)
@@ -123,6 +123,7 @@ static GTY (()) vec<tinfo_s, va_gc> *tinfo_descs;
 
 static tree ifnonnull (tree, tree, tsubst_flags_t);
 static tree tinfo_name (tree, bool);
+static tree get_tinfo_decl_direct (tree type, tree name, int pseudo_ix);
 static tree build_dynamic_cast_1 (location_t, tree, tree, tsubst_flags_t);
 static tree throw_bad_cast (void);
 static tree throw_bad_typeid (void);
@@ -166,10 +167,8 @@ pop_abi_namespace (void)
 void
 init_rtti_processing (void)
 {
-  tree type_info_type;
-
   push_nested_namespace (std_node);
-  type_info_type = xref_tag (class_type, get_identifier ("type_info"));
+  tree type_info_type = xref_tag (class_type, get_identifier ("type_info"));
   pop_nested_namespace (std_node);
   const_type_info_type_node
     = cp_build_qualified_type (type_info_type, TYPE_QUAL_CONST);
@@ -414,9 +413,6 @@ tinfo_name (tree type, bool mark_private)
 tree
 get_tinfo_decl (tree type)
 {
-  tree name;
-  tree d;
-
   if (variably_modified_type_p (type, /*fn=*/NULL_TREE))
     {
       error ("cannot create type information for type %qT because "
@@ -429,25 +425,41 @@ get_tinfo_decl (tree type)
     type = build_function_type (TREE_TYPE (type),
                                TREE_CHAIN (TYPE_ARG_TYPES (type)));
 
-  type = complete_type (type);
+  return get_tinfo_decl_direct (type, NULL, -1);
+}
 
+/* Get or create a tinfo VAR_DECL directly from the provided information.
+   The caller must have already checked it is valid to do so.  */
+
+static tree
+get_tinfo_decl_direct (tree type, tree name, int pseudo_ix)
+{
   /* For a class type, the variable is cached in the type node
      itself.  */
+  tree d = NULL_TREE;
+
+  gcc_checking_assert (TREE_CODE (type) != METHOD_TYPE);
+
+  if (pseudo_ix < 0)
+    type = complete_type (type);
+
   if (CLASS_TYPE_P (type))
-    {
-      d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
-      if (d)
-       return d;
-    }
+    d = CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (type));
+
+  if (!name)
+    name = mangle_typeinfo_for_type (type);
 
-  name = mangle_typeinfo_for_type (type);
+  if (!CLASS_TYPE_P (type))
+    d = get_global_binding (name);
 
-  d = get_global_binding (name);
   if (!d)
     {
-      int ix = get_pseudo_ti_index (type);
-      const tinfo_s *ti = get_tinfo_desc (ix);
-      
+      /* Create it.  */
+      if (pseudo_ix < 0)
+       pseudo_ix = get_pseudo_ti_index (type);
+
+      const tinfo_s *ti = get_tinfo_desc (pseudo_ix);
+
       d = build_lang_decl (VAR_DECL, name, ti->type);
       SET_DECL_ASSEMBLER_NAME (d, name);
       /* Remember the type it is for.  */
@@ -754,23 +766,21 @@ build_dynamic_cast_1 (location_t loc, tree type, tree expr,
          dcast_fn = dynamic_cast_node;
          if (!dcast_fn)
            {
-             tree tmp;
-             tree tinfo_ptr;
-             const char *name;
-
              push_abi_namespace ();
-             tinfo_ptr = xref_tag (class_type,
-                                   get_identifier ("__class_type_info"));
-             tinfo_ptr = build_pointer_type
-               (cp_build_qualified_type
-                (tinfo_ptr, TYPE_QUAL_CONST));
-             name = "__dynamic_cast";
-             tmp = build_function_type_list (ptr_type_node,
-                                             const_ptr_type_node,
-                                             tinfo_ptr, tinfo_ptr,
-                                             ptrdiff_type_node, NULL_TREE);
-             dcast_fn = build_library_fn_ptr (name, tmp,
-                                              ECF_LEAF | ECF_PURE | ECF_NOTHROW);
+             tree tinfo_ptr = xref_tag (class_type,
+                                        get_identifier ("__class_type_info"));
+             tinfo_ptr = cp_build_qualified_type (tinfo_ptr, TYPE_QUAL_CONST);
+             tinfo_ptr = build_pointer_type (tinfo_ptr);
+
+             const char *fn_name = "__dynamic_cast";
+             /* void *() (void const *, __class_type_info const *,
+                          __class_type_info const *, ptrdiff_t)  */
+             tree fn_type = (build_function_type_list
+                             (ptr_type_node, const_ptr_type_node,
+                              tinfo_ptr, tinfo_ptr, ptrdiff_type_node,
+                              NULL_TREE));
+             dcast_fn = (build_library_fn_ptr
+                         (fn_name, fn_type, ECF_LEAF | ECF_PURE | ECF_NOTHROW));
              pop_abi_namespace ();
              dynamic_cast_node = dcast_fn;
            }
@@ -947,6 +957,8 @@ tinfo_base_init (tinfo_s *ti, tree target)
     {
       push_abi_namespace ();
       tree real_type = xref_tag (class_type, ti->name);
+      tree real_decl = TYPE_NAME (real_type);
+      DECL_SOURCE_LOCATION (real_decl) = BUILTINS_LOCATION;
       pop_abi_namespace ();
 
       if (!COMPLETE_TYPE_P (real_type))
@@ -1450,8 +1462,6 @@ get_tinfo_desc (unsigned ix)
       }
     }
 
-  push_abi_namespace ();
-
   /* Generate the pseudo type name.  */
   const char *real_name = tinfo_names[ix < TK_VMI_CLASS_TYPES
                                      ? ix : unsigned (TK_VMI_CLASS_TYPES)];
@@ -1468,6 +1478,7 @@ get_tinfo_desc (unsigned ix)
   /* Pass the fields chained in reverse.  */
   finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
   CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;
+  DECL_CONTEXT (TYPE_NAME (pseudo_type)) = FROB_CONTEXT (global_namespace);
   xref_basetypes (pseudo_type, /*bases=*/NULL_TREE);
 
   res->type = cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
@@ -1477,7 +1488,6 @@ get_tinfo_desc (unsigned ix)
      internal linkage.  */
   TREE_PUBLIC (TYPE_MAIN_DECL (res->type)) = 1;
 
-  pop_abi_namespace ();
   return res;
 }
 
@@ -1608,12 +1618,10 @@ emit_support_tinfos (void)
 bool
 emit_tinfo_decl (tree decl)
 {
-  tree type = TREE_TYPE (DECL_NAME (decl));
-  int in_library = typeinfo_in_lib_p (type);
-
   gcc_assert (DECL_TINFO_P (decl));
 
-  if (in_library)
+  tree type = TREE_TYPE (DECL_NAME (decl));
+  if (typeinfo_in_lib_p (type))
     {
       if (doing_runtime)
        DECL_EXTERNAL (decl) = 0;