Studying note of GCC-3.4.6 source (53)

4.3.1.7.2.4.      Entity for global namespace

The identifier of global namespace is global_scope_name, and its front-end tree node has code NAMESPACE_DECL. As namespace hasn’t type information, so parameter type of below function is void_type_node.

 

687    tree

688    build_lang_decl (enum tree_code code, tree name, tree type)                              in lex.c

689    {

690      tree t;

691   

692      t = build_decl (code, name, type);

693      retrofit_lang_decl (t);

694   

695      return t;

696    }

 

For every declaration, it has a node of tree_decl going with. As declaration is part of the language, we can find following field in tree_decl definition.

 

1647 struct tree_decl GTY(())

1648 {

        ...

1748   struct lang_decl *lang_specific;

1749 };

 

Field lang_decl records the information of the language. In C++, the definition of lang_decl is following.

 

1661 struct lang_decl GTY(())                                                                            in cp-tree.h

1662 {

1663   struct lang_decl_flags decl_flags;

1664

1665   union lang_decl_u4

1666   {

1667     struct full_lang_decl

1668     {

1669       /* For a non-thunk function decl, this is a tree list of

1670         friendly classes. For a thunk function decl, it is the

1671         thunked to function decl.  */

1672       tree befriending_classes;

1673  

1674       /* For a non-virtual FUNCTION_DECL, this is

1675         DECL_FRIEND_CONTEXT. For a virtual FUNCTION_DECL for which

1676         DECL_THIS_THUNK_P does not hold, this is DECL_THUNKS. Both

1677         this pointer and result pointer adjusting thunks are

1678         chained here. This pointer thunks to return pointer thunks

1679         will be chained on the return pointer thunk.  */

1680       tree context;

1681

1682       /* In a FUNCTION_DECL, this is DECL_CLONED_FUNCTION.  */

1683       tree cloned_function;

1684  

1685       /* In a FUNCTION_DECL for which THUNK_P holds, this is

1686         THUNK_FIXED_OFFSET.  */

1687       HOST_WIDE_INT fixed_offset;

1688

1689       /* In an overloaded operator, this is the value of

1690         DECL_OVERLOADED_OPERATOR_P.  */

1691       enum tree_code operator_code;

1692

1693       unsigned u3sel : 1;

1694       unsigned pending_inline_p : 1;

1695  

1696       union lang_decl_u3

1697       {

1698         struct sorted_fields_type * GTY ((tag ("0"), reorder ("resort_sorted_fields")))

1699               sorted_fields;

1700         struct cp_token_cache * GTY ((tag ("2"))) pending_inline_info;

1701         struct language_function * GTY ((tag ("1")))

1702               saved_language_function;

1703       } GTY ((desc ("%1.u3sel + %1.pending_inline_p"))) u;

1704     } GTY ((tag ("1"))) f;

1705   } GTY ((desc ("%1.decl_flags.can_be_full"))) u;

1706 };

 

See that lang_decl_flags is the first element of lang_decl. So these two types can be used exchangable but need pay attention to not to exceed the boundary of lang_decl_flags when handling it as lang_decl. Field can_be_full in lang_decl_flags tells which type the node is, lang_decl_flags or lang_decl.

 

1601 struct lang_decl_flags GTY(())                                                                   in cp-tree.h

