Beispiel #1
0
static tree
create_pseudo_type_info (const char *real_name, int ident, ...)
{
  tree pseudo_type;
  char *pseudo_name;
  tree fields;
  tree field_decl;
  tree result;
  va_list ap;

  va_start (ap, ident);

  /* Generate the pseudo type name.  */
  pseudo_name = alloca (strlen (real_name) + 30);
  strcpy (pseudo_name, real_name);
  strcat (pseudo_name, "_pseudo");
  if (ident)
    sprintf (pseudo_name + strlen (pseudo_name), "%d", ident);
  
  /* First field is the pseudo type_info base class.  */
  fields = build_decl (FIELD_DECL, NULL_TREE, ti_desc_type_node);
  
  /* Now add the derived fields.  */
  while ((field_decl = va_arg (ap, tree)))
    {
      TREE_CHAIN (field_decl) = fields;
      fields = field_decl;
    }
  
  /* Create the pseudo type.  */
  pseudo_type = make_aggr_type (RECORD_TYPE);
  finish_builtin_struct (pseudo_type, pseudo_name, fields, NULL_TREE);
  CLASSTYPE_AS_BASE (pseudo_type) = pseudo_type;

  result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
  TINFO_REAL_NAME (result) = get_identifier (real_name);
  TINFO_PSEUDO_TYPE (result) =
    cp_build_qualified_type (pseudo_type, TYPE_QUAL_CONST);
  
  va_end (ap);
  return result;
}
Beispiel #2
0
static tree
call_eh_info ()
{
  tree fn;

  fn = get_identifier ("__start_cp_handler");
  if (IDENTIFIER_GLOBAL_VALUE (fn))
    fn = IDENTIFIER_GLOBAL_VALUE (fn);
  else
    {
      tree t1, t, fields[7];

      /* Declare cp_eh_info * __start_cp_handler (void),
	 as defined in exception.cc. */

      /* struct cp_eh_info.  This must match exception.cc.  Note that this
	 type is not pushed anywhere.  */
      t1= make_aggr_type (RECORD_TYPE);
      fields[0] = build_decl (FIELD_DECL, 
                    get_identifier ("handler_label"), ptr_type_node);
      fields[1] = build_decl (FIELD_DECL, 
                    get_identifier ("dynamic_handler_chain"), ptr_type_node);
      fields[2] = build_decl (FIELD_DECL, 
                    get_identifier ("info"), ptr_type_node);
      fields[3] = build_decl (FIELD_DECL, 
                    get_identifier ("table_index"), ptr_type_node);
      /* N.B.: The fourth field LEN is expected to be
	 the number of fields - 1, not the total number of fields.  */
      finish_builtin_type (t1, "eh_context", fields, 3, ptr_type_node);
      t1 = build_pointer_type (t1);

      t1= make_aggr_type (RECORD_TYPE);
#ifdef TARG_XTENSA
      fields[0] = build_decl (FIELD_DECL, 
                    get_identifier ("version"), integer_type_node);
      /* N.B.: The fourth field LEN is expected to be
	 the number of fields - 1, not the total number of fields.  */
      finish_builtin_type (t1, "__eh_info", fields, 0, ptr_type_node);
#else
      fields[0] = build_decl (FIELD_DECL, 
                    get_identifier ("match_function"), ptr_type_node);
      fields[1] = build_decl (FIELD_DECL, 
                    get_identifier ("language"), short_integer_type_node);
      fields[2] = build_decl (FIELD_DECL, 
                    get_identifier ("version"), short_integer_type_node);
      /* N.B.: The fourth field LEN is expected to be
	 the number of fields - 1, not the total number of fields.  */
      finish_builtin_type (t1, "__eh_info", fields, 2, ptr_type_node);
#endif
      t = make_aggr_type (RECORD_TYPE);
      fields[0] = build_decl (FIELD_DECL, 
			      get_identifier ("eh_info"), t1);
      fields[1] = build_decl (FIELD_DECL, get_identifier ("value"),
			      ptr_type_node);
      fields[2] = build_decl (FIELD_DECL, get_identifier ("type"),
			      ptr_type_node);
      fields[3] = build_decl
	(FIELD_DECL, get_identifier ("cleanup"),
	 build_pointer_type (build_function_type
			     (ptr_type_node, tree_cons
			      (NULL_TREE, ptr_type_node, void_list_node))));
      fields[4] = build_decl (FIELD_DECL, get_identifier ("caught"),
			      boolean_type_node);
      fields[5] = build_decl (FIELD_DECL, get_identifier ("next"),
			      build_pointer_type (t));
      fields[6] = build_decl
	(FIELD_DECL, get_identifier ("handlers"), long_integer_type_node);
      /* N.B.: The fourth field LEN is expected to be
	 the number of fields - 1, not the total number of fields.  */
      finish_builtin_type (t, "cp_eh_info", fields, 6, ptr_type_node);
      t = build_pointer_type (t);

      /* And now the function.  */
      fn = push_library_fn (fn, build_function_type (t, void_list_node));
    }
  return build_function_call (fn, NULL_TREE);
}
Beispiel #3
0
static void
create_tinfo_types (void)
{
  gcc_assert (!ti_desc_type_node);

  push_nested_namespace (abi_node);
  
  /* Create the internal type_info structure. This is used as a base for
     the other structures.  */
  {
    tree field, fields;

    ti_desc_type_node = make_aggr_type (RECORD_TYPE);
    field = build_decl (FIELD_DECL, NULL_TREE, const_ptr_type_node);
    fields = field;
    
    field = build_decl (FIELD_DECL, NULL_TREE, const_string_type_node);
    TREE_CHAIN (field) = fields;
    fields = field;
    
    finish_builtin_struct (ti_desc_type_node, "__type_info_pseudo",
			   fields, NULL_TREE);
    TYPE_HAS_CONSTRUCTOR (ti_desc_type_node) = 1;
  }
  
  /* Fundamental type_info */
  bltn_desc_type_node = create_pseudo_type_info
      ("__fundamental_type_info", 0,
       NULL);

  /* Array, function and enum type_info. No additional fields.  */
  ary_desc_type_node = create_pseudo_type_info
      ("__array_type_info", 0,
       NULL);
  func_desc_type_node = create_pseudo_type_info
       ("__function_type_info", 0,
        NULL);
  enum_desc_type_node = create_pseudo_type_info
       ("__enum_type_info", 0,
        NULL);
  
  /* Class type_info. Add a flags field.  */
  class_desc_type_node = create_pseudo_type_info
        ("__class_type_info", 0,
         NULL);
  
  /* Single public non-virtual base class. Add pointer to base class. 
     This is really a descendant of __class_type_info.  */
  si_class_desc_type_node = create_pseudo_type_info
           ("__si_class_type_info", 0,
            build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
            NULL);
  
  /* Base class internal helper. Pointer to base type, offset to base,
     flags.  */
  {
    tree field, fields;
    
    field = build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type);
    fields = field;
    
    field = build_decl (FIELD_DECL, NULL_TREE, integer_types[itk_long]);
    TREE_CHAIN (field) = fields;
    fields = field;
  
    base_desc_type_node = make_aggr_type (RECORD_TYPE);
    finish_builtin_struct (base_desc_type_node, "__base_class_type_info_pseudo",
			   fields, NULL_TREE);
    TYPE_HAS_CONSTRUCTOR (base_desc_type_node) = 1;
  }
  
  /* General hierarchy is created as necessary in this vector.  */
  vmi_class_desc_type_node = make_tree_vec (10);
  
  /* Pointer type_info. Adds two fields, qualification mask
     and pointer to the pointed to type.  This is really a descendant of
     __pbase_type_info.  */
  ptr_desc_type_node = create_pseudo_type_info
      ("__pointer_type_info", 0,
       build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
       build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
       NULL);

  /* Pointer to member data type_info.  Add qualifications flags,
     pointer to the member's type info and pointer to the class.
     This is really a descendant of __pbase_type_info.  */
  ptm_desc_type_node = create_pseudo_type_info
       ("__pointer_to_member_type_info", 0,
        build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
        build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
        build_decl (FIELD_DECL, NULL_TREE, type_info_ptr_type),
        NULL);

  pop_nested_namespace (abi_node);
}