Пример #1
0
void
record_vars (tree vars)
{
  for (; vars; vars = TREE_CHAIN (vars))
    {
      tree var = vars;

      /* Nothing to do in this case.  */
      if (DECL_EXTERNAL (var))
	continue;
      if (TREE_CODE (var) == FUNCTION_DECL)
	continue;

      /* Record the variable.  */
      cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
					     cfun->unexpanded_var_list);
    }
}
Пример #2
0
void
finish_stmt_tree (tree *t)
{
    tree stmt;

    /* Remove the fake extra statement added in begin_stmt_tree.  */
    stmt = TREE_CHAIN (*t);
    *t = stmt;
    last_tree = NULL_TREE;

    if (cfun && stmt)
    {
        /* The line-number recorded in the outermost statement in a function
        is the line number of the end of the function.  */
        STMT_LINENO (stmt) = input_line;
        STMT_LINENO_FOR_FN_P (stmt) = 1;
    }
}
Пример #3
0
void
flush_pending_stmts (edge e)
{
  tree phi, arg;

  if (!PENDING_STMT (e))
    return;

  for (phi = phi_nodes (e->dest), arg = PENDING_STMT (e);
       phi;
       phi = PHI_CHAIN (phi), arg = TREE_CHAIN (arg))
    {
      tree def = TREE_VALUE (arg);
      add_phi_arg (phi, def, e);
    }

  PENDING_STMT (e) = NULL;
}
Пример #4
0
/*
 ****************************************************************
 *	Same as `tree_cons' but make a permanent object		*
 ****************************************************************
 */