1602 {

1603   ENUM_BITFIELD(languages) language : 8;

1604

1605   unsigned operator_attr : 1;

1606   unsigned constructor_attr : 1;

1607   unsigned destructor_attr : 1;

1608   unsigned friend_attr : 1;

1609   unsigned static_function : 1;

1610   unsigned pure_virtual : 1;

1611   unsigned has_in_charge_parm_p : 1;

1612   unsigned has_vtt_parm_p : 1;

1613

1614   unsigned deferred : 1;

1615   unsigned use_template : 2;

1616   unsigned nonconverting : 1;

1617   unsigned not_really_extern : 1;

1618   unsigned needs_final_overrider : 1;

1619   unsigned initialized_in_class : 1;

1620   unsigned assignment_operator_p : 1;

1621

1622   unsigned global_ctor_p : 1;

1623   unsigned global_dtor_p : 1;

1624   unsigned anticipated_p : 1;

1625   unsigned template_conv_p : 1;

1626   unsigned u1sel : 1;

1627   unsigned u2sel : 1;

1628   unsigned can_be_full : 1;

1629   unsigned this_thunk_p : 1;

1630

1631   union lang_decl_u {

1632     /* In a FUNCTION_DECL for which DECL_THUNK_P does not hold,

1633       VAR_DECL, TYPE_DECL, or TEMPLATE_DECL, this is

1634       DECL_TEMPLATE_INFO.  */

1635     tree GTY ((tag ("0"))) template_info;

1636

1637     /* In a NAMESPACE_DECL, this is NAMESPACE_LEVEL.  */

1638     struct cp_binding_level * GTY ((tag ("1"))) level;

1639

1640     /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is

1641       THUNK_ALIAS.  */

1642     tree GTY ((tag ("2"))) thunk_alias;

1643   } GTY ((desc ("%1.u1sel"))) u;

1644

1645   union lang_decl_u2 {

1646     /* This is DECL_ACCESS.  */

1647     tree GTY ((tag ("0"))) access;

1648

1649     /* For VAR_DECL in function, this is DECL_DISCRIMINATOR.  */

1650     int GTY ((tag ("1"))) discriminator;

1651

1652     /* In a FUNCTION_DECL for which DECL_THUNK_P holds, this is

1653       THUNK_VIRTUAL_OFFSET.  */

1654     tree GTY((tag ("2"))) virtual_offset;

1655   } GTY ((desc ("%1.u2sel"))) u2;

1656 };

 

Notice that fields u[num]sel above, if nonzero indicates lang_decl_u[num] field in lang_decl/lang_decl_flags will be used.

This complex structure is created and initialized by retrofit_lang_decl according to the type of declaration.

 

701    void

702    retrofit_lang_decl (tree t)                                                                                 in lex.c

703    {

704      struct lang_decl *ld;

705      size_t size;

706   

707      if (CAN_HAVE_FULL_LANG_DECL_P (t))

708       size = sizeof (struct lang_decl);

709      else

710        size = sizeof (struct lang_decl_flags);

711    

712      ld = ggc_alloc_cleared (size);

713   

714      ld->decl_flags.can_be_full = CAN_HAVE_FULL_LANG_DECL_P (t) ? 1 : 0;

715      ld->decl_flags.u1sel = TREE_CODE (t) == NAMESPACE_DECL ? 1 : 0;

716      ld->decl_flags.u2sel = 0;

717      if (ld->decl_flags.can_be_full)

718        ld->u.f.u3sel = TREE_CODE (t) == FUNCTION_DECL ? 1 : 0;

719   

720      DECL_LANG_SPECIFIC (t) = ld;

721      if (current_lang_name == lang_name_cplusplus

722          || decl_linkage (t) == lk_none)

723        SET_DECL_LANGUAGE (t, lang_cplusplus);

724      else if (current_lang_name == lang_name_c)

725        SET_DECL_LANGUAGE (t, lang_c);

726      else if (current_lang_name == lang_name_java)

727        SET_DECL_LANGUAGE (t, lang_java);

728      else abort ();

729   

730    #ifdef GATHER_STATISTICS

731      tree_node_counts[(int)lang_decl] += 1;

732      tree_node_sizes[(int)lang_decl] += size;

733    #endif

734    }

 

CAN_HAVE_FULL_LANG_DECL_P is the macro to tell which type used for lang_specific of tree_decl.

 

1595 #define CAN_HAVE_FULL_LANG_DECL_P(NODE)            /                    in cp-tree.h

