示例#1
0
文件: sol2.c 项目: 13572293130/gcc
void
solaris_elf_asm_comdat_section (const char *name, unsigned int flags, tree decl)
{
  const char *signature;
  char *section;
  comdat_entry entry, **slot;

  if (TREE_CODE (decl) == IDENTIFIER_NODE)
    signature = IDENTIFIER_POINTER (decl);
  else
    signature = IDENTIFIER_POINTER (DECL_COMDAT_GROUP (decl));

  /* Sun as requires group sections to be fragmented, i.e. to have names of
     the form <section>%<fragment>.  Strictly speaking this is only
     necessary to support cc -xF, but is enforced globally in violation of
     the ELF gABI.  We keep the section names generated by GCC (generally
     of the form .text.<signature>) and append %<signature> to pacify as,
     despite the redundancy.  */
  section = concat (name, "%", signature, NULL);

  /* Clear SECTION_LINKONCE flag so targetm.asm_out.named_section only
     emits this as a regular section.  Emit section before .group
     directive since Sun as treats undeclared sections as @progbits,
     which conflicts with .bss* sections which are @nobits.  */
  targetm.asm_out.named_section (section, flags & ~SECTION_LINKONCE, decl);
  
  /* Sun as separates declaration of a group section and of the group
     itself, using the .group directive and the #comdat flag.  */
  fprintf (asm_out_file, "\t.group\t%s," SECTION_NAME_FORMAT ",#comdat\n",
	   signature, section);

  /* Unlike GNU as, group signature symbols need to be defined explicitly
     for Sun as.  With a few exceptions, this is already the case.  To
     identify the missing ones without changing the affected frontents,
     remember the signature symbols and emit those not marked
     TREE_SYMBOL_REFERENCED in solaris_file_end.  */
  if (!solaris_comdat_htab)
    solaris_comdat_htab = new hash_table<comdat_entry_hasher> (37);

  entry.sig = signature;
  slot = solaris_comdat_htab->find_slot (&entry, INSERT);

  if (*slot == NULL)
    {
      *slot = XCNEW (comdat_entry);
      /* Remember fragmented section name.  */
      (*slot)->name = section;
      /* Emit as regular section, .group declaration has already been done.  */
      (*slot)->flags = flags & ~SECTION_LINKONCE;
      (*slot)->decl = decl;
      (*slot)->sig = signature;
    }
}
示例#2
0
symtab_node *
symtab_nonoverwritable_alias (symtab_node *node)
{
  tree new_decl;
  symtab_node *new_node = NULL;

  /* First try to look up existing alias or base object
     (if that is already non-overwritable).  */
  node = symtab_alias_ultimate_target (node, NULL);
  gcc_assert (!node->alias && !node->weakref);
  symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
		               (void *)&new_node, true);
  if (new_node)
    return new_node;
#ifndef ASM_OUTPUT_DEF
  /* If aliases aren't supported by the assembler, fail.  */
  return NULL;