tree
perm_tree_cons (tree purpose, tree value, tree chain)
{
	register tree	 node;
	register OBSTACK *ambient_obstack = current_obstack;

	current_obstack = &permanent_obstack;

	node = make_node (TREE_LIST);
	TREE_CHAIN (node) = chain;
	TREE_PURPOSE (node) = purpose;
	TREE_VALUE (node) = value;

	current_obstack = ambient_obstack;

	return (node);

}	/* end perm_tree_cons */
Пример #5
0
void
handle_pre_generic (void *event_data, void *data)
{
  tree fndecl = (tree) event_data;
  tree arg;
  for (arg = DECL_ARGUMENTS(fndecl); arg; arg = DECL_CHAIN (arg)) {
      tree attr;
      for (attr = DECL_ATTRIBUTES (arg); attr; attr = TREE_CHAIN (attr)) {
          tree attrname = TREE_PURPOSE (attr);
          tree attrargs = TREE_VALUE (attr);
          warning (0, G_("attribute '%s' on param '%s' of function %s"),
                   IDENTIFIER_POINTER (attrname),
                   IDENTIFIER_POINTER (DECL_NAME (arg)),
                   IDENTIFIER_POINTER (DECL_NAME (fndecl))
                   );
      }
  }
}
Пример #6
0
void
cxx_print_xnode (FILE *file, tree node, int indent)
{
  switch (TREE_CODE (node))
    {
    case BASELINK:
      print_node (file, "functions", BASELINK_FUNCTIONS (node), indent + 4);
      print_node (file, "binfo", BASELINK_BINFO (node), indent + 4);
      print_node (file, "access_binfo", BASELINK_ACCESS_BINFO (node),
		  indent + 4);
      break;
    case OVERLOAD:
      print_node (file, "function", OVL_FUNCTION (node), indent+4);
      print_node (file, "chain", TREE_CHAIN (node), indent+4);
      break;
    case TEMPLATE_PARM_INDEX:
      indent_to (file, indent + 3);
      fprintf (file, "index %d level %d orig_level %d",
	       TEMPLATE_PARM_IDX (node), TEMPLATE_PARM_LEVEL (node),
	       TEMPLATE_PARM_ORIG_LEVEL (node));
      break;
    case TEMPLATE_INFO:
      print_node (file, "template", TI_TEMPLATE (node), indent+4);
      print_node (file, "args", TI_ARGS (node), indent+4);
      if (TI_PENDING_TEMPLATE_FLAG (node))
	{
	  indent_to (file, indent + 3);
	  fprintf (file, "pending_template");
	}
      break;
    case ARGUMENT_PACK_SELECT:
      print_node (file, "pack", ARGUMENT_PACK_SELECT_FROM_PACK (node),
		  indent+4);
      indent_to (file, indent + 3);
      fprintf (file, "index %d", ARGUMENT_PACK_SELECT_INDEX (node));
      break;
    case DEFERRED_NOEXCEPT:
      print_node (file, "pattern", DEFERRED_NOEXCEPT_PATTERN (node), indent+4);
      print_node (file, "args", DEFERRED_NOEXCEPT_ARGS (node), indent+4);
      break;
    default:
      break;
    }
}
static int
mangle_record_type (tree type, int for_pointer)
{
  tree current;
  int match;
  int nadded_p = 0;
  int qualified;
  
  /* Does this name have a package qualifier? */
  qualified = QUALIFIED_P (DECL_NAME (TYPE_NAME (type)));

#define ADD_N() \
  do { obstack_1grow (mangle_obstack, 'N'); nadded_p = 1; } while (0)

  gcc_assert (TREE_CODE (type) == RECORD_TYPE);

  if (!TYPE_PACKAGE_LIST (type))
    set_type_package_list (type);

  match = find_compression_record_match (type, &current);
  if (match >= 0)
    {
      /* If we had a pointer, and there's more, we need to emit
	 'N' after 'P' (for_pointer tells us we already emitted it.) */
      if (for_pointer && current)
	ADD_N();
      emit_compression_string (match);
    }
  while (current)
    {
      /* Add the new type to the table */
      compression_table_add (TREE_PURPOSE (current));
      /* Add 'N' if we never got a chance to, but only if we have a qualified
         name.  For non-pointer elements, the name is always qualified. */
      if ((qualified || !for_pointer) && !nadded_p)
	ADD_N();
      /* Use the bare type name for the mangle. */
      append_gpp_mangled_name (IDENTIFIER_POINTER (TREE_VALUE (current)),
			       IDENTIFIER_LENGTH (TREE_VALUE (current)));
      current = TREE_CHAIN (current);
    }
  return nadded_p;
#undef ADD_N
}
Пример #8
0
static tree
gen_regparm_prefix (tree decl, unsigned nregs)
{
  unsigned total = 0;
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
     of DECL_ASSEMBLER_NAME.  */
  const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  char *newsym;
  tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));

  if (formal_type != NULL_TREE)
    {
      /* This attribute is ignored for variadic functions.  */ 
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
	return NULL_TREE;

      /* Quit if we hit an incomplete type.  Error is reported
	 by convert_arguments in c-typeck.c or cp/typeck.c.  */
      while (TREE_VALUE (formal_type) != void_type_node
	     && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))	
	{
	  unsigned parm_size
	    = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));

	  /* Must round up to include padding.  This is done the same
	     way as in store_one_arg.  */
	  parm_size = ((parm_size + PARM_BOUNDARY - 1)
		       / PARM_BOUNDARY * PARM_BOUNDARY);
	  total += parm_size;
	  formal_type = TREE_CHAIN (formal_type);
	}
    }

  if (nregs > total / BITS_PER_WORD)
    nregs = total / BITS_PER_WORD;
  gcc_assert (nregs <= 9);
  newsym = alloca (3 + strlen (asmname) + 1);
  return get_identifier_with_length (newsym,
				     sprintf (newsym,
					      "_%u@%s",
					      nregs,
					      asmname));
}
Пример #9
0
static void
sdbout_dequeue_anonymous_types (void)
{
  tree types, link;

  while (anonymous_types)
    {
      types = nreverse (anonymous_types);
      anonymous_types = NULL_TREE;

      for (link = types; link; link = TREE_CHAIN (link))
	{
	  tree type = TREE_VALUE (link);

	  if (type && ! TREE_ASM_WRITTEN (type))
	    sdbout_one_type (type);
	}
    }
}
Пример #10
0
static void
record_common_node (struct streamer_tree_cache_d *cache, tree node)
{
  /* If we recursively end up at nodes we do not want to preload simply don't.
     ???  We'd want to verify that this doesn't happen, or alternatively
     do not recurse at all.  */
  if (node == char_type_node)
    return;

  gcc_checking_assert (node != boolean_type_node
		       && node != boolean_true_node
		       && node != boolean_false_node);

  /* We have to make sure to fill exactly the same number of
     elements for all frontends.  That can include NULL trees.
     As our hash table can't deal with zero entries we'll simply stream
     a random other tree.  A NULL tree never will be looked up so it
     doesn't matter which tree we replace it with, just to be sure
     use error_mark_node.  */
  if (!node)
    node = error_mark_node;

  /* ???  FIXME, devise a better hash value.  But the hash needs to be equal
     for all frontend and lto1 invocations.  So just use the position
     in the cache as hash value.  */
  streamer_tree_cache_append (cache, node, cache->nodes.length ());

  if (POINTER_TYPE_P (node)
      || TREE_CODE (node) == COMPLEX_TYPE
      || TREE_CODE (node) == ARRAY_TYPE)
    record_common_node (cache, TREE_TYPE (node));
  else if (TREE_CODE (node) == RECORD_TYPE)
    {
      /* The FIELD_DECLs of structures should be shared, so that every
	 COMPONENT_REF uses the same tree node when referencing a field.
	 Pointer equality between FIELD_DECLs is used by the alias
	 machinery to compute overlapping component references (see
	 nonoverlapping_component_refs_p and
	 nonoverlapping_component_refs_of_decl_p).  */
      for (tree f = TYPE_FIELDS (node); f; f = TREE_CHAIN (f))
	record_common_node (cache, f);
    }
}
Пример #11
0
static tree
gen_stdcall_or_fastcall_decoration (tree decl, char prefix)
{
  unsigned total = 0;
  /* ??? This probably should use XSTR (XEXP (DECL_RTL (decl), 0), 0) instead
     of DECL_ASSEMBLER_NAME.  */
  const char *asmname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
  char *newsym;
  tree formal_type = TYPE_ARG_TYPES (TREE_TYPE (decl));

  if (formal_type != NULL_TREE)
    {
      /* These attributes are ignored for variadic functions in
	 i386.c:ix86_return_pops_args. For compatibility with MS
	 compiler do not add @0 suffix here.  */ 
      if (TREE_VALUE (tree_last (formal_type)) != void_type_node)
	return NULL_TREE;

      /* Quit if we hit an incomplete type.  Error is reported
	 by convert_arguments in c-typeck.c or cp/typeck.c.  */
      while (TREE_VALUE (formal_type) != void_type_node
	     && COMPLETE_TYPE_P (TREE_VALUE (formal_type)))	
	{
	  unsigned parm_size
	    = TREE_INT_CST_LOW (TYPE_SIZE (TREE_VALUE (formal_type)));

	  /* Must round up to include padding.  This is done the same
	     way as in store_one_arg.  */
	  parm_size = ((parm_size + PARM_BOUNDARY - 1)
		       / PARM_BOUNDARY * PARM_BOUNDARY);
	  total += parm_size;
	  formal_type = TREE_CHAIN (formal_type);
	}
    }

  newsym = alloca (1 + strlen (asmname) + 1 + 10 + 1);
  return get_identifier_with_length (newsym,
				     sprintf (newsym,
					      "%c%s@%u",
					      prefix,
					      asmname,
					      total / BITS_PER_UNIT));
}
Пример #12
0
/* Helper for mudflap_init: construct a tree corresponding to the type
     struct __mf_cache { uintptr_t low; uintptr_t high; };
     where uintptr_t is the FIELD_TYPE argument.  */