1596   (!(TREE_CODE (NODE) == VAR_DECL           /

1597      || TREE_CODE (NODE) == CONST_DECL          /

1598      || TREE_CODE (NODE) == FIELD_DECL           /

1599      || TREE_CODE (NODE) == USING_DECL)

 

Know that lang_decl_u1 is used for namespace declaration, lang_decl_u3 used for function declaration.

4.3.1.7.2.5.      Create the scope

When new scope is expected, begin_scope is invoked to create the scope and make it the top of the active scopes stack.

 

1277 cxx_scope *

1278 begin_scope (scope_kind kind, tree entity)                                                  in name-lookup.c

1279 {

1280   cxx_scope *scope;

1281   

1282   /* Reuse or create a struct for this binding level.  */

1283   if (!ENABLE_SCOPE_CHECKING && free_binding_level)

1284   {

1285     scope = free_binding_level;

1286     free_binding_level = scope->level_chain;

1287   }

1288   else

1289     scope = ggc_alloc (sizeof (cxx_scope));

1290   memset (scope, 0, sizeof (cxx_scope));

1291

1292   scope->this_entity = entity;

1293   scope->more_cleanups_ok = true;

1294   switch (kind)

1295   {

1296     case sk_cleanup:

1297       scope->keep = true;

1298       break;

1299       

1300     case sk_template_spec:

1301       scope->explicit_spec_p = true;

1302       kind = sk_template_parms;

1303       /* Fall through.  */

1304     case sk_template_parms:

1305     case sk_block:

1306     case sk_try:

1307     case sk_catch:

1308     case sk_for:

1309     case sk_class:

1310     case sk_function_parms:

1311       scope->keep = keep_next_level_flag;

1312       break;

1313

1314     case sk_namespace:

1315       scope->type_decls = binding_table_new (namespace_scope_ht_size (entity));

1316       NAMESPACE_LEVEL (entity) = scope;

1317       VARRAY_TREE_INIT (scope->static_decls,

1318                         DECL_NAME (entity) == std_identifier

1319                         || DECL_NAME (entity) == global_scope_name

1320                         ? 200 : 10,

1321                         "Static declarations");

1322       break;

1323

1324     default:

1325       /* Should not happen.  */

1326       my_friendly_assert (false, 20030922);

1327       break;

1328   }

1329   scope->kind = kind;

1330

1331   /* Add it to the front of currently active scopes stack.  */

1332   scope->level_chain = current_binding_level;

1333   current_binding_level = scope;

1334   keep_next_level_flag = false;

1335

1336   if (ENABLE_SCOPE_CHECKING)

1337   {

1338     scope->binding_depth = binding_depth;

1339     indent (binding_depth);

1340     cxx_scope_debug (scope, input_location.line, "push");

1341     is_class_level = 0;

1342     binding_depth++;

1343   }

1344

1345   return scope;

1346 }

 

Being a namespace declaration, field type_decls of cp_binding_level should be created first as the dictionary for user-defined-type. The field is of type of below.

 

29      typedef struct binding_table_s *binding_table;                                           in name-lookup.h

30      typedef struct binding_entry_s *binding_entry;

 

100    struct binding_table_s GTY(())                                                           in name-lookup.c

101    {

102      /* Array of chains of "binding_entry"s  */

103      binding_entry * GTY((length ("%h.chain_count"))) chain;

104   

105      /* The number of chains in this table. This is the length of the

106        the member "chain" considered as an array.  */

107      size_t chain_count;

108   

109      /* Number of "binding_entry"s in this table.  */

110       size_t entry_count;

111     };

 

Notice that chain at line 103 is of type binding_entry_s**.

 

35      struct binding_entry_s GTY(())                                                          in name-lookup.h

36      {

37        binding_entry chain;

38        tree name;

39        tree type;

40      };

 

From the definition of binding_table_s, it can be guessed that chain field will be created as an array, and chain_count and entry_count control its usage. It is really what binding_table_new does.

 

151    static inline binding_table

152    binding_table_new (size_t chain_count)                                              in name-lookup.c

153    {

154      binding_table table = ggc_alloc (sizeof (struct binding_table_s));

155      table->chain = NULL;

156      binding_table_construct (table, chain_count);

157      return table;

158    }

 

115     static inline void

116     binding_table_construct (binding_table table, size_t chain_count)          in name-lookup.c

117     {

118       table->chain_count = chain_count;

119       table->entry_count = 0;

120      table->chain = ggc_alloc_cleared

121        (table->chain_count * sizeof (binding_entry));

122    }

 

Parameter chain_count of above functions is determined by namespace_scope_ht_size.

 

1257   static inline size_t

1258   namespace_scope_ht_size (tree ns)                                                     in name-lookup.c

1259   {

1260     tree name = DECL_NAME (ns);

1261  

1262     return name == std_identifier

1263       ? NAMESPACE_STD_HT_SIZE

1264       : (name == global_scope_name

1265          ? GLOBAL_SCOPE_HT_SIZE

1266          : NAMESPACE_ORDINARY_HT_SIZE);

1267   }

 

In the function, NAMESPACE_STD_HT_SIZE and GLOBAL_SCOPE_HT_SIZE is 1<<8, NAMESPACE_ORDINARY_HT_SIZE is 1<<5.

 

你可能感兴趣的:(struct,function,tree,table,binding,destructor)