#endif

  /* Otherwise create a new one.  */
  new_decl = copy_node (node->decl);
  DECL_DLLIMPORT_P (new_decl) = 0;
  DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias");
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (new_decl) = NULL;
  DECL_INITIAL (new_decl) = NULL;
  SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
  SET_DECL_RTL (new_decl, NULL);

  /* Update the properties.  */
  DECL_EXTERNAL (new_decl) = 0;
  if (DECL_ONE_ONLY (node->decl))
    DECL_SECTION_NAME (new_decl) = NULL;
  DECL_COMDAT_GROUP (new_decl) = 0;
  TREE_PUBLIC (new_decl) = 0;
  DECL_COMDAT (new_decl) = 0;
  DECL_WEAK (new_decl) = 0;
  DECL_VIRTUAL_P (new_decl) = 0;
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    {
      DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
      DECL_STATIC_DESTRUCTOR (new_decl) = 0;
      new_node = cgraph_create_function_alias
				 (new_decl, node->decl);
    }
  else
    new_node = varpool_create_variable_alias (new_decl,
							    node->decl);
  symtab_resolve_alias (new_node, node);  
  gcc_assert (decl_binds_to_current_def_p (new_decl));
  return new_node;
}
static void
write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
			              bool ref_p)
{
  /* Make sure we don't inadvertently set the assembler name.  */
  if (DECL_ASSEMBLER_NAME_SET_P (expr))
    stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
  else
    stream_write_tree (ob, NULL_TREE, false);

  stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
  stream_write_tree (ob, DECL_COMDAT_GROUP (expr), ref_p);
}
示例#4
0
void
symtab_add_to_same_comdat_group (symtab_node new_node,
				 symtab_node old_node)
{
  gcc_assert (DECL_ONE_ONLY (old_node->symbol.decl));
  gcc_assert (!new_node->symbol.same_comdat_group);
  gcc_assert (new_node != old_node);

  DECL_COMDAT_GROUP (new_node->symbol.decl) = DECL_COMDAT_GROUP (old_node->symbol.decl);
  new_node->symbol.same_comdat_group = old_node;
  if (!old_node->symbol.same_comdat_group)
    old_node->symbol.same_comdat_group = new_node;
  else
    {
      symtab_node n;
      for (n = old_node->symbol.same_comdat_group;
	   n->symbol.same_comdat_group != old_node;
	   n = n->symbol.same_comdat_group)
	;
      n->symbol.same_comdat_group = new_node;
    }
}
示例#5
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);
}
static void
lto_input_ts_decl_with_vis_tree_pointers (struct lto_input_block *ib,
				          struct data_in *data_in, tree expr)
{
  tree id;

  id = stream_read_tree (ib, data_in);
  if (id)
    {
      gcc_assert (TREE_CODE (id) == IDENTIFIER_NODE);
      SET_DECL_ASSEMBLER_NAME (expr, id);
    }

