gcc 源码阅读--全局符号表管理

重点查看几个类的定义

enum symtab_type
{
  SYMTAB_SYMBOL,
  SYMTAB_FUNCTION,
  SYMTAB_VARIABLE
};

/* Base of all entries in the symbol table.
   The symtab_node is inherited by cgraph and varpol nodes.  */
struct 
  symtab_node

{
public:
  friend class symbol_table;

  /* Constructor.  */
  explicit symtab_node (symtab_type t)
    : type (t), resolution (LDPR_UNKNOWN), definition (false), alias (false),
      transparent_alias (false), weakref (false), cpp_implicit_alias (false),
      symver (false), analyzed (false), writeonly (false),
      refuse_visibility_changes (false), externally_visible (false),
      no_reorder (false), force_output (false), forced_by_abi (false),
      unique_name (false), implicit_section (false), body_removed (false),
      semantic_interposition (flag_semantic_interposition),
      used_from_other_partition (false), in_other_partition (false),
      address_taken (false), in_init_priority_hash (false),
      need_lto_streaming (false), offloadable (false), ifunc_resolver (false),
      order (-1), next_sharing_asm_name (NULL),
      previous_sharing_asm_name (NULL), same_comdat_group (NULL), ref_list (),
      alias_target (NULL), lto_file_data (NULL), aux (NULL),
      x_comdat_group (NULL_TREE), x_section (NULL), m_uid (-1)
  {}

  /* Return name.  */
  const char *name () const;

  /* Return dump name.  */
  const char *dump_name () const;

  /* Return asm name.  */
  const char *asm_name () const;

  /* Return dump name with assembler name.  */
  const char *dump_asm_name () const;

  /* Return visibility name.  */
  const char *get_visibility_string () const;

  /* Return type_name name.  */
  const char *get_symtab_type_string () const;

  /* Add node into symbol table.  This function is not used directly, but via
     cgraph/varpool node creation routines.  */
  void register_symbol (void);

  /* Remove symbol from symbol table.  */
  void remove (void);

  /* Undo any definition or use of the symbol.  */
  void reset (bool preserve_comdat_group = false);

  /* Dump symtab node to F.  */
  void dump (FILE *f);

  /* Dump symtab callgraph in graphviz format.  */
  void dump_graphviz (FILE *f);

  /* Dump symtab node to stderr.  */
  void DEBUG_FUNCTION debug (void);

  /* Verify consistency of node.  */
  void DEBUG_FUNCTION verify (void);

  /* Return ipa reference from this symtab_node to
     REFERRED_NODE or REFERRED_VARPOOL_NODE. USE_TYPE specify type
     of the use and STMT the statement (if it exists).  */
  ipa_ref *create_reference (symtab_node *referred_node,
                 enum ipa_ref_use use_type);

  /* Return ipa reference from this symtab_node to
     REFERRED_NODE or REFERRED_VARPOOL_NODE. USE_TYPE specify type
     of the use and STMT the statement (if it exists).  */
  ipa_ref *create_reference (symtab_node *referred_node,
                 enum ipa_ref_use use_type, gimple *stmt);

  /* If VAL is a reference to a function or a variable, add a reference from
     this symtab_node to the corresponding symbol table node.  Return the new
     reference or NULL if none was created.  */
  ipa_ref *maybe_create_reference (tree val, gimple *stmt);

  /* Clone all references from symtab NODE to this symtab_node.  */
  void clone_references (symtab_node *node);

  /* Remove all stmt references in non-speculative references.
     Those are not maintained during inlining & clonning.
     The exception are speculative references that are updated along
     with callgraph edges associated with them.  */
  void clone_referring (symtab_node *node);

  /* Clone reference REF to this symtab_node and set its stmt to STMT.  */
  ipa_ref *clone_reference (ipa_ref *ref, gimple *stmt);

  /* Find the structure describing a reference to REFERRED_NODE of USE_TYPE and
     associated with statement STMT or LTO_STMT_UID.  */
  ipa_ref *find_reference (symtab_node *referred_node, gimple *stmt,
               unsigned int lto_stmt_uid,
               enum ipa_ref_use use_type);

  /* Remove all references that are associated with statement STMT.  */
  void remove_stmt_references (gimple *stmt);

  /* Remove all stmt references in non-speculative references.
     Those are not maintained during inlining & clonning.
     The exception are speculative references that are updated along
     with callgraph edges associated with them.  */
  void clear_stmts_in_references (void);

  /* Remove all references in ref list.  */
  void remove_all_references (void);

  /* Remove all referring items in ref list.  */
  void remove_all_referring (void);

  /* Dump references in ref list to FILE.  */
  void dump_references (FILE *file);

  /* Dump referring in list to FILE.  */
  void dump_referring (FILE *);

  /* Get number of references for this node.  */
  inline unsigned num_references (void)
  {
    return ref_list.references.length ();
  }

  /* Iterates I-th reference in the list, REF is also set.  */
  ipa_ref *iterate_reference (unsigned i, ipa_ref *&ref);

  /* Iterates I-th referring item in the list, REF is also set.  */
  ipa_ref *iterate_referring (unsigned i, ipa_ref *&ref);

  /* Iterates I-th referring alias item in the list, REF is also set.  */
  ipa_ref *iterate_direct_aliases (unsigned i, ipa_ref *&ref);

  /* Return true if symtab node and TARGET represents
     semantically equivalent symbols.  */
  bool semantically_equivalent_p (symtab_node *target);

  /* Classify symbol symtab node for partitioning.  */
  enum symbol_partitioning_class get_partitioning_class (void);

  /* Return comdat group.  */
  tree get_comdat_group ()
    {
      return x_comdat_group;
    }

  /* Return comdat group as identifier_node.  */
  tree get_comdat_group_id ()
    {
      if (x_comdat_group && TREE_CODE (x_comdat_group) != IDENTIFIER_NODE)
    x_comdat_group = DECL_ASSEMBLER_NAME (x_comdat_group);
      return x_comdat_group;
    }

  /* Set comdat group.  */
  void set_comdat_group (tree group)
    {
      gcc_checking_assert (!group || TREE_CODE (group) == IDENTIFIER_NODE
               || DECL_P (group));
      x_comdat_group = group;
    }

  /* Return section as string.  */
  const char * get_section () const
    {
      if (!x_section)
    return NULL;
      return x_section->name;
    }

  /* Remove node from same comdat group.   */
  void remove_from_same_comdat_group (void);

  /* Add this symtab_node to the same comdat group that OLD is in.  */
  void add_to_same_comdat_group (symtab_node *old_node);

  /* Dissolve the same_comdat_group list in which NODE resides.  */
  void dissolve_same_comdat_group_list (void);

  /* Return true when symtab_node is known to be used from other (non-LTO)
     object file. Known only when doing LTO via linker plugin.  */
  bool used_from_object_file_p (void);

  /* Walk the alias chain to return the symbol NODE is alias of.
     If NODE is not an alias, return NODE.
     When AVAILABILITY is non-NULL, get minimal availability in the chain.
     When REF is non-NULL, assume that reference happens in symbol REF
     when determining the availability.  */
  symtab_node *ultimate_alias_target (enum availability *avail = NULL,
                      struct symtab_node *ref = NULL);

  /* Return next reachable static symbol with initializer after NODE.  */
  inline symtab_node *next_defined_symbol (void);

  /* Add reference recording that symtab node is alias of TARGET.
     If TRANSPARENT is true make the alias to be transparent alias.
     The function can fail in the case of aliasing cycles; in this case
     it returns false.  */
  bool resolve_alias (symtab_node *target, bool transparent = false);

  /* C++ FE sometimes change linkage flags after producing same
     body aliases.  */
  void fixup_same_cpp_alias_visibility (symtab_node *target);

  /* Call callback on symtab node and aliases associated to this node.
     When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
     skipped.  */
  bool call_for_symbol_and_aliases (bool (*callback) (symtab_node *, void *),
                    void *data,
                    bool include_overwrite);

  /* If node cannot be interposable by static or dynamic linker to point to
     different definition, return this symbol. Otherwise look for alias with
     such property and if none exists, introduce new one.  */
  symtab_node *noninterposable_alias (void);

  /* Return node that alias is aliasing.  */
  inline symtab_node *get_alias_target (void);

  /* Return DECL that alias is aliasing.  */
  inline tree get_alias_target_tree ();

  /* Set section for symbol and its aliases.  */
  void set_section (const char *section);

  /* Like set_section, but copying the section name from another node.  */
  void set_section (const symtab_node &other);

  /* Set section, do not recurse into aliases.
     When one wants to change section of symbol and its aliases,
     use set_section.  */
  void set_section_for_node (const char *section);

  /* Like set_section_for_node, but copying the section name from another
     node.  */
  void set_section_for_node (const symtab_node &other);

  /* Set initialization priority to PRIORITY.  */
  void set_init_priority (priority_type priority);

  /* Return the initialization priority.  */
  priority_type get_init_priority ();

  /* Return availability of NODE when referenced from REF.  */
  enum availability get_availability (symtab_node *ref = NULL);

  /* During LTO stream-in this predicate can be used to check whether node
     in question prevails in the linking to save some memory usage.  */
  bool prevailing_p (void);

  /* Return true if NODE binds to current definition in final executable
     when referenced from REF.  If REF is NULL return conservative value
     for any reference.  */
  bool binds_to_current_def_p (symtab_node *ref = NULL);

  /* Make DECL local.  */
  void make_decl_local (void);

  /* Copy visibility from N.  */
  void copy_visibility_from (symtab_node *n);

  /* Return desired alignment of the definition.  This is NOT alignment useful
     to access THIS, because THIS may be interposable and DECL_ALIGN should
     be used instead.  It however must be guaranteed when output definition
     of THIS.  */
  unsigned int definition_alignment ();

  /* Return true if alignment can be increased.  */
  bool can_increase_alignment_p ();

  /* Increase alignment of symbol to ALIGN.  */
  void increase_alignment (unsigned int align);

  /* Return true if list contains an alias.  */
  bool has_aliases_p (void);

  /* Return true when the symbol is real symbol, i.e. it is not inline clone
     or abstract function kept for debug info purposes only.  */
  bool real_symbol_p (void);

  /* Return true when the symbol needs to be output to the LTO symbol table.  */
  bool output_to_lto_symbol_table_p (void);

  /* Determine if symbol declaration is needed.  That is, visible to something
     either outside this translation unit, something magic in the system
     configury. This function is used just during symbol creation.  */
  bool needed_p (void);

  /* Return true if this symbol is a function from the C frontend specified
     directly in RTL form (with "__RTL").  */
  bool native_rtl_p () const;

  /* Return true when there are references to the node.  */
  bool referred_to_p (bool include_self = true);

  /* Return true if symbol can be discarded by linker from the binary.
     Assume that symbol is used (so there is no need to take into account
     garbage collecting linkers)

     This can happen for comdats, commons and weaks when they are prevailed
     by other definition at static linking time.  */
  inline bool
  can_be_discarded_p (void)
  {
    return ((DECL_EXTERNAL (decl)
         && !in_other_partition)
        || ((get_comdat_group ()
         || DECL_COMMON (decl)
         || (DECL_SECTION_NAME (decl) && DECL_WEAK (decl)))
        && ((resolution != LDPR_PREVAILING_DEF
             && resolution != LDPR_PREVAILING_DEF_IRONLY_EXP)
            || flag_incremental_link)
        && resolution != LDPR_PREVAILING_DEF_IRONLY));
  }

  /* Return true if NODE is local to a particular COMDAT group, and must not
     be named from outside the COMDAT.  This is used for C++ decloned
     constructors.  */
  inline bool comdat_local_p (void)
  {
    return (same_comdat_group && !TREE_PUBLIC (decl));
  }

  /* Return true if ONE and TWO are part of the same COMDAT group.  */
  inline bool in_same_comdat_group_p (symtab_node *target);

  /* Return true if symbol is known to be nonzero, assume that
     flag_delete_null_pointer_checks is equal to delete_null_pointer_checks.  */
  bool nonzero_address (bool delete_null_pointer_checks);

  /* Return true if symbol is known to be nonzero.  */
  bool nonzero_address ();

  /* Return 0 if symbol is known to have different address than S2,
     Return 1 if symbol is known to have same address as S2,
     return 2 otherwise.

     If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
     and S2 is going to be accessed.  This eliminates the situations when
     either THIS or S2 is NULL and is useful for comparing bases when deciding
     about memory aliasing.  */
  int equal_address_to (symtab_node *s2, bool memory_accessed = false);

  /* Return true if symbol's address may possibly be compared to other
     symbol's address.  */
  bool address_matters_p ();

  /* Return true if NODE's address can be compared.  This use properties
     of NODE only and does not look if the address is actually taken in
     interesting way.  For that use ADDRESS_MATTERS_P instead.  */
  bool address_can_be_compared_p (void);

  /* Return symbol table node associated with DECL, if any,
    &

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GoldKey

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值