Esempio n. 1
0
void
i386_nlm_encode_section_info (tree decl, rtx rtl, int first)
{
  default_encode_section_info (decl, rtl, first);

  if (first
      && TREE_CODE (decl) == FUNCTION_DECL
      && *IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)) != '*'
      && !strchr (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), '@'))
    {
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      tree newid;

      if (lookup_attribute ("stdcall", type_attributes))
	newid = gen_stdcall_or_fastcall_decoration (decl, '_');
      else if (lookup_attribute ("fastcall", type_attributes))
	newid = gen_stdcall_or_fastcall_decoration (decl, FASTCALL_PREFIX);
      else if ((newid = lookup_attribute ("regparm", type_attributes)) != NULL_TREE)
	newid = gen_regparm_prefix (decl,
		      TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (newid))));
      if (newid != NULL_TREE) 	
	{
	  rtx rtlname = XEXP (rtl, 0);

	  if (GET_CODE (rtlname) == MEM)
	    rtlname = XEXP (rtlname, 0);
	  XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
	  /* These attributes must be present on first declaration,
	     change_decl_assembler_name will warn if they are added
	     later and the decl has been referenced, but duplicate_decls
	     should catch the mismatch before this is called.  */ 
	  change_decl_assembler_name (decl, newid);
	}
    }
}
Esempio n. 2
0
/* Make DECL local.  FIXME: We shouldn't need to mess with rtl this early,
   but other code such as notice_global_symbol generates rtl.  */
void
symtab_make_decl_local (tree decl)
{
  rtx rtl, symbol;

  if (TREE_CODE (decl) == VAR_DECL)
    DECL_COMMON (decl) = 0;
  else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);

  if (DECL_ONE_ONLY (decl) || DECL_COMDAT (decl))
    {
      /* It is possible that we are linking against library defining same COMDAT
	 function.  To avoid conflict we need to rename our local name of the
	 function just in the case WHOPR partitioning decide to make it hidden
	 to avoid cross partition references.  */
      if (flag_wpa)
	{
	  const char *old_name;
          symtab_node node = symtab_get_node (decl);
	  old_name  = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
	  change_decl_assembler_name (decl,
				      clone_function_name (decl, "local"));
	  if (node->symbol.lto_file_data)
	    lto_record_renamed_decl (node->symbol.lto_file_data,
				     old_name,
				     IDENTIFIER_POINTER
				       (DECL_ASSEMBLER_NAME (decl)));
	}
      DECL_SECTION_NAME (decl) = 0;
      DECL_COMDAT (decl) = 0;
    }
  DECL_COMDAT_GROUP (decl) = 0;
  DECL_WEAK (decl) = 0;
  DECL_EXTERNAL (decl) = 0;
  TREE_PUBLIC (decl) = 0;
  if (!DECL_RTL_SET_P (decl))
    return;

  /* Update rtl flags.  */
  make_decl_rtl (decl);

  rtl = DECL_RTL (decl);
  if (!MEM_P (rtl))
    return;

  symbol = XEXP (rtl, 0);
  if (GET_CODE (symbol) != SYMBOL_REF)
    return;

  SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}
