全局名字空间的标识符是global_scope_name,其对应的树节点的编码是NAMESPACE_DECL,名字空间本身没有类型信息,是故下面的参数type为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 }
对于每个声明,都有一个伴随的tree_decl节点。因为声明是语言的一部分,在tree_decl的定义中我们可以看到以下域。
1647 struct tree_decl GTY(())
1648 {
...
1748 struct lang_decl *lang_specific;
1749 };
域lang_decl记录了语言的信息。对于C++,lang_decl的定义如下:
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 };
看到lang_decl_flags是lang_decl的第一个成员。因此这2个类型可以互换使用,不过要注意不要越过lang_decl_flags的边界,如果将它作为lang_decl来处理。1682行lang_decl_flags中的域can_be_full指出节点为何种,lang_decl_flags或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 };
注意上面形如u[num]sel的域,如果非零表示在lang_decl/lang_decl_flags 中域lang_decl_u[num]被使用。
这个复杂的结构体由retrofit_lang_decl,根据声明的类型,创建及初始化。
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告知为tree_decl 的lang_specific使用那个类型。
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)
可知lang_decl_u1用于名字空间声明,lang_decl_u3用于函数声明。
当期望一个新的作用域时,begin_scope被调用以创建这个作用域,并置于当前活动的作用域栈顶。
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 }
作为一个名字空间声明,cp_binding_level中的域type_decls首先被创建,它将作为用户定义类型的字典。其声明及类型定义如下。
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 };
注意103行的chain具有类型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 };
从binding_table_s的定义,可以猜到域chain将是一个数组,而chain_count及entry_count用于控制其使用。而这正是binding_table_new所做的。
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 }
上面函数的参数chain_count由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 }
在这个函数中,NAMESPACE_STD_HT_SIZE及GLOBAL_SCOPE_HT_SIZE是1<<8, NAMESPACE_ORDINARY_HT_SIZE是1<<5。