static inline tree
mf_make_mf_cache_struct_type (tree field_type)
{
  /* There is, abominably, no language-independent way to construct a
     RECORD_TYPE.  So we have to call the basic type construction
     primitives by hand.  */
  tree fieldlo = build_decl (FIELD_DECL, get_identifier ("low"), field_type);
  tree fieldhi = build_decl (FIELD_DECL, get_identifier ("high"), field_type);

  tree struct_type = make_node (RECORD_TYPE);
  DECL_CONTEXT (fieldlo) = struct_type;
  DECL_CONTEXT (fieldhi) = struct_type;
  TREE_CHAIN (fieldlo) = fieldhi;
  TYPE_FIELDS (struct_type) = fieldlo;
  TYPE_NAME (struct_type) = get_identifier ("__mf_cache");
  layout_type (struct_type);

  return struct_type;
}
Пример #13
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;
}
Пример #14
0
static tree
synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
                           void *client)
{
  tree raises = empty_except_spec;
  tree fields = TYPE_FIELDS (type);
  int i, n_bases = CLASSTYPE_N_BASECLASSES (type);
  tree binfos = TYPE_BINFO_BASETYPES (type);

  for (i = 0; i != n_bases; i++)
    {
      tree base = BINFO_TYPE (TREE_VEC_ELT (binfos, i));
      tree fn = (*extractor) (base, client);
      if (fn)
        {
          tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
          
          raises = merge_exception_specifiers (raises, fn_raises);
        }
    }
  for (; fields; fields = TREE_CHAIN (fields))
    {
      tree type = TREE_TYPE (fields);
      tree fn;
      
      if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
        continue;
      while (TREE_CODE (type) == ARRAY_TYPE)
  	type = TREE_TYPE (type);
      if (!CLASS_TYPE_P (type))
        continue;
      
      fn = (*extractor) (type, client);
      if (fn)
        {
          tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));
          
          raises = merge_exception_specifiers (raises, fn_raises);
        }
    }
  return raises;
}
Пример #15
0
tree
c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses)
{
  tree c;
  vec<tree> clvec = vNULL;

  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    {
      if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
	  && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
	  && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
	{
	  tree decl = OMP_CLAUSE_DECL (c);
	  tree arg;
	  int idx;
	  for (arg = parms, idx = 0; arg;
	       arg = TREE_CHAIN (arg), idx++)
	    if (arg == decl)
	      break;
	  if (arg == NULL_TREE)
	    {
	      error_at (OMP_CLAUSE_LOCATION (c),
			"%qD is not an function argument", decl);
	      continue;
	    }
	  OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, idx);
	}
      clvec.safe_push (c);
    }
  if (!clvec.is_empty ())
    {
      unsigned int len = clvec.length (), i;
      clvec.qsort (c_omp_declare_simd_clause_cmp);
      clauses = clvec[0];
      for (i = 0; i < len; i++)
	OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE;
    }
  else
    clauses = NULL_TREE;
  clvec.release ();
  return clauses;
}
Пример #16
0
static bool
wrapper_parm_cb (const void *key0, void **val0, void *data)
{
  struct wrapper_data *wd = (struct wrapper_data *) data;
  tree arg = * (tree *)&key0;
  tree val = (tree)*val0;
  tree parm;

  if (val == error_mark_node || val == arg)
    return true;

  if (TREE_CODE (val) == PAREN_EXPR)
    {
      /* We should not reach here with a register receiver.
	 We may see a register variable modified in the
	 argument list.  Because register variables are
	 worker-local we don't need to work hard to support
	 them in code that spawns.  */
      if ((TREE_CODE (arg) == VAR_DECL) && DECL_HARD_REGISTER (arg))
	{
	  error_at (EXPR_LOCATION (arg),
		    "explicit register variable %qD may not be modified in "
		    "spawn", arg);
	  arg = null_pointer_node;
	}
      else
	arg = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), arg);
	
      val = TREE_OPERAND (val, 0);
      *val0 = val;
      gcc_assert (TREE_CODE (val) == INDIRECT_REF);
      parm = TREE_OPERAND (val, 0);
      STRIP_NOPS (parm);
    }
  else
    parm = val;
  TREE_CHAIN (parm) = wd->parms;
  wd->parms = parm;
  wd->argtypes = tree_cons (NULL_TREE, TREE_TYPE (parm), wd->argtypes); 
  wd->arglist = tree_cons (NULL_TREE, arg, wd->arglist); 
  return true;
}
Пример #17
0
static tree
synthesize_exception_spec (tree type, tree (*extractor) (tree, void*),
                           void *client)
{
    tree raises = empty_except_spec;
    tree fields = TYPE_FIELDS (type);
    tree binfo, base_binfo;
    int i;

    for (binfo = TYPE_BINFO (type), i = 0;
            BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    {
        tree fn = (*extractor) (BINFO_TYPE (base_binfo), client);
        if (fn)
        {
            tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));

            raises = merge_exception_specifiers (raises, fn_raises);
        }
    }
    for (; fields; fields = TREE_CHAIN (fields))
    {
        tree type = TREE_TYPE (fields);
        tree fn;

        if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
            continue;
        while (TREE_CODE (type) == ARRAY_TYPE)
            type = TREE_TYPE (type);
        if (!CLASS_TYPE_P (type))
            continue;

        fn = (*extractor) (type, client);
        if (fn)
        {
            tree fn_raises = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn));

            raises = merge_exception_specifiers (raises, fn_raises);
        }
    }
    return raises;
}
Пример #18
0
void
record_vars (tree vars)
{
  for (; vars; vars = TREE_CHAIN (vars))
    {
      tree var = vars;

      /* BIND_EXPRs contains also function/type/constant declarations
         we don't need to care about.  */
      if (TREE_CODE (var) != VAR_DECL)
	continue;
      /* Nothing to do in this case.  */
      if (DECL_EXTERNAL (var))
	continue;

      /* Record the variable.  */
      cfun->unexpanded_var_list = tree_cons (NULL_TREE, var,
					     cfun->unexpanded_var_list);
    }
}
Пример #19
0
static void
sdbout_field_types (tree type)
{
  tree tail;

  for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
    /* This condition should match the one for emitting the actual
       members below.  */
    if (TREE_CODE (tail) == FIELD_DECL
	&& DECL_NAME (tail)
	&& DECL_SIZE (tail)
	&& host_integerp (DECL_SIZE (tail), 1)
	&& host_integerp (bit_position (tail), 0))
      {
	if (POINTER_TYPE_P (TREE_TYPE (tail)))
	  sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
	else
	  sdbout_one_type (TREE_TYPE (tail));
      }
}
Пример #20
0
void
c_omp_declare_simd_clauses_to_decls (tree fndecl, tree clauses)
{
  tree c;

  for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_SIMDLEN
	&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_INBRANCH
	&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_NOTINBRANCH)
      {
	int idx = tree_to_shwi (OMP_CLAUSE_DECL (c)), i;
	tree arg;
	for (arg = DECL_ARGUMENTS (fndecl), i = 0; arg;
	     arg = TREE_CHAIN (arg), i++)
	  if (i == idx)
	    break;
	gcc_assert (arg);
	OMP_CLAUSE_DECL (c) = arg;
      }
}
unsigned int find_arg_number_tree(const_tree arg, const_tree func)
{
	tree var;
	unsigned int argnum = 1;

	if (DECL_ARGUMENTS(func) == NULL_TREE)
		return CANNOT_FIND_ARG;

	if (TREE_CODE(arg) == SSA_NAME)
		arg = SSA_NAME_VAR(arg);

	for (var = DECL_ARGUMENTS(func); var; var = TREE_CHAIN(var), argnum++) {
		if (!operand_equal_p(arg, var, 0) && strcmp(DECL_NAME_POINTER(var), DECL_NAME_POINTER(arg)))
			continue;
		if (!skip_types(var))
			return argnum;
	}

	return CANNOT_FIND_ARG;
}
Пример #22
0
/* Return false if the function FNDECL cannot be inlined on account of its
   attributes, true otherwise.  */
