Ejemplo n.º 1
0
static tree
ubsan_source_location (location_t loc)
{
  expanded_location xloc;
  tree type = ubsan_source_location_type ();

  xloc = expand_location (loc);
  if (xloc.file == NULL)
    xloc.file = "<unknown>";

  /* Fill in the values from LOC.  */
  size_t len = strlen (xloc.file);
  tree str = build_string (len + 1, xloc.file);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  str = build_fold_addr_expr (str);
  tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
				    build_int_cst (unsigned_type_node,
						   xloc.line), NULL_TREE,
				    build_int_cst (unsigned_type_node,
						   xloc.column));
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;

  return ctor;
}
Ejemplo n.º 2
0
static tree
make_fname_decl ()
{
    const char *name = lang_hooks.decl_printable_name (current_function_decl, 0);
    tree decl, type, init;
    size_t length = strlen (name);

    type = build_array_type (build_type_variant (char_type_node, true, false),
                             build_index_type (size_int (length)));

    decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
                       get_identifier ("__function_name__"), type);

    TREE_STATIC (decl) = 1;
    TREE_READONLY (decl) = 1;
    DECL_ARTIFICIAL (decl) = 1;

    init = build_string (length + 1, name);
    TREE_TYPE (init) = type;
    TREE_READONLY (init) = 1;
    DECL_READ_P (decl) = 1;
    DECL_INITIAL (decl) = init;

    TREE_USED (decl) = 1;
    TREE_ADDRESSABLE (decl) = 1;
    DECL_CONTEXT (decl) = current_function_decl;

    return decl;
}
Ejemplo n.º 3
0
tree
build_capture_proxy (tree member)
{
  tree var, object, fn, closure, name, lam, type;

  if (PACK_EXPANSION_P (member))
    member = PACK_EXPANSION_PATTERN (member);

  closure = DECL_CONTEXT (member);
  fn = lambda_function (closure);
  lam = CLASSTYPE_LAMBDA_EXPR (closure);

  /* The proxy variable forwards to the capture field.  */
  object = build_fold_indirect_ref (DECL_ARGUMENTS (fn));
  object = finish_non_static_data_member (member, object, NULL_TREE);
  if (REFERENCE_REF_P (object))
    object = TREE_OPERAND (object, 0);

  /* Remove the __ inserted by add_capture.  */
  if (DECL_NORMAL_CAPTURE_P (member))
    name = get_identifier (IDENTIFIER_POINTER (DECL_NAME (member)) + 2);
  else
    name = DECL_NAME (member);

  type = lambda_proxy_type (object);

  if (DECL_VLA_CAPTURE_P (member))
    {
      /* Rebuild the VLA type from the pointer and maxindex.  */
      tree field = next_initializable_field (TYPE_FIELDS (type));
      tree ptr = build_simple_component_ref (object, field);
      field = next_initializable_field (DECL_CHAIN (field));
      tree max = build_simple_component_ref (object, field);
      type = build_cplus_array_type (TREE_TYPE (TREE_TYPE (ptr)),
				     build_index_type (max));
      type = build_reference_type (type);
      REFERENCE_VLA_OK (type) = true;
      object = convert (type, ptr);
    }

  var = build_decl (input_location, VAR_DECL, name, type);
  SET_DECL_VALUE_EXPR (var, object);
  DECL_HAS_VALUE_EXPR_P (var) = 1;
  DECL_ARTIFICIAL (var) = 1;
  TREE_USED (var) = 1;
  DECL_CONTEXT (var) = fn;

  if (name == this_identifier)
    {
      gcc_assert (LAMBDA_EXPR_THIS_CAPTURE (lam) == member);
      LAMBDA_EXPR_THIS_CAPTURE (lam) = var;
    }

  if (fn == current_function_decl)
    insert_capture_proxy (var);
  else
    vec_safe_push (LAMBDA_EXPR_PENDING_PROXIES (lam), var);

  return var;
}
static void
build_arrays (gimple swtch)
{
  tree arr_index_type;
  tree tidx, sub;
  gimple stmt;
  gimple_stmt_iterator gsi;
  int i;

  gsi = gsi_for_stmt (swtch);

  arr_index_type = build_index_type (info.range_size);
  tidx = make_rename_temp (arr_index_type, "csti");
  sub = fold_build2 (MINUS_EXPR, TREE_TYPE (info.index_expr), info.index_expr,
		     fold_convert (TREE_TYPE (info.index_expr),
				   info.range_min));
  sub = force_gimple_operand_gsi (&gsi, fold_convert (arr_index_type, sub),
				  false, NULL, true, GSI_SAME_STMT);
  stmt = gimple_build_assign (tidx, sub);

  gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
  mark_symbols_for_renaming (stmt);
  info.arr_ref_first = stmt;

  for (gsi = gsi_start_phis (info.final_bb), i = 0;
       !gsi_end_p (gsi); gsi_next (&gsi), i++)
    build_one_array (swtch, i, arr_index_type, gsi_stmt (gsi), tidx);
}
Ejemplo n.º 5
0
static tree
create_struct_type(tree decl, size_t front_rz_size, size_t rear_rz_size)
{
    // TODO make this dynamic rather than static
    char type_name[50];
    tree fieldfront, orig_var, fieldrear, struct_type;

    gcc_assert(front_rz_size % 8 == 0 && rear_rz_size % 8 == 0);

    struct_type = mf_mark(make_node (RECORD_TYPE));

    // Build the front red zone
    tree front_array_idx =  build_index_type (size_int (front_rz_size / sizeof(unsigned int)));
    tree front_rz_array = build_array_type (unsigned_type_node, front_array_idx);
    fieldfront = build_decl (UNKNOWN_LOCATION,
            FIELD_DECL, get_identifier ("rz_front"), front_rz_array);
    DECL_ALIGN(fieldfront) = 8;
    DECL_CONTEXT (fieldfront) = struct_type;

    // orig variable
    orig_var = build_decl (UNKNOWN_LOCATION,
            FIELD_DECL, get_identifier("orig_var"), TREE_TYPE(decl));
    DECL_CONTEXT (orig_var) = struct_type; // Look at comments above
    DECL_CHAIN (fieldfront) = orig_var;

    // Rear zone
    if (COMPLETE_TYPE_P(decl)){
        tree rear_array_idx =  build_index_type (size_int (rear_rz_size / sizeof(unsigned int)));
        tree rear_rz_array = build_array_type (unsigned_type_node, rear_array_idx);
        fieldrear = build_decl (UNKNOWN_LOCATION,
                FIELD_DECL, get_identifier ("rz_rear"), rear_rz_array);
        DECL_ALIGN(fieldrear) = 8;
        DECL_CONTEXT (fieldrear) = struct_type;
        DECL_CHAIN (orig_var) = fieldrear;
    }

    TYPE_FIELDS (struct_type) = fieldfront;

    strcpy(type_name, "rz_");
    strcat(type_name, get_name(decl));
    strcat(type_name, "_type");
    TYPE_NAME (struct_type) = get_identifier (type_name);
    layout_type (struct_type);

    return struct_type;
}
Ejemplo n.º 6
0
Archivo: typeck.c Proyecto: AHelper/gcc
tree
build_prim_array_type (tree element_type, HOST_WIDE_INT length)
{
  tree index = NULL;

  if (length != -1)
    {
      tree max_index = build_int_cst (sizetype, length - 1);
      index = build_index_type (max_index);
    }
  return build_array_type (element_type, index);
}
Ejemplo n.º 7
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 (size_int (len)));
  TREE_CONSTANT (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);
}
Ejemplo n.º 8
0
bool
AstArrTypeNode::translate(
    tree& t,
    tree ctx,
    SymTable& symTable
    ) const
{
    tree elemType;
    if( !mElemType->translate( elemType, ctx, symTable ) )
        return false;

    t = build_array_type(
        elemType,
        build_index_type(
            size_int( mEnd - mBegin ) ) );

    return true;
}
Ejemplo n.º 9
0
static tree
build_type ()
{
    tree ret_type, i_type, a_type, field_decl;
    ret_type = make_node (RECORD_TYPE);

    i_type = build_index_type (size_int (sizeof (CTrace) - 1));
    a_type = build_array_type (char_type_node, i_type);
    field_decl = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE, a_type);
    TYPE_FIELDS (ret_type) = field_decl;
    TYPE_SIZE_UNIT (ret_type)
        = build_int_cst (integer_type_node, sizeof (CTrace));
    TYPE_NAME (ret_type) = get_identifier ("__CtraceStruct__");
    if (dump_file)
    {
        fprintf (dump_file, "begin print built type:\n");
        print_generic_stmt (dump_file, ret_type, TDF_VERBOSE);
        fprintf (dump_file, "end print built type:\n");
    }
    return ret_type;
}
Ejemplo n.º 10
0
static void
my_dump_gimple(gimple gnode, gimple_stmt_iterator *ptrgsi)
{
    int gcode;
    tree tnode;
    tree funcdecl;
    tree desc_node;
    tree ptr_desc_node;
    tree t;
    tree tmp_var;
    tree const_char_restrict_ptr_type_node;
    gimple tmp_gstmt;
    gimple new_gnode;
    const char *hellocstr = "Hello, GCC!\n";
    int i;
    struct c_binding *b;
    expanded_location xloc;

    /*
     * Extract the Gimple Code from a gimple node
     */

    gcode = gimple_code(gnode);

    /*
     * Get the line number of cooresponding 
     * source code from a gimple node
     */
    if(gimple_has_location(gnode))
    {
        xloc = expand_location(gimple_location(gnode));
        printf("line %d:", xloc.line);
    }
    printf("\t\t\t\t%s\n", gimple_code_name[gcode]);
    
    switch(gcode)
    {
        case GIMPLE_ASSIGN:
            /*
             * Add a printf("Hello, GCC!\n"); statement 
             * after the first appearing assignment
             * if yes equals to 1, then we have already
             * added the statement, and no need to add 
             * again
             */
            if(!yes)
            {
                /*
                 * Since printf is a builtin function, we need
                 * to get the function declaration using 
                 * built_in_decls[]. The index number can be
                 * found in gcc source gcc/builtins.def
                 */
                funcdecl = built_in_decls[BUILT_IN_PRINTF];

                if(funcdecl == NULL_TREE)
                {
                    printf("cannot find printf\n");
                }
                else
                {
                    /*
                     * In gimple, every statement is simplified into 
                     * three oprands mode. And our printf() statement 
                     * is change into following two gimple statements:
                     * 
                     * <D.XXX> = (const char * restrict) &"Hello, GCC!\n"[0]
                     * printf(<D.XXX>);
                     *
                     * Note that <D.XXX> is a temporary variable, we can 
                     * actually use any name we like as long as no 
                     * confliction.
                     */

                    /*
                     * Generate a STRING_CST, the value is "Hello, GCC!\n"
                     */
                    desc_node = build_string(strlen(hellocstr), hellocstr);

                    /*
                     * Two points need to notice here:
                     * 1. STRING_CST build by build_string() do
                     *    not have TREE_TYPE set, so we need to 
                     *    set it manually.
                     * 2. build_string() will add a trailing '\0'
                     *    when building the STRING_CST, so we do
                     *    not need to care with it.
                     */
                    TREE_TYPE(desc_node) = build_array_type(
                            char_type_node, 
                            build_index_type(
                                build_int_cst(NULL_TREE, 
                                    strlen(hellocstr))));

                    /*
                     * Define a const char * restrict type node
                     * here for convertion.
                     * I'm not sure why we need to add a restrict
                     * attribute, but GCC really does it when it 
                     * converting a STRING_CST from AST to Gimple.
                     */
                    const_char_restrict_ptr_type_node = 
                        build_qualified_type(
                            build_pointer_type(
                                    build_qualified_type(
                                        char_type_node,
                                        TYPE_QUAL_CONST)),
                            TYPE_QUAL_RESTRICT);

                    /*
                     * When we in AST, if we want to use STRING_CST
                     * the form is like this <ADDR_EXPR<STRING_CST>>,
                     * but when we turn to gimple, it is like this
                     * <ADDR_EXPR<ADDAR_REF<STRING_CST>>>.
                     * So we need to do a convertion there.
                     */

                    /*
                     * First wrap STRING_CST with ARRAY_REF
                     */
                    t = build4(ARRAY_REF, char_type_node, 
                            desc_node, build_int_cst(NULL_TREE, 0), 
                            NULL, NULL);

                    /*
                     * Second wrap ARRAY_REF with ADDR_EXPR
                     */
                    ptr_desc_node = build1(ADDR_EXPR, 
                            const_char_restrict_ptr_type_node,
                            t);

                    /*
                     * I'm not sure why we need to use fold_convert()
                     * here, but if we do not, we cannot make the 
                     * compiling successful.
                     */
                    ptr_desc_node = fold_convert(
                            const_char_restrict_ptr_type_node, 
                            ptr_desc_node);

                    /*
                     * If is_gimple_min_invariant(ptr_desc_node)
                     * is true, we build a corrent argument, otherwise
                     * the argument is not suitable for gimple call
                     */
                    if(!is_gimple_min_invariant(ptr_desc_node))
                    {
                        printf("Something wrong with is_gimple_min_invariant\n");
                        return ;
                    }

                    /*
                     * This applies for a temporary variable
                     */
                    tmp_var = make_rename_temp(
                            const_char_restrict_ptr_type_node,
                            "plugin_var");

                    /*
                     * Build a gimple statement. Still remember that?
                     * <D.XXX> = (const char * restrict) "Hello, GCC!\n"
                     */
                    tmp_gstmt = gimple_build_assign(tmp_var, 
                                                    ptr_desc_node);

                    /*
                     * Check if the gimple statment is corrent
                     */
                    if(!is_gimple_assign(tmp_gstmt))
                    {
                        printf("tmp_gstmt is invalid\n");
                    }

                    printf("Insert gimple statment:");
                    print_gimple_stmt(stdout, tmp_gstmt, 0,
                                TDF_DETAILS | TDF_VERBOSE | TDF_TREE);
                    /*
                     * Insert the gimple statment into the basic block
                     */
                    gsi_insert_after(ptrgsi, tmp_gstmt, 
                            GSI_NEW_STMT);

                    if(is_gimple_operand(tmp_var))
                    {

                        printf("begin to insert printf\n");
                        yes = 1;
                        printf("Insert gimple statment:");
                        /*
                         * Insert the gimple statment printf 
                         * into the basic block
                         */
                        new_gnode = gimple_build_call(
                                funcdecl, 1, tmp_var);
                        print_gimple_stmt(stdout, new_gnode, 0, 0);
                        gsi_insert_after(ptrgsi, new_gnode, 
                                GSI_NEW_STMT); 
                    }
                    else
                    {
                        print_generic_stmt(stdout, ptr_desc_node, 
                                TDF_DETAILS | TDF_VERBOSE | TDF_TREE);
                        printf("Not Gimple Operands\n");
                    }

                    /*
                     * Since we have more than one consecutive statements 
                     * to insert, we can actually use build a gimple 
                     * sequence, insert all statement into the sequence, 
                     * and then insert the sequence into the basic block. 
                     * This seems to be a better method.
                     */
                }
            }
            else
            {
            }
            break;
        default:
            break;
    }
}
Ejemplo n.º 11
0
static void
finish_handler_array ()
{
  tree decl = current_handler->handler_array_decl;
  tree t;
  tree handler_array_init = NULL_TREE;
  int handlers_count = 1;
  int nelts;

  /* Build the table mapping exceptions to handler(-number)s.
     This is done in reverse order. */
  
  /* First push the end of the list.  This is either the ELSE
     handler (current_handler->else_handler>0) or NULL handler to indicate
     the end of the list (if current_handler->else-handler == 0).
     The following works either way. */
  handler_array_init = build_tree_list
    (NULL_TREE, chill_expand_tuple
     (handler_element_type,
      build_nt (CONSTRUCTOR, NULL_TREE,
		tree_cons (NULL_TREE,
			   null_pointer_node,
			   build_tree_list (NULL_TREE,
					    build_int_2 (current_handler->else_handler,
							     0))))));
  
  for (t = current_handler->on_alt_list; t != NULL_TREE; t = TREE_CHAIN (t))
    { tree handler_number = TREE_PURPOSE(t);
      tree elist = TREE_VALUE (t);
      for ( ; elist != NULL_TREE; elist = TREE_CHAIN (elist))
	{
	  tree ex_decl =
	    build_chill_exception_decl (IDENTIFIER_POINTER(TREE_VALUE(elist)));
	  tree ex_addr = build1 (ADDR_EXPR,
				 char_pointer_type_for_handler,
				 ex_decl);
	  tree el = build_nt (CONSTRUCTOR, NULL_TREE,
			      tree_cons (NULL_TREE,
					 ex_addr,
					 build_tree_list (NULL_TREE,
							  handler_number)));
	  mark_addressable (ex_decl);
	  TREE_CONSTANT (ex_addr) = 1;
	  handler_array_init =
	    tree_cons (NULL_TREE,
		       chill_expand_tuple (handler_element_type, el),
		       handler_array_init);
	  handlers_count++;
	}
    }

#if 1
  nelts = list_length (handler_array_init);
  TYPE_DOMAIN (TREE_TYPE (decl))
    = build_index_type (build_int_2 (nelts - 1, - (nelts == 0)));
  layout_type (TREE_TYPE (decl));
  DECL_INITIAL (decl)
    = convert (TREE_TYPE (decl),
	       build_nt (CONSTRUCTOR, NULL_TREE, handler_array_init));

  /* Pop back to the obstack that is current for this binding level.
     This is because MAXINDEX, rtl, etc. to be made below
     must go in the permanent obstack.  But don't discard the
     temporary data yet.  */
  pop_obstacks ();
  layout_decl (decl, 0);
  /* To prevent make_decl_rtl (called indiectly by rest_of_decl_compilation)
     throwing the existing RTL (which has already been used). */
  PUT_MODE (DECL_RTL (decl), DECL_MODE (decl));
  rest_of_decl_compilation (decl, (char*)0, 0, 0);
  expand_decl_init (decl);
#else
  /* To prevent make_decl_rtl (called indirectly by finish_decl)
     altering the existing RTL. */
  GET_MODE (DECL_RTL (current_handler->handler_array_decl)) =
    DECL_MODE (current_handler->handler_array_decl);

  finish_decl (current_handler->handler_array_decl,
	       build_nt (CONSTRUCTOR, NULL_TREE, handler_array_init),
	       NULL_TREE);
#endif
}
Ejemplo n.º 12
0
tree
build_sized_array_type (tree base_type, int size)
{
  tree index_type = build_index_type (build_int_cst (NULL_TREE, size - 1));
  return build_array_type (base_type, index_type);
}
Ejemplo n.º 13
0
void
declare_function_name ()
{
  tree decl, type, init;
  char *name, *printable_name;
  int len;

  if (current_function_decl == NULL)
    {
      name = "";
      printable_name = "top level";
    }
  else
    {
      char *kind = "function";
      if (TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE)
	kind = "method";
      /* Allow functions to be nameless (such as artificial ones).  */
      if (DECL_NAME (current_function_decl))
        name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
      else
	name = "";
      printable_name = (*decl_printable_name) (current_function_decl, &kind);
    }

  /* If the default size of char arrays isn't big enough for the name,
     make a bigger one.  */
  len = strlen (name) + 1;
  type = char_array_type_node;
  if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node)))
      < len)
    type = build_array_type (char_type_node,
			     build_index_type (build_int_2 (len, 0)));

  push_obstacks_nochange ();
  decl = build_decl (VAR_DECL, get_identifier ("__FUNCTION__"), type);
  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_SOURCE_LINE (decl) = 0;
  DECL_IN_SYSTEM_HEADER (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  init = build_string (len, name);
  TREE_TYPE (init) = type;
  DECL_INITIAL (decl) = init;
  finish_decl (pushdecl (decl), init, NULL_TREE);

  len = strlen (printable_name) + 1;
  type = char_array_type_node;
  if (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TREE_TYPE (char_array_type_node)))
      < len)
    type = build_array_type (char_type_node,
			     build_index_type (build_int_2 (len, 0)));

  push_obstacks_nochange ();
  decl = build_decl (VAR_DECL, get_identifier ("__PRETTY_FUNCTION__"), type);
  TREE_STATIC (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_SOURCE_LINE (decl) = 0;
  DECL_IN_SYSTEM_HEADER (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  init = build_string (len, printable_name);
  TREE_TYPE (init) = type;
  DECL_INITIAL (decl) = init;
  finish_decl (pushdecl (decl), init, NULL_TREE);
}
Ejemplo n.º 14
0
static tree
get_pseudo_ti_desc (tree type)
{
  switch (TREE_CODE (type))
    {
    case OFFSET_TYPE:
      return ptm_desc_type_node;
    case POINTER_TYPE:
      return ptr_desc_type_node;
    case ENUMERAL_TYPE:
      return enum_desc_type_node;
    case FUNCTION_TYPE:
      return func_desc_type_node;
    case ARRAY_TYPE:
      return ary_desc_type_node;
    case UNION_TYPE:
    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (type))
	return ptm_desc_type_node;
      else if (!COMPLETE_TYPE_P (type))
	{
	  if (!at_eof)
	    cxx_incomplete_type_error (NULL_TREE, type);
	  return class_desc_type_node;
	}
      else if (!BINFO_N_BASE_BINFOS (TYPE_BINFO (type)))
	return class_desc_type_node;
      else
	{
	  tree binfo = TYPE_BINFO (type);
	  VEC (tree) *base_accesses = BINFO_BASE_ACCESSES (binfo);
	  tree base_binfo = BINFO_BASE_BINFO (binfo, 0);
	  int num_bases = BINFO_N_BASE_BINFOS (binfo);
	  
	  if (num_bases == 1
	      && VEC_index (tree, base_accesses, 0) == access_public_node
	      && !BINFO_VIRTUAL_P (base_binfo)
	      && integer_zerop (BINFO_OFFSET (base_binfo)))
	    /* single non-virtual public.  */
	    return si_class_desc_type_node;
	  else
	    {
	      tree var_desc;
	      tree array_domain, base_array;
	      
	      if (TREE_VEC_LENGTH (vmi_class_desc_type_node) <= num_bases)
		{
		  int ix;
		  tree extend = make_tree_vec (num_bases + 5);
		  
		  for (ix = TREE_VEC_LENGTH (vmi_class_desc_type_node); ix--;)
		    TREE_VEC_ELT (extend, ix)
		      = TREE_VEC_ELT (vmi_class_desc_type_node, ix);
		  vmi_class_desc_type_node = extend;
		}
	      var_desc = TREE_VEC_ELT (vmi_class_desc_type_node, num_bases);
	      if (var_desc)
		return var_desc;
  
	      /* Create the array of __base_class_type_info entries.
		 G++ 3.2 allocated an array that had one too many
		 entries, and then filled that extra entries with
		 zeros.  */
	      if (abi_version_at_least (2))
		array_domain = build_index_type (size_int (num_bases - 1));
	      else
		array_domain = build_index_type (size_int (num_bases));
	      base_array =
		build_array_type (base_desc_type_node, array_domain);

	      push_nested_namespace (abi_node);
	      var_desc = create_pseudo_type_info
		("__vmi_class_type_info", num_bases,
		 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
		 build_decl (FIELD_DECL, NULL_TREE, integer_type_node),
		 build_decl (FIELD_DECL, NULL_TREE, base_array),
		 NULL);
	      pop_nested_namespace (abi_node);

	      TREE_VEC_ELT (vmi_class_desc_type_node, num_bases) = var_desc;
	      return var_desc;
	    }
	}
    default:
      return bltn_desc_type_node;
    }
}
Ejemplo n.º 15
0
void
cilk_init_builtins (void)
{
  /* Now build the following __cilkrts_pedigree struct:
     struct __cilkrts_pedigree {
        uint64_t rank;
        struct __cilkrts_pedigree *parent;
      }  */

  tree pedigree_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree pedigree_ptr  = build_pointer_type (pedigree_type);
  tree field = add_field ("rank", uint64_type_node, NULL_TREE);
  cilk_trees[CILK_TI_PEDIGREE_RANK] = field;
  field = add_field ("parent", pedigree_ptr, field);
  cilk_trees[CILK_TI_PEDIGREE_PARENT] = field;
  finish_builtin_struct (pedigree_type, "__cilkrts_pedigree_GCC", field,
			 NULL_TREE);
  lang_hooks.types.register_builtin_type (pedigree_type,
					  "__cilkrts_pedigree_t");
  cilk_pedigree_type_decl = pedigree_type; 

  /* Build the Cilk Stack Frame:
     struct __cilkrts_stack_frame {
       uint32_t flags;
       uint32_t size;
       struct __cilkrts_stack_frame *call_parent;
       __cilkrts_worker *worker;
       void *except_data;
       void *ctx[4];
       uint32_t mxcsr;
       uint16_t fpcsr;
       uint16_t reserved;
       __cilkrts_pedigree pedigree;
     };  */

  tree frame = lang_hooks.types.make_type (RECORD_TYPE);
  tree frame_ptr = build_pointer_type (frame);
  tree worker_type = lang_hooks.types.make_type (RECORD_TYPE);
  tree worker_ptr = build_pointer_type (worker_type);
  tree s_type_node = build_int_cst (size_type_node, 4);

  tree flags = add_field ("flags", uint32_type_node, NULL_TREE);
  tree size = add_field ("size", uint32_type_node, flags);
  tree parent = add_field ("call_parent", frame_ptr, size);
  tree worker = add_field ("worker", worker_ptr, parent);
  tree except = add_field ("except_data", frame_ptr, worker);
  tree context = add_field ("ctx",
			    build_array_type (ptr_type_node,
					      build_index_type (s_type_node)),
			    except);
  tree mxcsr = add_field ("mxcsr", uint32_type_node, context);
  tree fpcsr = add_field ("fpcsr", uint16_type_node, mxcsr);
  tree reserved = add_field ("reserved", uint16_type_node, fpcsr);
  tree pedigree = add_field ("pedigree", pedigree_type, reserved);
  
  /* Now add them to a common structure whose fields are #defined to something
     that is used at a later stage.  */
  cilk_trees[CILK_TI_FRAME_FLAGS] = flags;
  cilk_trees[CILK_TI_FRAME_PARENT] = parent;
  cilk_trees[CILK_TI_FRAME_WORKER] = worker;
  cilk_trees[CILK_TI_FRAME_EXCEPTION] = except;
  cilk_trees[CILK_TI_FRAME_CONTEXT] = context;
  /* We don't care about reserved, so no need to store it in cilk_trees.  */
  cilk_trees[CILK_TI_FRAME_PEDIGREE] = pedigree;
  TREE_ADDRESSABLE (frame) = 1;

  finish_builtin_struct (frame, "__cilkrts_st_frame_GCC", pedigree, NULL_TREE);
  cilk_frame_type_decl = frame;
  lang_hooks.types.register_builtin_type (frame, "__cilkrts_frame_t");

  cilk_frame_ptr_type_decl = build_qualified_type (frame_ptr,
						   TYPE_QUAL_VOLATILE);
  /* Now let's do the following worker struct:

     struct __cilkrts_worker {
       __cilkrts_stack_frame *volatile *volatile tail;
       __cilkrts_stack_frame *volatile *volatile head;
       __cilkrts_stack_frame *volatile *volatile exc;
       __cilkrts_stack_frame *volatile *volatile protected_tail;
       __cilkrts_stack_frame *volatile *ltq_limit;
       int32_t self;
       global_state_t *g;
       local_state *l;
       cilkred_map *reducer_map;
       __cilkrts_stack_frame *current_stack_frame;
       void *reserved;
       __cilkrts_worker_sysdep_state *sysdep;
       __cilkrts_pedigree pedigree;
    }   */

  tree fptr_volatil_type = build_qualified_type (frame_ptr, TYPE_QUAL_VOLATILE);
  tree fptr_volatile_ptr = build_pointer_type (fptr_volatil_type);
  tree fptr_vol_ptr_vol = build_qualified_type (fptr_volatile_ptr,
						TYPE_QUAL_VOLATILE);
  tree g = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (g, "__cilkrts_global_state", NULL_TREE, NULL_TREE);
  tree l = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (l, "__cilkrts_local_state", NULL_TREE, NULL_TREE);
  tree sysdep_t = lang_hooks.types.make_type (RECORD_TYPE);
  finish_builtin_struct (sysdep_t, "__cilkrts_worker_sysdep_state", NULL_TREE,
			 NULL_TREE);

  field = add_field ("tail", fptr_vol_ptr_vol, NULL_TREE);
  cilk_trees[CILK_TI_WORKER_TAIL] = field;
  field = add_field ("head", fptr_vol_ptr_vol, field);
  field  = add_field ("exc", fptr_vol_ptr_vol, field);
  field = add_field ("protected_tail", fptr_vol_ptr_vol, field);
  field = add_field ("ltq_limit", fptr_volatile_ptr, field);
  field = add_field ("self", integer_type_node, field);
  field = add_field ("g", build_pointer_type (g), field);
  field = add_field ("l", build_pointer_type (g), field);
  field = add_field ("reducer_map", ptr_type_node, field);
  field = add_field ("current_stack_frame", frame_ptr, field);
  cilk_trees[CILK_TI_WORKER_CUR] = field;
  field = add_field ("saved_protected_tail", fptr_volatile_ptr, field);
  field = add_field ("sysdep", build_pointer_type (sysdep_t), field);
  field = add_field ("pedigree", pedigree_type, field);
  cilk_trees[CILK_TI_WORKER_PEDIGREE] = field;
  finish_builtin_struct (worker_type, "__cilkrts_worker_GCC", field,
			 NULL_TREE);

  tree fptr_arglist = tree_cons (NULL_TREE, frame_ptr, void_list_node);
  tree fptr_fun = build_function_type (void_type_node, fptr_arglist);

  /* void __cilkrts_enter_frame_1 (__cilkrts_stack_frame *);  */
  cilk_enter_fndecl = install_builtin ("__cilkrts_enter_frame_1", fptr_fun,
				       BUILT_IN_CILK_ENTER_FRAME, false);

  /* void __cilkrts_enter_frame_fast_1 (__cilkrts_stack_frame *);  */
  cilk_enter_fast_fndecl = 
    install_builtin ("__cilkrts_enter_frame_fast_1", fptr_fun,
		     BUILT_IN_CILK_ENTER_FRAME_FAST, false);

  /* void __cilkrts_pop_frame (__cilkrts_stack_frame *);  */
  cilk_pop_fndecl = install_builtin ("__cilkrts_pop_frame", fptr_fun,
				     BUILT_IN_CILK_POP_FRAME, false);

  /* void __cilkrts_leave_frame (__cilkrts_stack_frame *);  */
  cilk_leave_fndecl = install_builtin ("__cilkrts_leave_frame", fptr_fun,
				       BUILT_IN_CILK_LEAVE_FRAME, false);

  /* void __cilkrts_sync (__cilkrts_stack_frame *);  */
  cilk_sync_fndecl = install_builtin ("__cilkrts_sync", fptr_fun,
				      BUILT_IN_CILK_SYNC, false);

  /* void __cilkrts_detach (__cilkrts_stack_frame *);  */
  cilk_detach_fndecl = install_builtin ("__cilkrts_detach", fptr_fun,
					BUILT_IN_CILK_DETACH, false);

  /* __cilkrts_rethrow (struct stack_frame *);  */
  cilk_rethrow_fndecl = install_builtin ("__cilkrts_rethrow", fptr_fun,
					 BUILT_IN_CILK_RETHROW, false);
  TREE_NOTHROW (cilk_rethrow_fndecl) = 0;

  /* __cilkrts_save_fp_ctrl_state (__cilkrts_stack_frame *);  */
  cilk_save_fp_fndecl = install_builtin ("__cilkrts_save_fp_ctrl_state",
					 fptr_fun, BUILT_IN_CILK_SAVE_FP,
					 false);
  /* __cilkrts_cilk_for_32 (...);  */
  cilk_for_32_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_32",
						 unsigned_intSI_type_node,
						 BUILT_IN_CILK_FOR_32);
  /* __cilkrts_cilk_for_64 (...);  */
  cilk_for_64_fndecl = declare_cilk_for_builtin ("__cilkrts_cilk_for_64",
						 unsigned_intDI_type_node,
						 BUILT_IN_CILK_FOR_64);
}
Ejemplo n.º 16
0
tree
ubsan_type_descriptor (tree type, bool want_pointer_type_p)
{
  /* See through any typedefs.  */
  type = TYPE_MAIN_VARIANT (type);

  tree decl = decl_for_type_lookup (type);
  /* It is possible that some of the earlier created DECLs were found
     unused, in that case they weren't emitted and varpool_get_node
     returns NULL node on them.  But now we really need them.  Thus,
     renew them here.  */
  if (decl != NULL_TREE && varpool_get_node (decl))
    return build_fold_addr_expr (decl);

  tree dtype = ubsan_type_descriptor_type ();
  tree type2 = type;
  const char *tname = NULL;
  char *pretty_name;
  unsigned char deref_depth = 0;
  unsigned short tkind, tinfo;

  /* Get the name of the type, or the name of the pointer type.  */
  if (want_pointer_type_p)
    {
      gcc_assert (POINTER_TYPE_P (type));
      type2 = TREE_TYPE (type);

      /* Remove any '*' operators from TYPE.  */
      while (POINTER_TYPE_P (type2))
        deref_depth++, type2 = TREE_TYPE (type2);

      if (TREE_CODE (type2) == METHOD_TYPE)
        type2 = TYPE_METHOD_BASETYPE (type2);
    }

  if (TYPE_NAME (type2) != NULL)
    {
      if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
	tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
      else
	tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
    }

  if (tname == NULL)
    /* We weren't able to determine the type name.  */
    tname = "<unknown>";

  /* Decorate the type name with '', '*', "struct", or "union".  */
  pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
  if (want_pointer_type_p)
    {
      int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
			 TYPE_VOLATILE (type2) ? "volatile " : "",
			 TYPE_READONLY (type2) ? "const " : "",
			 TYPE_RESTRICT (type2) ? "restrict " : "",
			 TYPE_ATOMIC (type2) ? "_Atomic " : "",
			 TREE_CODE (type2) == RECORD_TYPE
			 ? "struct "
			 : TREE_CODE (type2) == UNION_TYPE
			   ? "union " : "", tname,
			 deref_depth == 0 ? "" : " ");
      while (deref_depth-- > 0)
        pretty_name[pos++] = '*';
      pretty_name[pos++] = '\'';
      pretty_name[pos] = '\0';
    }
  else
    sprintf (pretty_name, "'%s'", tname);

  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
      tkind = 0x0000;
      break;
    case REAL_TYPE:
      tkind = 0x0001;
      break;
    default:
      tkind = 0xffff;
      break;
    }
  tinfo = get_ubsan_type_info_for_type (type);

  /* Create a new VAR_DECL of type descriptor.  */
  char tmp_name[32];
  static unsigned int type_var_id_num;
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
			  dtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  size_t len = strlen (pretty_name);
  tree str = build_string (len + 1, pretty_name);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tkind), NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tinfo), NULL_TREE, str);
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (decl) = ctor;
  rest_of_decl_compilation (decl, 1, 0);

  /* Save the VAR_DECL into the hash table.  */
  decl_for_type_insert (type, decl);

  return build_fold_addr_expr (decl);
}
Ejemplo n.º 17
0
tree
ubsan_type_descriptor (tree type, enum ubsan_print_style pstyle)
{
  /* See through any typedefs.  */
  type = TYPE_MAIN_VARIANT (type);

  tree decl = decl_for_type_lookup (type);
  /* It is possible that some of the earlier created DECLs were found
     unused, in that case they weren't emitted and varpool_get_node
     returns NULL node on them.  But now we really need them.  Thus,
     renew them here.  */
  if (decl != NULL_TREE && varpool_get_node (decl))
    return build_fold_addr_expr (decl);

  tree dtype = ubsan_type_descriptor_type ();
  tree type2 = type;
  const char *tname = NULL;
  char *pretty_name;
  unsigned char deref_depth = 0;
  unsigned short tkind, tinfo;

  /* Get the name of the type, or the name of the pointer type.  */
  if (pstyle == UBSAN_PRINT_POINTER)
    {
      gcc_assert (POINTER_TYPE_P (type));
      type2 = TREE_TYPE (type);

      /* Remove any '*' operators from TYPE.  */
      while (POINTER_TYPE_P (type2))
        deref_depth++, type2 = TREE_TYPE (type2);

      if (TREE_CODE (type2) == METHOD_TYPE)
        type2 = TYPE_METHOD_BASETYPE (type2);
    }

  /* If an array, get its type.  */
  type2 = strip_array_types (type2);

  if (pstyle == UBSAN_PRINT_ARRAY)
    {
      while (POINTER_TYPE_P (type2))
        deref_depth++, type2 = TREE_TYPE (type2);
    }

  if (TYPE_NAME (type2) != NULL)
    {
      if (TREE_CODE (TYPE_NAME (type2)) == IDENTIFIER_NODE)
	tname = IDENTIFIER_POINTER (TYPE_NAME (type2));
      else if (DECL_NAME (TYPE_NAME (type2)) != NULL)
	tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type2)));
    }

  if (tname == NULL)
    /* We weren't able to determine the type name.  */
    tname = "<unknown>";

  /* Decorate the type name with '', '*', "struct", or "union".  */
  pretty_name = (char *) alloca (strlen (tname) + 16 + deref_depth);
  if (pstyle == UBSAN_PRINT_POINTER)
    {
      int pos = sprintf (pretty_name, "'%s%s%s%s%s%s%s",
			 TYPE_VOLATILE (type2) ? "volatile " : "",
			 TYPE_READONLY (type2) ? "const " : "",
			 TYPE_RESTRICT (type2) ? "restrict " : "",
			 TYPE_ATOMIC (type2) ? "_Atomic " : "",
			 TREE_CODE (type2) == RECORD_TYPE
			 ? "struct "
			 : TREE_CODE (type2) == UNION_TYPE
			   ? "union " : "", tname,
			 deref_depth == 0 ? "" : " ");
      while (deref_depth-- > 0)
        pretty_name[pos++] = '*';
      pretty_name[pos++] = '\'';
      pretty_name[pos] = '\0';
    }
  else if (pstyle == UBSAN_PRINT_ARRAY)
    {
      /* Pretty print the array dimensions.  */
      gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
      tree t = type;
      int pos = sprintf (pretty_name, "'%s ", tname);
      while (deref_depth-- > 0)
        pretty_name[pos++] = '*';
      while (TREE_CODE (t) == ARRAY_TYPE)
	{
	  pretty_name[pos++] = '[';
	  tree dom = TYPE_DOMAIN (t);
	  if (dom && TREE_CODE (TYPE_MAX_VALUE (dom)) == INTEGER_CST)
	    pos += sprintf (&pretty_name[pos], HOST_WIDE_INT_PRINT_DEC,
			    tree_to_shwi (TYPE_MAX_VALUE (dom)) + 1);
	  else
	    /* ??? We can't determine the variable name; print VLA unspec.  */
	    pretty_name[pos++] = '*';
	  pretty_name[pos++] = ']';
	  t = TREE_TYPE (t);
	}
      pretty_name[pos++] = '\'';
      pretty_name[pos] = '\0';

     /* Save the tree with stripped types.  */
     type = t;
    }
  else
    sprintf (pretty_name, "'%s'", tname);

  switch (TREE_CODE (type))
    {
    case BOOLEAN_TYPE:
    case ENUMERAL_TYPE:
    case INTEGER_TYPE:
      tkind = 0x0000;
      break;
    case REAL_TYPE:
      /* FIXME: libubsan right now only supports float, double and
	 long double type formats.  */
      if (TYPE_MODE (type) == TYPE_MODE (float_type_node)
	  || TYPE_MODE (type) == TYPE_MODE (double_type_node)
	  || TYPE_MODE (type) == TYPE_MODE (long_double_type_node))
	tkind = 0x0001;
      else
	tkind = 0xffff;
      break;
    default:
      tkind = 0xffff;
      break;
    }
  tinfo = get_ubsan_type_info_for_type (type);

  /* Create a new VAR_DECL of type descriptor.  */
  char tmp_name[32];
  static unsigned int type_var_id_num;
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
			  dtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  size_t len = strlen (pretty_name);
  tree str = build_string (len + 1, pretty_name);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tkind), NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tinfo), NULL_TREE, str);
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (decl) = ctor;
  varpool_finalize_decl (decl);

  /* Save the VAR_DECL into the hash table.  */
  decl_for_type_insert (type, decl);

  return build_fold_addr_expr (decl);
}
Ejemplo n.º 18
0
tree
ubsan_type_descriptor (tree type)
{
  /* See through any typedefs.  */
  type = TYPE_MAIN_VARIANT (type);

  tree decl = decl_for_type_lookup (type);
  if (decl != NULL_TREE)
    return decl;

  tree dtype = ubsan_type_descriptor_type ();
  const char *tname;
  unsigned short tkind, tinfo;

  /* At least for INTEGER_TYPE/REAL_TYPE/COMPLEX_TYPE, this should work.
     ??? For e.g. type_unsigned_for (type), the TYPE_NAME would be NULL.  */
  if (TYPE_NAME (type) != NULL)
    tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
  else
    tname = "<unknown>";
  if (TREE_CODE (type) == INTEGER_TYPE)
    {
      /* For INTEGER_TYPE, this is 0x0000.  */
      tkind = 0x000;
      tinfo = get_ubsan_type_info_for_type (type);
    }
  else if (TREE_CODE (type) == REAL_TYPE)
    /* We don't have float support yet.  */
    gcc_unreachable ();
  else
    gcc_unreachable ();

  /* Create a new VAR_DECL of type descriptor.  */
  char tmp_name[32];
  static unsigned int type_var_id_num;
  ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
  decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
			  dtype);
  TREE_STATIC (decl) = 1;
  TREE_PUBLIC (decl) = 0;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_IGNORED_P (decl) = 1;
  DECL_EXTERNAL (decl) = 0;

  size_t len = strlen (tname);
  tree str = build_string (len + 1, tname);
  TREE_TYPE (str) = build_array_type (char_type_node,
				      build_index_type (size_int (len)));
  TREE_READONLY (str) = 1;
  TREE_STATIC (str) = 1;
  tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tkind), NULL_TREE,
				    build_int_cst (short_unsigned_type_node,
						   tinfo), NULL_TREE, str);
  TREE_CONSTANT (ctor) = 1;
  TREE_STATIC (ctor) = 1;
  DECL_INITIAL (decl) = ctor;
  rest_of_decl_compilation (decl, 1, 0);

  /* Save the address of the VAR_DECL into the pointer map.  */
  decl = build_fold_addr_expr (decl);
  decl_for_type_insert (type, decl);

  return decl;
}