  DECL_SECTION_NAME (expr) = stream_read_tree (ib, data_in);
  DECL_COMDAT_GROUP (expr) = stream_read_tree (ib, data_in);
}
示例#7
0
void
symtab_dissolve_same_comdat_group_list (symtab_node *node)
{
  symtab_node *n = node;
  symtab_node *next;

  if (!node->same_comdat_group)
    return;
  do
    {
      next = n->same_comdat_group;
      n->same_comdat_group = NULL;
      /* Clear DECL_COMDAT_GROUP for comdat locals, since
         make_decl_local doesn't.  */
      if (!TREE_PUBLIC (n->decl))
	DECL_COMDAT_GROUP (n->decl) = NULL_TREE;
      n = next;
    }
  while (n != node);
}
示例#8
0
void
symtab_make_decl_local (tree decl)
{
  rtx rtl, symbol;

  /* Avoid clearing DECL_COMDAT_GROUP on comdat-local decls.  */
  if (TREE_PUBLIC (decl) == 0)
    return;

  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))
    {
      DECL_SECTION_NAME (decl) = 0;
      DECL_COMDAT (decl) = 0;
    }
  DECL_COMDAT_GROUP (decl) = 0;
  DECL_WEAK (decl) = 0;
  DECL_EXTERNAL (decl) = 0;
  DECL_VISIBILITY_SPECIFIED (decl) = 0;
  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
  TREE_PUBLIC (decl) = 0;
  DECL_DLLIMPORT_P (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);
}
示例#9
0
文件: symtab.c 项目: Roffi/gcc
symtab_node
symtab_nonoverwritable_alias (symtab_node node)
{
  tree new_decl;
  symtab_node new_node = NULL;
  symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
		               (void *)&new_node, true);
  if (new_node)
    return new_node;

  new_decl = copy_node (node->symbol.decl);
  DECL_NAME (new_decl) = clone_function_name (node->symbol.decl, "localalias");
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (new_decl) = NULL;
  DECL_INITIAL (new_decl) = NULL;
  SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
  SET_DECL_RTL (new_decl, NULL);

  /* Update the properties.  */
  DECL_EXTERNAL (new_decl) = 0;
  if (DECL_ONE_ONLY (node->symbol.decl))
    DECL_SECTION_NAME (new_decl) = NULL;
  DECL_COMDAT_GROUP (new_decl) = 0;
  TREE_PUBLIC (new_decl) = 0;
  DECL_COMDAT (new_decl) = 0;
  DECL_WEAK (new_decl) = 0;
  DECL_VIRTUAL_P (new_decl) = 0;
  if (TREE_CODE (new_decl) == FUNCTION_DECL)
    {
      DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
      DECL_STATIC_DESTRUCTOR (new_decl) = 0;
      new_node = (symtab_node) cgraph_create_function_alias (new_decl, node->symbol.decl);
    }
  else
    new_node = (symtab_node) varpool_create_variable_alias (new_decl, node->symbol.decl);
  symtab_resolve_alias (new_node, node);  
  return new_node;
}
示例#10
0
static struct cgraph_node *
save_inline_function_body (struct cgraph_node *node)
{
  struct cgraph_node *first_clone, *n;

  if (dump_file)
    fprintf (dump_file, "\nSaving body of %s for later reuse\n",
	     cgraph_node_name (node));
 
  gcc_assert (node == cgraph_get_node (node->symbol.decl));

  /* first_clone will be turned into real function.  */
  first_clone = node->clones;
  first_clone->symbol.decl = copy_node (node->symbol.decl);
  symtab_insert_node_to_hashtable ((symtab_node) first_clone);
  gcc_assert (first_clone == cgraph_get_node (first_clone->symbol.decl));

  /* Now reshape the clone tree, so all other clones descends from
     first_clone.  */
  if (first_clone->next_sibling_clone)
    {
      for (n = first_clone->next_sibling_clone; n->next_sibling_clone; n = n->next_sibling_clone)
        n->clone_of = first_clone;
      n->clone_of = first_clone;
      n->next_sibling_clone = first_clone->clones;
      if (first_clone->clones)
        first_clone->clones->prev_sibling_clone = n;
      first_clone->clones = first_clone->next_sibling_clone;
      first_clone->next_sibling_clone->prev_sibling_clone = NULL;
      first_clone->next_sibling_clone = NULL;
      gcc_assert (!first_clone->prev_sibling_clone);
    }
  first_clone->clone_of = NULL;

  /* Now node in question has no clones.  */
  node->clones = NULL;

  /* Inline clones share decl with the function they are cloned
     from.  Walk the whole clone tree and redirect them all to the
     new decl.  */
  if (first_clone->clones)
    for (n = first_clone->clones; n != first_clone;)
      {
        gcc_assert (n->symbol.decl == node->symbol.decl);
	n->symbol.decl = first_clone->symbol.decl;
	if (n->clones)
	  n = n->clones;
	else if (n->next_sibling_clone)
	  n = n->next_sibling_clone;
	else
	  {
	    while (n != first_clone && !n->next_sibling_clone)
	      n = n->clone_of;
	    if (n != first_clone)
	      n = n->next_sibling_clone;
	  }
      }

  /* Copy the OLD_VERSION_NODE function tree to the new version.  */
  tree_function_versioning (node->symbol.decl, first_clone->symbol.decl,
			    NULL, true, NULL, false,
			    NULL, NULL);

  /* The function will be short lived and removed after we inline all the clones,
     but make it internal so we won't confuse ourself.  */
  DECL_EXTERNAL (first_clone->symbol.decl) = 0;
  DECL_COMDAT_GROUP (first_clone->symbol.decl) = NULL_TREE;
  TREE_PUBLIC (first_clone->symbol.decl) = 0;
  DECL_COMDAT (first_clone->symbol.decl) = 0;
  first_clone->ipa_transforms_to_apply.release ();

  /* When doing recursive inlining, the clone may become unnecessary.
     This is possible i.e. in the case when the recursive function is proved to be
     non-throwing and the recursion happens only in the EH landing pad.
     We can not remove the clone until we are done with saving the body.
     Remove it now.  */
  if (!first_clone->callers)
    {
      cgraph_remove_node_and_inline_clones (first_clone, NULL);
      first_clone = NULL;
    }
#ifdef ENABLE_CHECKING
  else
    verify_cgraph_node (first_clone);
#endif
  return first_clone;
}
示例#11
0
/* Walk the decls we marked as necessary and see if they reference new
   variables or functions and add them into the worklists.  */