bool
function_attribute_inlinable_p (const_tree fndecl)
{
  if (targetm.attribute_table)
    {
      const_tree a;

      for (a = DECL_ATTRIBUTES (fndecl); a; a = TREE_CHAIN (a))
	{
	  const_tree name = TREE_PURPOSE (a);
	  int i;

	  for (i = 0; targetm.attribute_table[i].name != NULL; i++)
	    if (is_attribute_p (targetm.attribute_table[i].name, name))
	      return targetm.function_attribute_inlinable_p (fndecl);
	}
    }

  return true;
}
Пример #23
0
/* Used only by build_*_selector_translation_table (). */
void
diagnose_missing_method (tree meth, location_t here)
{
  tree method_chain;
  bool found = false;
  for (method_chain = meth_var_names_chain;
       method_chain;
       method_chain = TREE_CHAIN (method_chain))
    {
      if (TREE_VALUE (method_chain) == meth)
	{
	  found = true;
	  break;
	}
     }

  if (!found)
    warning_at (here, 0, "creating selector for nonexistent method %qE",
			meth);
}
Пример #24
0
void
genrtl_scope_stmt (tree t)
{
    tree block = SCOPE_STMT_BLOCK (t);

    if (!SCOPE_NO_CLEANUPS_P (t))
    {
        if (SCOPE_BEGIN_P (t))
            expand_start_bindings_and_block (2 * SCOPE_NULLIFIED_P (t), block);
        else if (SCOPE_END_P (t))
            expand_end_bindings (NULL_TREE, !SCOPE_NULLIFIED_P (t), 0);
    }
    else if (!SCOPE_NULLIFIED_P (t))
    {
        rtx note = emit_note (SCOPE_BEGIN_P (t)
                              ? NOTE_INSN_BLOCK_BEG : NOTE_INSN_BLOCK_END);
        NOTE_BLOCK (note) = block;
    }

    /* If we're at the end of a scope that contains inlined nested
       functions, we have to decide whether or not to write them out.  */
    if (block && SCOPE_END_P (t))
    {
        tree fn;

        for (fn = BLOCK_VARS (block); fn; fn = TREE_CHAIN (fn))
        {
            if (TREE_CODE (fn) == FUNCTION_DECL
                    && DECL_CONTEXT (fn) == current_function_decl
                    && DECL_SAVED_INSNS (fn)
                    && DECL_SAVED_INSNS (fn)->saved_for_inline
                    && !TREE_ASM_WRITTEN (fn)
                    && TREE_ADDRESSABLE (fn))
            {
                push_function_context ();
                output_inline_function (fn);
                pop_function_context ();
            }
        }
    }
}
Пример #25
0
void
finish_eh_spec_block (tree raw_raises, tree eh_spec_block)
{
  tree raises;

  EH_SPEC_STMTS (eh_spec_block) = pop_stmt_list (EH_SPEC_STMTS (eh_spec_block));

  /* Strip cv quals, etc, from the specification types.  */
  for (raises = NULL_TREE;
       raw_raises && TREE_VALUE (raw_raises);
       raw_raises = TREE_CHAIN (raw_raises))
    {
      tree type = prepare_eh_type (TREE_VALUE (raw_raises));
      tree tinfo = eh_type_info (type);

      mark_used (tinfo);
      raises = tree_cons (NULL_TREE, type, raises);
    }

  EH_SPEC_RAISES (eh_spec_block) = raises;
}
Пример #26
0
static void
record_type_list (cgraph_node *node, tree list)
{
  for (; list; list = TREE_CHAIN (list))
    {
      tree type = TREE_VALUE (list);
      
      if (TYPE_P (type))
	type = lookup_type_for_runtime (type);
      STRIP_NOPS (type);
      if (TREE_CODE (type) == ADDR_EXPR)
	{
	  type = TREE_OPERAND (type, 0);
	  if (TREE_CODE (type) == VAR_DECL)
	    {
	      varpool_node *vnode = varpool_node::get_create (type);
	      node->create_reference (vnode, IPA_REF_ADDR);
	    }
	}
    }
}
Пример #27
0
void
generate_protocol_references (tree plist)
{
  tree lproto;

  /* Forward declare protocols referenced.  */
  for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto))
    {
      tree proto = TREE_VALUE (lproto);

      if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE
	  && PROTOCOL_NAME (proto))
	{
          if (! PROTOCOL_FORWARD_DECL (proto))
            PROTOCOL_FORWARD_DECL (proto) = (*runtime.protocol_decl) (proto);

          if (PROTOCOL_LIST (proto))
            generate_protocol_references (PROTOCOL_LIST (proto));
        }
    }
}
Пример #28
0
tree
streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
{
  tree first, prev, curr;

  /* The chain is written as NULL terminated list of trees.  */
  first = prev = NULL_TREE;
  do
    {
      curr = stream_read_tree (ib, data_in);
      if (prev)
	TREE_CHAIN (prev) = curr;
      else
	first = curr;

      prev = curr;
    }
  while (curr);

  return first;
}
Пример #29
0
void
streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
{
  while (t)
    {
      /* We avoid outputting external vars or functions by reference
	 to the global decls section as we do not want to have them
	 enter decl merging.  This is, of course, only for the call
	 for streaming BLOCK_VARS, but other callers are safe.
	 See also lto-streamer-out.c:DFS_write_tree_body.  */
      if (VAR_OR_FUNCTION_DECL_P (t)
	  && DECL_EXTERNAL (t))
	stream_write_tree_shallow_non_ref (ob, t, ref_p);
      else
	stream_write_tree (ob, t, ref_p);

      t = TREE_CHAIN (t);
    }

  /* Write a sentinel to terminate the chain.  */
  stream_write_tree (ob, NULL_TREE, ref_p);
}
void
crx_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
		      rtx libfunc ATTRIBUTE_UNUSED)
{
  tree param, next_param;

  cum->ints = 0;

  /* Determine if this function has variable arguments.  This is indicated by
   * the last argument being 'void_type_mode' if there are no variable
   * arguments.  Change here for a different vararg.  */
  for (param = (fntype) ? TYPE_ARG_TYPES (fntype) : 0;
       param != (tree) 0; param = next_param)
    {
      next_param = TREE_CHAIN (param);
      if (next_param == (tree) 0 && TREE_VALUE (param) != void_type_node)
	{
	  cum->ints = -1;
	  return;
	}
    }
}