Esempio n. 3
0
void
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
    default_encode_section_info (decl, rtl, first);

    if (first && TREE_CODE (decl) == FUNCTION_DECL)
    {
        tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
        tree newid = NULL_TREE;

        if (lookup_attribute ("stdcall", type_attributes))
            newid = gen_stdcall_or_fastcall_suffix (decl, false);
        else if (lookup_attribute ("fastcall", type_attributes))
            newid = gen_stdcall_or_fastcall_suffix (decl, true);
        if (newid != NULL_TREE)
        {
            rtx rtlname = XEXP (rtl, 0);
            if (GET_CODE (rtlname) == MEM)
                rtlname = XEXP (rtlname, 0);
            XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
            /* These attributes must be present on first declaration,
               change_decl_assembler_name will warn if they are added
               later and the decl has been referenced, but duplicate_decls
               should catch the mismatch before this is called.  */
            change_decl_assembler_name (decl, newid);
        }
    }

    else if (TREE_CODE (decl) == VAR_DECL
             && lookup_attribute ("selectany", DECL_ATTRIBUTES (decl)))
    {
        if (DECL_INITIAL (decl)
                /* If an object is initialized with a ctor, the static
                   initialization and destruction code for it is present in
                   each unit defining the object.  The code that calls the
                   ctor is protected by a link-once guard variable, so that
                   the object still has link-once semantics,  */
                || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)))
            make_decl_one_only (decl);
        else
            error ("%q+D:'selectany' attribute applies only to initialized objects",
                   decl);
    }

    /* Mark the decl so we can tell from the rtl whether the object is
       dllexport'd or dllimport'd.  tree.c: merge_dllimport_decl_attributes
       handles dllexport/dllimport override semantics.  */

    if (i386_pe_dllexport_p (decl))
        i386_pe_mark_dllexport (decl);
    else if (i386_pe_dllimport_p (decl))
        i386_pe_mark_dllimport (decl);
    /* It might be that DECL has been declared as dllimport, but a
       subsequent definition nullified that.  Assert that
       tree.c: merge_dllimport_decl_attributes has removed the attribute
       before the RTL name was marked with the DLL_IMPORT_PREFIX.  */
    else
        gcc_assert (!((TREE_CODE (decl) == FUNCTION_DECL
                       || TREE_CODE (decl) == VAR_DECL)
                      && rtl != NULL_RTX
                      && GET_CODE (rtl) == MEM
                      && GET_CODE (XEXP (rtl, 0)) == MEM
                      && GET_CODE (XEXP (XEXP (rtl, 0), 0)) == SYMBOL_REF
                      && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (rtl, 0), 0), 0))));
}
Esempio n. 4
0
void
i386_pe_encode_section_info (tree decl, rtx rtl, int first)
{
  default_encode_section_info (decl, rtl, first);

  if (first && TREE_CODE (decl) == FUNCTION_DECL)
    {
      tree type_attributes = TYPE_ATTRIBUTES (TREE_TYPE (decl));
      tree newid = NULL_TREE;

      if (lookup_attribute ("stdcall", type_attributes))
	newid = gen_stdcall_or_fastcall_suffix (decl, false);
      else if (lookup_attribute ("fastcall", type_attributes))
	newid = gen_stdcall_or_fastcall_suffix (decl, true);
      if (newid != NULL_TREE) 	
	{
	  rtx rtlname = XEXP (rtl, 0);
	  if (GET_CODE (rtlname) == MEM)
	    rtlname = XEXP (rtlname, 0);
	  XSTR (rtlname, 0) = IDENTIFIER_POINTER (newid);
	  /* These attributes must be present on first declaration,
	     change_decl_assembler_name will warn if they are added
	     later and the decl has been referenced, but duplicate_decls
	     should catch the mismatch before this is called.  */ 
	  change_decl_assembler_name (decl, newid);
	}
    }

  /* Mark the decl so we can tell from the rtl whether the object is
     dllexport'd or dllimport'd.  This also handles dllexport/dllimport
     override semantics.  */

  if (i386_pe_dllexport_p (decl))
    i386_pe_mark_dllexport (decl);
  else if (i386_pe_dllimport_p (decl))
    i386_pe_mark_dllimport (decl);
  /* It might be that DECL has already been marked as dllimport, but a
     subsequent definition nullified that.  The attribute is gone but
     DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
     that. Ditto for the DECL_NON_ADDR_CONST_P flag.  */
  else if ((TREE_CODE (decl) == FUNCTION_DECL
	    || TREE_CODE (decl) == VAR_DECL)
	   && DECL_RTL (decl) != NULL_RTX
	   && GET_CODE (DECL_RTL (decl)) == MEM
	   && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
	   && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
	   && i386_pe_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
    {
      const char *oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);

      /* Remove DLL_IMPORT_PREFIX.  */
      tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
      rtx symref = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
      SYMBOL_REF_DECL (symref) = decl;
      XEXP (DECL_RTL (decl), 0) = symref;
      DECL_NON_ADDR_CONST_P (decl) = 0;

      /* We previously set TREE_PUBLIC and DECL_EXTERNAL.
	 We leave these alone for now.  */

      if (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
	warning ("%J'%D' defined locally after being "
		 "referenced with dllimport linkage", decl, decl);
      else
	warning ("%J'%D' redeclared without dllimport attribute "
		 "after being referenced with dllimport linkage", decl, decl);
    }
}