示例#1
0
static tree
ptm_initializer (tree desc, tree target)
{
  tree init = tinfo_base_init (desc, target);
  tree to = TYPE_PTRMEM_POINTED_TO_TYPE (target);
  tree klass = TYPE_PTRMEM_CLASS_TYPE (target);
  int flags = qualifier_flags (to);
  bool incomplete = target_incomplete_p (to);
  
  if (incomplete)
    flags |= 0x8;
  if (!COMPLETE_TYPE_P (klass))
    flags |= 0x10;
  init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init);
  init = tree_cons (NULL_TREE,
		    get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
                    init);
  init = tree_cons (NULL_TREE,
		    get_tinfo_ptr (klass),
		    init);  
  
  init = build_constructor (NULL_TREE, nreverse (init));
  TREE_CONSTANT (init) = 1;
  TREE_INVARIANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;  
}
示例#2
0
static tree
generic_initializer (tree desc, tree target)
{
  tree init = tinfo_base_init (desc, target);
  
  init = build_constructor (NULL_TREE, init);
  TREE_CONSTANT (init) = 1;
  TREE_INVARIANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;
}
示例#3
0
static tree
class_initializer (tree desc, tree target, tree trail)
{
  tree init = tinfo_base_init (desc, target);
  
  TREE_CHAIN (init) = trail;
  init = build_constructor (NULL_TREE, init);
  TREE_CONSTANT (init) = 1;
  TREE_INVARIANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;  
}
示例#4
0
/* Build a reference to a literal string.  */
static tree
mf_build_string (const char *string)
{
  size_t len = strlen (string);
  tree result = mf_mark (build_string (len + 1, string));

  TREE_TYPE (result) = build_array_type
    (char_type_node, build_index_type (build_int_cst (NULL_TREE, len)));
  TREE_CONSTANT (result) = 1;
  TREE_INVARIANT (result) = 1;
  TREE_READONLY (result) = 1;
  TREE_STATIC (result) = 1;

  result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result);

  return mf_mark (result);
}
示例#5
0
bool
is_gimple_min_invariant (tree t)
{
  switch (TREE_CODE (t))
    {
    case ADDR_EXPR:
      return TREE_INVARIANT (t);

    case INTEGER_CST:
    case REAL_CST:
    case STRING_CST:
    case COMPLEX_CST:
    case VECTOR_CST:
      return true;

    default:
      return false;
    }
}
void
compile_resource_data (const char *name, const char *buffer, int length)
{
  tree rtype, field = NULL_TREE, data_type, rinit, data, decl;
  char buf[60];

  data_type = build_prim_array_type (unsigned_byte_type_node,
				     strlen (name) + length);
  rtype = make_node (RECORD_TYPE);
  PUSH_FIELD (rtype, field, "name_length", unsigned_int_type_node);
  PUSH_FIELD (rtype, field, "resource_length", unsigned_int_type_node);
  PUSH_FIELD (rtype, field, "data", data_type);
  FINISH_RECORD (rtype);
  START_RECORD_CONSTRUCTOR (rinit, rtype);
  PUSH_FIELD_VALUE (rinit, "name_length", 
		    build_int_cst (NULL_TREE, strlen (name)));
  PUSH_FIELD_VALUE (rinit, "resource_length", 
		    build_int_cst (NULL_TREE, length));
  data = build_string (strlen(name) + length, buffer);
  TREE_TYPE (data) = data_type;
  PUSH_FIELD_VALUE (rinit, "data", data);
  FINISH_RECORD_CONSTRUCTOR (rinit);
  TREE_CONSTANT (rinit) = 1;
  TREE_INVARIANT (rinit) = 1;

  /* Generate a unique-enough identifier.  */
  sprintf (buf, "_Jr%d", ++Jr_count);

  decl = build_decl (VAR_DECL, get_identifier (buf), rtype);
  TREE_STATIC (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  TREE_READONLY (decl) = 1;
  TREE_THIS_VOLATILE (decl) = 0;
  DECL_INITIAL (decl) = rinit;
  layout_decl (decl, 0);
  pushdecl (decl);
  rest_of_decl_compilation (decl, global_bindings_p (), 0);
  make_decl_rtl (decl);
  assemble_variable (decl, 1, 0, 0);

  resources = tree_cons (NULL_TREE, decl, resources);
}
示例#7
0
static tree
ptr_initializer (tree desc, tree target)
{
  tree init = tinfo_base_init (desc, target);
  tree to = TREE_TYPE (target);
  int flags = qualifier_flags (to);
  bool incomplete = target_incomplete_p (to);
  
  if (incomplete)
    flags |= 8;
  init = tree_cons (NULL_TREE, build_int_cst (NULL_TREE, flags), init);
  init = tree_cons (NULL_TREE,
                    get_tinfo_ptr (TYPE_MAIN_VARIANT (to)),
                    init);
  
  init = build_constructor (NULL_TREE, nreverse (init));
  TREE_CONSTANT (init) = 1;
  TREE_INVARIANT (init) = 1;
  TREE_STATIC (init) = 1;
  return init;
}
示例#8
0
static tree
tinfo_base_init (tree desc, tree target)
{
  tree init = NULL_TREE;
  tree name_decl;
  tree vtable_ptr;
  
  {
    tree name_name;
    
    /* Generate the NTBS array variable.  */
    tree name_type = build_cplus_array_type
                     (build_qualified_type (char_type_node, TYPE_QUAL_CONST),
                     NULL_TREE);
    tree name_string = tinfo_name (target);

    /* Determine the name of the variable -- and remember with which
       type it is associated.  */
    name_name = mangle_typeinfo_string_for_type (target);
    TREE_TYPE (name_name) = target;

    name_decl = build_lang_decl (VAR_DECL, name_name, name_type);
    SET_DECL_ASSEMBLER_NAME (name_decl, name_name);
    DECL_ARTIFICIAL (name_decl) = 1;
    DECL_IGNORED_P (name_decl) = 1;
    TREE_READONLY (name_decl) = 1;
    TREE_STATIC (name_decl) = 1;
    DECL_EXTERNAL (name_decl) = 0;
    DECL_TINFO_P (name_decl) = 1;
    if (involves_incomplete_p (target))
      {
	TREE_PUBLIC (name_decl) = 0;
	DECL_INTERFACE_KNOWN (name_decl) = 1;
      }
    else
      set_linkage_according_to_type (target, name_decl);
    import_export_decl (name_decl);
    DECL_INITIAL (name_decl) = name_string;
    mark_used (name_decl);
    pushdecl_top_level_and_finish (name_decl, name_string);
  }

  vtable_ptr = TINFO_VTABLE_DECL (desc);
  if (!vtable_ptr)
    {
      tree real_type;
  
      push_nested_namespace (abi_node);
      real_type = xref_tag (class_type, TINFO_REAL_NAME (desc),
			    /* APPLE LOCAL 4184203 */
			    /*tag_scope=*/ts_global, false);
      pop_nested_namespace (abi_node);
  
      if (!COMPLETE_TYPE_P (real_type))
	{
          /* We never saw a definition of this type, so we need to
	     tell the compiler that this is an exported class, as
	     indeed all of the __*_type_info classes are.  */
	  SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
	  CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
	}

      vtable_ptr = get_vtable_decl (real_type, /*complete=*/1);
      vtable_ptr = build_unary_op (ADDR_EXPR, vtable_ptr, 0);

      /* We need to point into the middle of the vtable.  */
      vtable_ptr = build2
	(PLUS_EXPR, TREE_TYPE (vtable_ptr), vtable_ptr,
	 size_binop (MULT_EXPR,
		     size_int (2 * TARGET_VTABLE_DATA_ENTRY_DISTANCE),
		     TYPE_SIZE_UNIT (vtable_entry_type)));

      TINFO_VTABLE_DECL (desc) = vtable_ptr;
    }

  init = tree_cons (NULL_TREE, vtable_ptr, init);
  
  init = tree_cons (NULL_TREE, decay_conversion (name_decl), init);
  
  init = build_constructor (NULL_TREE, nreverse (init));
  TREE_CONSTANT (init) = 1;
  TREE_INVARIANT (init) = 1;
  TREE_STATIC (init) = 1;
  init = tree_cons (NULL_TREE, init, NULL_TREE);
  
  return init;
}
示例#9
0
static void
create_common (gfc_common_head *com)
{
  segment_info *s, *next_s;
  tree union_type;
  tree *field_link;
  record_layout_info rli;
  tree decl;
  bool is_init = false;

  /* Declare the variables inside the common block.  */
  union_type = make_node (UNION_TYPE);
  rli = start_record_layout (union_type);
  field_link = &TYPE_FIELDS (union_type);

  for (s = current_common; s; s = s->next)
    {
      build_field (s, union_type, rli);

      /* Link the field into the type.  */
      *field_link = s->field;
      field_link = &TREE_CHAIN (s->field);

      /* Has initial value.  */
      if (s->sym->value)
        is_init = true;
    }
  finish_record_layout (rli, true);

  if (com)
    decl = build_common_decl (com, union_type, is_init);
  else
    decl = build_equiv_decl (union_type, is_init);

  if (is_init)
    {
      tree list, ctor, tmp;
      HOST_WIDE_INT offset = 0;

      list = NULL_TREE;
      for (s = current_common; s; s = s->next)
        {
          if (s->sym->value)
            {
              if (s->offset < offset)
                {
		    /* We have overlapping initializers.  It could either be
		       partially initialized arrays (legal), or the user
		       specified multiple initial values (illegal).
		       We don't implement this yet, so bail out.  */
                  gfc_todo_error ("Initialization of overlapping variables");
                }
	      /* Add the initializer for this field.  */
	      tmp = gfc_conv_initializer (s->sym->value, &s->sym->ts,
		  TREE_TYPE (s->field), s->sym->attr.dimension,
		  s->sym->attr.pointer || s->sym->attr.allocatable);
	      list = tree_cons (s->field, tmp, list);
              offset = s->offset + s->length;
            }
        }
      gcc_assert (list);
      ctor = build1 (CONSTRUCTOR, union_type, nreverse(list));
      TREE_CONSTANT (ctor) = 1;
      TREE_INVARIANT (ctor) = 1;
      TREE_STATIC (ctor) = 1;
      DECL_INITIAL (decl) = ctor;

#ifdef ENABLE_CHECKING
      for (tmp = CONSTRUCTOR_ELTS (ctor); tmp; tmp = TREE_CHAIN (tmp))
	gcc_assert (TREE_CODE (TREE_PURPOSE (tmp)) == FIELD_DECL);
#endif
    }

  /* Build component reference for each variable.  */
  for (s = current_common; s; s = next_s)
    {
      s->sym->backend_decl = build3 (COMPONENT_REF, TREE_TYPE (s->field),
				     decl, s->field, NULL_TREE);

      next_s = s->next;
      gfc_free (s);
    }
}