bool
varpool_analyze_pending_decls (void)
{
  bool changed = false;

  timevar_push (TV_VARPOOL);
  while (varpool_first_unanalyzed_node)
    {
      struct varpool_node *node = varpool_first_unanalyzed_node, *next;
      tree decl = node->decl;
      bool analyzed = node->analyzed;

      varpool_first_unanalyzed_node->analyzed = true;

      varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed;

      /* When reading back varpool at LTO time, we re-construct the queue in order
         to have "needed" list right by inserting all needed nodes into varpool.
	 We however don't want to re-analyze already analyzed nodes.  */
      if (!analyzed)
	{
	  gcc_assert (!in_lto_p || cgraph_function_flags_ready);
          /* Compute the alignment early so function body expanders are
	     already informed about increased alignment.  */
          align_variable (decl, 0);
	}
      if (node->alias && node->alias_of)
	{
	  struct varpool_node *tgt = varpool_node (node->alias_of);
          struct varpool_node *n;

	  for (n = tgt; n && n->alias;
	       n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
	    if (n == node)
	      {
		error ("variable %q+D part of alias cycle", node->decl);
		node->alias = false;
		continue;
	      }
	  if (!VEC_length (ipa_ref_t, node->ref_list.references))
	    ipa_record_reference (NULL, node, NULL, tgt, IPA_REF_ALIAS, NULL);
	  /* C++ FE sometimes change linkage flags after producing same body aliases.  */
	  if (node->extra_name_alias)
	    {
	      DECL_WEAK (node->decl) = DECL_WEAK (node->alias_of);
	      TREE_PUBLIC (node->decl) = TREE_PUBLIC (node->alias_of);
	      DECL_EXTERNAL (node->decl) = DECL_EXTERNAL (node->alias_of);
	      DECL_VISIBILITY (node->decl) = DECL_VISIBILITY (node->alias_of);
	      if (TREE_PUBLIC (node->decl))
		{
		  DECL_COMDAT (node->decl) = DECL_COMDAT (node->alias_of);
		  DECL_COMDAT_GROUP (node->decl) = DECL_COMDAT_GROUP (node->alias_of);
		  if (DECL_ONE_ONLY (node->alias_of) && !node->same_comdat_group)
		    {
		      node->same_comdat_group = tgt;
		      if (!tgt->same_comdat_group)
			tgt->same_comdat_group = node;
		      else
			{
			  struct varpool_node *n;
			  for (n = tgt->same_comdat_group;
			       n->same_comdat_group != tgt;
			       n = n->same_comdat_group)
			    ;
			  n->same_comdat_group = node;
			}
		    }
		}
	    }
	}
      else if (DECL_INITIAL (decl))
	record_references_in_initializer (decl, analyzed);
      if (node->same_comdat_group)
	{
	  for (next = node->same_comdat_group;
	       next != node;
	       next = next->same_comdat_group)
	    varpool_mark_needed_node (next);
	}
      changed = true;
    }
  timevar_pop (TV_VARPOOL);
  return changed;
}
示例#12
0
void
dump_symtab_base (FILE *f, symtab_node node)
{
  static const char * const visibility_types[] = {
    "default", "protected", "hidden", "internal"
  };

  fprintf (f, "%s/%i (%s)",
	   symtab_node_asm_name (node),
	   node->symbol.order,
	   symtab_node_name (node));
  dump_addr (f, " @", (void *)node);
  fprintf (f, "\n  Type: %s\n", symtab_type_names[node->symbol.type]);
  fprintf (f, "  Visibility:");

  if (node->symbol.in_other_partition)
    fprintf (f, " in_other_partition");
  if (node->symbol.used_from_other_partition)
    fprintf (f, " used_from_other_partition");
  if (node->symbol.force_output)
    fprintf (f, " force_output");
  if (node->symbol.resolution != LDPR_UNKNOWN)
    fprintf (f, " %s",
 	     ld_plugin_symbol_resolution_names[(int)node->symbol.resolution]);
  if (TREE_ASM_WRITTEN (node->symbol.decl))
    fprintf (f, " asm_written");
  if (DECL_EXTERNAL (node->symbol.decl))
    fprintf (f, " external");
  if (TREE_PUBLIC (node->symbol.decl))
    fprintf (f, " public");
  if (DECL_COMMON (node->symbol.decl))
    fprintf (f, " common");
  if (DECL_WEAK (node->symbol.decl))
    fprintf (f, " weak");
  if (DECL_DLLIMPORT_P (node->symbol.decl))
    fprintf (f, " dll_import");
  if (DECL_COMDAT (node->symbol.decl))
    fprintf (f, " comdat");
  if (DECL_COMDAT_GROUP (node->symbol.decl))
    fprintf (f, " comdat_group:%s",
	     IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->symbol.decl)));
  if (DECL_ONE_ONLY (node->symbol.decl))
    fprintf (f, " one_only");
  if (DECL_SECTION_NAME (node->symbol.decl))
    fprintf (f, " section_name:%s",
	     TREE_STRING_POINTER (DECL_SECTION_NAME (node->symbol.decl)));
  if (DECL_VISIBILITY_SPECIFIED (node->symbol.decl))
    fprintf (f, " visibility_specified");
  if (DECL_VISIBILITY (node->symbol.decl))
    fprintf (f, " visibility:%s",
	     visibility_types [DECL_VISIBILITY (node->symbol.decl)]);
  if (DECL_VIRTUAL_P (node->symbol.decl))
    fprintf (f, " virtual");
  if (DECL_ARTIFICIAL (node->symbol.decl))
    fprintf (f, " artificial");
  if (TREE_CODE (node->symbol.decl) == FUNCTION_DECL)
    {
      if (DECL_STATIC_CONSTRUCTOR (node->symbol.decl))
	fprintf (f, " constructor");
      if (DECL_STATIC_DESTRUCTOR (node->symbol.decl))
	fprintf (f, " destructor");
    }
  fprintf (f, "\n");
  
  if (node->symbol.same_comdat_group)
    fprintf (f, "  Same comdat group as: %s/%i\n",
	     symtab_node_asm_name (node->symbol.same_comdat_group),
	     node->symbol.same_comdat_group->symbol.order);
  if (node->symbol.next_sharing_asm_name)
    fprintf (f, "  next sharing asm name: %i\n",
	     node->symbol.next_sharing_asm_name->symbol.order);
  if (node->symbol.previous_sharing_asm_name)
    fprintf (f, "  previous sharing asm name: %i\n",
	     node->symbol.previous_sharing_asm_name->symbol.order);

  if (node->symbol.address_taken)
    fprintf (f, "  Address is taken.\n");
  if (node->symbol.aux)
    {
      fprintf (f, "  Aux:");
      dump_addr (f, " @", (void *)node->symbol.aux);
    }

  fprintf (f, "  References: ");
  ipa_dump_references (f, &node->symbol.ref_list);
  fprintf (f, "  Referring: ");
  ipa_dump_referring (f, &node->symbol.ref_list);
}
示例#13
0
DEBUG_FUNCTION bool
verify_symtab_base (symtab_node *node)
{
  bool error_found = false;
  symtab_node *hashed_node;

  if (is_a <cgraph_node> (node))
    {
      if (TREE_CODE (node->decl) != FUNCTION_DECL)
	{
          error ("function symbol is not function");
          error_found = true;
	}
    }
  else if (is_a <varpool_node> (node))
    {
      if (TREE_CODE (node->decl) != VAR_DECL)
	{
          error ("variable symbol is not variable");
          error_found = true;
	}
    }
  else
    {
      error ("node has unknown type");
      error_found = true;
    }
   
  if (cgraph_state != CGRAPH_LTO_STREAMING)
    {
      hashed_node = symtab_get_node (node->decl);
      if (!hashed_node)
	{
	  error ("node not found in symtab decl hashtable");
	  error_found = true;
	}
      if (hashed_node != node
	  && (!is_a <cgraph_node> (node)
	      || !dyn_cast <cgraph_node> (node)->clone_of
	      || dyn_cast <cgraph_node> (node)->clone_of->decl
		 != node->decl))
	{
	  error ("node differs from symtab decl hashtable");
	  error_found = true;
	}
    }
  if (assembler_name_hash)
    {
      hashed_node = symtab_node_for_asm (DECL_ASSEMBLER_NAME (node->decl));
      if (hashed_node && hashed_node->previous_sharing_asm_name)
	{
          error ("assembler name hash list corrupted");
          error_found = true;
	}
      while (hashed_node)
	{
	  if (hashed_node == node)
	    break;
	  hashed_node = hashed_node->next_sharing_asm_name;
	}
      if (!hashed_node
          && !(is_a <varpool_node> (node)
	       || DECL_HARD_REGISTER (node->decl)))
	{
          error ("node not found in symtab assembler name hash");
          error_found = true;
	}
    }
  if (node->previous_sharing_asm_name
      && node->previous_sharing_asm_name->next_sharing_asm_name != node)
    {
      error ("double linked list of assembler names corrupted");
      error_found = true;
    }
  if (node->analyzed && !node->definition)
    {
      error ("node is analyzed byt it is not a definition");
      error_found = true;
    }
  if (node->cpp_implicit_alias && !node->alias)
    {
      error ("node is alias but not implicit alias");
      error_found = true;
    }
  if (node->alias && !node->definition
      && !node->weakref)
    {
      error ("node is alias but not definition");
      error_found = true;
    }
  if (node->weakref && !node->alias)
    {
      error ("node is weakref but not an alias");
      error_found = true;
    }
  if (node->same_comdat_group)
    {
      symtab_node *n = node->same_comdat_group;

      if (!DECL_ONE_ONLY (n->decl))
	{
	  error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
	  error_found = true;
	}
      if (DECL_COMDAT_GROUP (n->decl) != DECL_COMDAT_GROUP (node->same_comdat_group->decl))
	{
	  error ("same_comdat_group list across different groups");
	  error_found = true;
	}
      if (!n->definition)
	{
	  error ("Node has same_comdat_group but it is not a definition");
	  error_found = true;
	}
      if (n->type != node->type)
	{
	  error ("mixing different types of symbol in same comdat groups is not supported");
	  error_found = true;
	}
      if (n == node)
	{
	  error ("node is alone in a comdat group");
	  error_found = true;
	}
      do
	{
	  if (!n->same_comdat_group)
	    {
	      error ("same_comdat_group is not a circular list");
	      error_found = true;
	      break;
	    }
	  n = n->same_comdat_group;
	}
      while (n != node);
      if (symtab_comdat_local_p (node))
	{
	  struct ipa_ref_list *refs = &node->ref_list;
	  struct ipa_ref *ref;
	  for (int i = 0; ipa_ref_list_referring_iterate (refs, i, ref); ++i)
	    {
	      if (!symtab_in_same_comdat_p (ref->referring, node))
		{
		  error ("comdat-local symbol referred to by %s outside its "
			 "comdat",
			 identifier_to_locale (ref->referring->name()));
		  error_found = true;
		}
	    }
	}
    }
  return error_found;
}
示例#14
0
void
dump_symtab_base (FILE *f, symtab_node *node)
{
  static const char * const visibility_types[] = {
    "default", "protected", "hidden", "internal"
  };

  fprintf (f, "%s/%i (%s)",
	   node->asm_name (),
	   node->order,
	   node->name ());
  dump_addr (f, " @", (void *)node);
  fprintf (f, "\n  Type: %s", symtab_type_names[node->type]);

  if (node->definition)
    fprintf (f, " definition");
  if (node->analyzed)
    fprintf (f, " analyzed");
  if (node->alias)
    fprintf (f, " alias");
  if (node->weakref)
    fprintf (f, " weakref");
  if (node->cpp_implicit_alias)
    fprintf (f, " cpp_implicit_alias");
  if (node->alias_target)
    fprintf (f, " target:%s",
	     DECL_P (node->alias_target) 
	     ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
				     (node->alias_target))
	     : IDENTIFIER_POINTER (node->alias_target));
  if (node->body_removed)
    fprintf (f, "\n  Body removed by symtab_remove_unreachable_nodes");
  fprintf (f, "\n  Visibility:");
  if (node->in_other_partition)
    fprintf (f, " in_other_partition");
  if (node->used_from_other_partition)
    fprintf (f, " used_from_other_partition");
  if (node->force_output)
    fprintf (f, " force_output");
  if (node->forced_by_abi)
    fprintf (f, " forced_by_abi");
  if (node->externally_visible)
    fprintf (f, " externally_visible");
  if (node->resolution != LDPR_UNKNOWN)
    fprintf (f, " %s",
 	     ld_plugin_symbol_resolution_names[(int)node->resolution]);
  if (TREE_ASM_WRITTEN (node->decl))
    fprintf (f, " asm_written");
  if (DECL_EXTERNAL (node->decl))
    fprintf (f, " external");
  if (TREE_PUBLIC (node->decl))
    fprintf (f, " public");
  if (DECL_COMMON (node->decl))
    fprintf (f, " common");
  if (DECL_WEAK (node->decl))
    fprintf (f, " weak");
  if (DECL_DLLIMPORT_P (node->decl))
    fprintf (f, " dll_import");
  if (DECL_COMDAT (node->decl))
    fprintf (f, " comdat");
  if (DECL_COMDAT_GROUP (node->decl))
    fprintf (f, " comdat_group:%s",
	     IDENTIFIER_POINTER (DECL_COMDAT_GROUP (node->decl)));
  if (DECL_ONE_ONLY (node->decl))
    fprintf (f, " one_only");
  if (DECL_SECTION_NAME (node->decl))
    fprintf (f, " section_name:%s",
	     TREE_STRING_POINTER (DECL_SECTION_NAME (node->decl)));
  if (DECL_VISIBILITY_SPECIFIED (node->decl))
    fprintf (f, " visibility_specified");
  if (DECL_VISIBILITY (node->decl))
    fprintf (f, " visibility:%s",
	     visibility_types [DECL_VISIBILITY (node->decl)]);
  if (DECL_VIRTUAL_P (node->decl))
    fprintf (f, " virtual");
  if (DECL_ARTIFICIAL (node->decl))
    fprintf (f, " artificial");
  if (TREE_CODE (node->decl) == FUNCTION_DECL)
    {
      if (DECL_STATIC_CONSTRUCTOR (node->decl))
	fprintf (f, " constructor");
      if (DECL_STATIC_DESTRUCTOR (node->decl))
	fprintf (f, " destructor");
    }
  fprintf (f, "\n");
  
  if (node->same_comdat_group)
    fprintf (f, "  Same comdat group as: %s/%i\n",
	     node->same_comdat_group->asm_name (),
	     node->same_comdat_group->order);
  if (node->next_sharing_asm_name)
    fprintf (f, "  next sharing asm name: %i\n",
	     node->next_sharing_asm_name->order);
  if (node->previous_sharing_asm_name)
    fprintf (f, "  previous sharing asm name: %i\n",
	     node->previous_sharing_asm_name->order);

  if (node->address_taken)
    fprintf (f, "  Address is taken.\n");
  if (node->aux)
    {
      fprintf (f, "  Aux:");
      dump_addr (f, " @", (void *)node->aux);
    }

  fprintf (f, "  References: ");
  ipa_dump_references (f, &node->ref_list);
  fprintf (f, "  Referring: ");
  ipa_dump_referring (f, &node->ref_list);
  if (node->lto_file_data)
    fprintf (f, "  Read from file: %s\n",
	     node->lto_file_data->file_name);
}