5.12.3.2.1.2.1.1.1. 处理函数之前准备数据
接下来,为展开函数体内的语句准备结构体。注意到在 begin_stmt_tree 中的参数 t 指向 RESULT_DECL 的 DECL_SAVED_TREE 域的地址。
67 void
68 begin_stmt_tree (tree *t) in c-semantics.c
69 {
70 /* We create a trivial EXPR_STMT so that last_tree is never NULL in
71 what follows. We remove the extraneous statement in
72 finish_stmt_tree. */
73 *t = build_nt (EXPR_STMT, void_zero_node);
74 last_tree = *t;
75 last_expr_type = NULL_TREE;
76 last_expr_filename = input_filename;
77 }
在处理之前语句链表必须由一个伪 EXPR_STMT 节点结尾。并且这个 EXPR_STMT 节点将在处理完成时移除。在上面, last_* 是访问作用域节点相关域的宏。
300 #define last_tree (current_stmt_tree ()->x_last_stmt) in c-common.h
316 stmt_tree
317 current_stmt_tree (void) in semantics.c
318 {
319 return (cfun
320 ? &cfun ->language->base.x_stmt_tree
321 : &scope_chain ->x_stmt_tree);
322 }
现在,因为是在处理方法, cfun 已经为 start_function 中 10360 行的 allocate_struct_function 所分配。因此在这里,我们先看一下 cfun 的构建。
6434 void
6435 allocate_struct_function (tree fndecl) in function.c
6436 {
6437 tree result;
6438
6439 cfun = ggc_alloc_cleared (sizeof (struct function));
6440
6441 max_parm_reg = LAST_VIRTUAL_REGISTER + 1;
6442
6443 cfun ->stack_alignment_needed = STACK_BOUNDARY;
6444 cfun ->preferred_stack_boundary = STACK_BOUNDARY;
6445
6446 current_function_funcdef_no = funcdef_no ++;
6447
6448 cfun ->function_frequency = FUNCTION_FREQUENCY_NORMAL;
6449
6450 init_stmt_for_function ();
6451 init_eh_for_function ();
6452
6453 (*lang_hooks .function.init ) (cfun );
6454 if (init_machine_status)
6455 cfun ->machine = (*init_machine_status ) ();
6456
6457 if (fndecl == NULL)
6458 return ;
6459
6460 DECL_SAVED_INSNS (fndecl) = cfun ;
6461 cfun ->decl = fndecl;
6462
6463 result = DECL_RESULT (fndecl);
6464 if (aggregate_value_p (result, fndecl))
6465 {
6466 #ifdef PCC_STATIC_STRUCT_RETURN
6467 current_function_returns_pcc_struct = 1;
6468 #endif
6469 current_function_returns_struct = 1;
6470 }
6471
6472 current_function_returns_pointer = POINTER_TYPE_P (TREE_TYPE (result));
6473
6474 current_function_needs_context
6475 = (decl_function_context (current_function_decl ) != 0
6476 && ! DECL_NO_STATIC_CHAIN (current_function_decl ));
6477 }
其细节可参考章节: 评估算术操作的代价 – 创建伪函数上下文 。在这次调用里,参数 fndecl 指向 FUNCTION_DECL 节点。 在上面, init_stmt_for_function 及 init_eh_for_function 仅为 cfun 创建 stmt_status 及 eh_status 的实例。
而在 6453 行,在 C++ 前端中, cxx_push_function_context 被注册到 lang_hooks 中的 function.init 。它初始化用于编译 C++ 函数的变量。
11290 void
11291 cxx_push_function_context (struct function * f) in decl.c
11292 {
11293 struct language_function *p
11294 = ggc_alloc_cleared (sizeof (struct language_function));
11295 f->language = p;
11296
11297 /* Whenever we start a new function, we destroy temporaries in the
11298 usual way. */
11299 current_stmt_tree ()->stmts_are_full_exprs_p = 1;
11300
11301 if (f->decl)
11302 {
11303 tree fn = f->decl;
11304
11305 if (DECL_SAVED_FUNCTION_DATA (fn))
11306 {
11307 /* If we already parsed this function, and we're just expanding it
11308 now, restore saved state. */
11309 *cp_function_chain = *DECL_SAVED_FUNCTION_DATA (fn);
11310
11311 /* If we decided that we didn't want to inline this function,
11312 make sure the back-end knows that. */
11313 if (!current_function_cannot_inline)
11314 current_function_cannot_inline = cp_function_chain->cannot_inline;
11315
11316 /* We don't need the saved data anymore. Unless this is an inline
11317 function; we need the named return value info for
11318 cp_copy_res_decl_for_inlining. */
11319 if (! DECL_INLINE (fn))
11320 DECL_SAVED_FUNCTION_DATA (fn) = NULL;
11321 }
11322 }
11323 }
下面的 cp_function_chain 返回 cfun 的 language 域。
802 #define cp_function_chain (cfun ->language) in cp-tree.h
而 DECL_SAVED_FUNCTION_DATA 返回 FUNCTION_DECL 节点中的域 saved_language_function 的地址,它在该函数完成解析时被填充。但是如果 DECL_SAVED_FUNCTION_DATA 不是 NULL ,这意味着发生了函数重复定义的错误。实际上,参数 f 是在 6439 行新构建的 cfun ,它不满足 11301 行的条件,因此对于 C++ , 11302 至 11322 行的代码不会执行(在当前版本, cxx_push_function_context 只有这一处调用)。为了记录 C++ 函数的状态,定义了以下结构体。
771 struct language_function GTY(()) in cp-tree.h
772 {
773 struct c_language_function base;
774
775 tree x_dtor_label;
776 tree x_current_class_ptr;
777 tree x_current_class_ref;
778 tree x_eh_spec_block;
779 tree x_in_charge_parm;
780 tree x_vtt_parm;
781 tree x_return_value;
782
783 int returns_value;
784 int returns_null;
785 int returns_abnormally;
786 int in_function_try_handler;
787 int in_base_initializer;
788
789 /* True if this function can throw an exception. */
790 BOOL_BITFIELD can_throw : 1;
791
792 struct named_label_use_list *x_named_label_uses;
793 struct named_label_list *x_named_labels;
794 struct cp_binding_level *bindings;
795 varray_type x_local_names;
796
797 const char *cannot_inline;
798 };
因为 C++ 包含 C 的语法,这个结构体包含了 c_language_function 来保存与 C 相关的状态。而其它域专用于 C++ 。
289 struct c_language_function GTY(()) { in c-common.h
290 /* While we are parsing the function, this contains information
291 about the statement-tree that we are building. */
292 struct stmt_tree_s x_stmt_tree;
293 /* The stack of SCOPE_STMTs for the current function. */
294 tree x_scope_stmt_stack;
295 };
为不同的机器产生代码必须考虑机器的特性,为机器产生指令时,需要使用这些信息。
11911 static struct machine_function *
11912 ix86_init_machine_status (void) in i386.c
11913 {
11914 struct machine_function *f;
11915
11916 f = ggc_alloc_cleared (sizeof (struct machine_function));
11917 f->use_fast_prologue_epilogue_nregs = -1;
11918
11919 return f;
11920 }
看到为 x86 机器定义的 machine_function 将记录,在执行函数这一点上,机器的快像( snapshot )。
3167 struct machine_function GTY(()) in i386.h
3168 {
3169 struct stack_local_entry *stack_locals;
3170 const char *some_ld_name;
3171 int save_varrargs_registers;
3172 int accesses_prev_frame;
3173 int optimize_mode_switching;
3174 /* Set by ix86_compute_frame_layout and used by prologue/epilogue expander to
3175 determine the style used. */
3176 int use_fast_prologue_epilogue;
3177 /* Number of saved registers USE_FAST_PROLOGUE_EPILOGUE has been computed
3178 for. */
3179 int use_fast_prologue_epilogue_nregs;
3180 };
下面的 stmt_tree_s 用于保存函数体内的语句。看到在 begin_stmt_tree 的 73 行, x_last_stmt 将是 EXPR_STMT 的链表。
259 struct stmt_tree_s GTY(()) { in c-common.h
260 /* The last statement added to the tree. */
261 tree x_last_stmt;
262 /* The type of the last expression statement. (This information is
263 needed to implement the statement-expression extension.) */
264 tree x_last_expr_type;
265 /* The last filename we recorded. */
266 const char *x_last_expr_filename;
267 /* In C++, Nonzero if we should treat statements as full
268 expressions. In particular, this variable is no-zero if at the
269 end of a statement we should destroy any temporaries created
270 during that statement. Similarly, if, at the end of a block, we
271 should destroy any local variables in this block. Normally, this
272 variable is nonzero, since those are the normal semantics of
273 C++.
274
275 However, in order to represent aggregate initialization code as
276 tree structure, we use statement-expressions. The statements
277 within the statement expression should not result in cleanups
278 being run until the entire enclosing statement is complete.
279
280 This flag has no effect in C. */
281 int stmts_are_full_exprs_p;
282 };
283
284 typedef struct stmt_tree_s *stmt_tree ;
那么在 allocate_struct_function 的 6460 行, DECL_SAVED_INSNS 指向 cfun 。看到当在处理下一个函数时, cfun 将在 6439 行被重新构建,而 DECL_SAVED_INSNS 将是该函数节点的唯一的引用。
进一步的,如果该函数返回聚合类型,需要产生更多的代码来传递其地址,并且可能应用特定的优化。例如:
struct A { … };
A func() { return A(); }
int main() {
A a = func();
}
一个优化的机会就是使得 func 直接操控 a 。
简而言之,返回聚合类型的函数需要特殊的处理,这里由 aggregate_value_p 把它们找出来,并标记它。这个函数我们稍后再看。
start_function (continue)
10373 /* Let the user know we're compiling this function. */
10374 announce_function (decl1);
10375
10376 /* Record the decl so that the function name is defined.
10377 If we already have a decl for this name, and it is a FUNCTION_DECL,
10378 use the old decl. */
10379 if (!processing_template_decl && !(flags & SF_PRE_PARSED))
10380 {
…
10405 }
10406
10407 /* Reset these in case the call to pushdecl changed them. */
10408 current_function_decl = decl1;
10409 cfun ->decl = decl1;
10410
10411 /* If we are (erroneously) defining a function that we have already
10412 defined before, wipe out what we knew before. */
10413 if (!DECL_PENDING_INLINE_P (decl1))
10414 DECL_SAVED_FUNCTION_DATA (decl1) = NULL;
10415
10416 if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
10417 {
10418 /* We know that this was set up by `grokclassfn'. We do not
10419 wait until `store_parm_decls', since evil parse errors may
10420 never get us to that point. Here we keep the consistency
10421 between `current_class_type' and `current_class_ptr'. */
10422 tree t = DECL_ARGUMENTS (decl1);
10423
10424 my_friendly_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL,
10425 162);
10426 my_friendly_assert (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE,
10427 19990811);
10428
10429 cp_function_chain->x_current_class_ref
10430 = build_indirect_ref (t, NULL);
10431 cp_function_chain->x_current_class_ptr = t;
10432
10433 /* Constructors and destructors need to know whether they're "in
10434 charge" of initializing virtual base classes. */
10435 t = TREE_CHAIN (t);
10436 if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
10437 {
10438 current_in_charge_parm = t;
10439 t = TREE_CHAIN (t);
10440 }
10441 if (DECL_HAS_VTT_PARM_P (decl1))
10442 {
10443 if (DECL_NAME (t) != vtt_parm_identifier)
10444 abort ();
10445 current_vtt_parm = t;
10446 }
10447 }
上面在 10374 行 , announce_function 仅打印出将要编译的函数的信息。在 10416 行 , 如果 ctype 不是 NULL , 可以确认正在处理方法 ( method ) 。并且如果方法不是静态的 , 那么在 10422 行的 DECL_ARGUMENTS 将返回 “ const this* ” 。为了可以快速地访问这个“ this ”实例,最好把这个引用及指针保存在 function 结构体里。这就是 10429 及 10431 行的 x_current_class_ref 和 x_current_class_ptr 的目的。
引用由下面的函数来构建。
2082 tree
2083 build_indirect_ref (tree ptr, const char *errorstring) in typeck.c
2084 {
2085 tree pointer, type;
2086
2087 if (ptr == error_mark_node)
2088 return error_mark_node;
2089
2090 if (ptr == current_class_ptr)
2091 return current_class_ref;
2092
2093 pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE
2094 ? ptr : decay_conversion (ptr));
2095 type = TREE_TYPE (pointer);
2096
2097 if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE)
2098 {
2099 /* [expr.unary.op]
2100
2101 If the type of the expression is "pointer to T," the type
2102 of the result is "T."
2103
2104 We must use the canonical variant because certain parts of
2105 the back end, like fold, do pointer comparisons between
2106 types. */
2107 tree t = canonical_type_variant (TREE_TYPE (type));
2108
2109 if (VOID_TYPE_P (t))
2110 {
2111 /* A pointer to incomplete type (other than cv void) can be
2112 dereferenced [expr.unary.op]/1 */
2113 error ("`%T' is not a pointer-to-object type", type);
2114 return error_mark_node;
2115 }
2116 else if (TREE_CODE (pointer) == ADDR_EXPR
2117 && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0))))
2118 /* The POINTER was something like `&x'. We simplify `*&x' to
2119 `x'. */
2120 return TREE_OPERAND (pointer, 0);
2121 else
2122 {
2123 tree ref = build1 (INDIRECT_REF, t, pointer);
2124
2125 /* We *must* set TREE_READONLY when dereferencing a pointer to const,
2126 so that we get the proper error message if the result is used
2127 to assign to. Also, &* is supposed to be a no-op. */
2128 TREE_READONLY (ref) = CP_TYPE_CONST_P (t);
2129 TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t);
2130 TREE_SIDE_EFFECTS (ref)
2131 = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer));
2132 return ref;
2133 }
2134 }
2135 /* `pointer' won't be an error_mark_node if we were given a
2136 pointer to member, so it's cool to check for this here. */
2137 else if (TYPE_PTR_TO_MEMBER_P (type))
2138 error ("invalid use of `%s' on pointer to member", errorstring);
2139 else if (pointer != error_mark_node)
2140 {
2141 if (errorstring)
2142 error ("invalid type argument of `%s'", errorstring);
2143 else
2144 error ("invalid type argument");
2145 }
2146 return error_mark_node;
2147 }
上面在 2094 行, decay_conversion 不做任何事情,仅返回 ptr – “ const this* ”的 PARM_DECL 节点。而在 2107 行, canonical_type_variant 仅是 cp_build_qualified_type 的简单封装,它创建了 cv-qualifier 的限定类型。
start_function (continue)
10449 if (DECL_INTERFACE_KNOWN (decl1))
10450 {
10451 tree ctx = decl_function_context (decl1);
10452
10453 if (DECL_NOT_REALLY_EXTERN (decl1))
10454 DECL_EXTERNAL (decl1) = 0;
10455
10456 if (ctx != NULL_TREE && DECL_DECLARED_INLINE_P (ctx)
10457 && TREE_PUBLIC (ctx))
10458 /* This is a function in a local class in an extern inline
10459 function. */
10460 comdat_linkage (decl1);
10461 }
10462 /* If this function belongs to an interface, it is public.
10463 If it belongs to someone else's interface, it is also external.
10464 This only affects inlines and template instantiations. */
10465 else if (interface_unknown == 0
10466 && ! DECL_TEMPLATE_INSTANTIATION (decl1))
10467 {
10468 if (DECL_DECLARED_INLINE_P (decl1)
10469 || DECL_TEMPLATE_INSTANTIATION (decl1)
10470 || processing_template_decl )
10471 {
10472 DECL_EXTERNAL (decl1)
10473 = (interface_only
10474 || (DECL_DECLARED_INLINE_P (decl1)
10475 && ! flag_implement_inlines
10476 && !DECL_VINDEX (decl1)));
10477
10478 /* For WIN32 we also want to put these in linkonce sections. */
10479 maybe_make_one_only (decl1);
10480 }
10481 else
10482 DECL_EXTERNAL (decl1) = 0;
10483 DECL_NOT_REALLY_EXTERN (decl1) = 0;
10484 DECL_INTERFACE_KNOWN (decl1) = 1;
10485 }
10486 else if (interface_unknown && interface_only
10487 && ! DECL_TEMPLATE_INSTANTIATION (decl1))
10488 {
10489 /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma
10490 interface, we will have interface_only set but not
10491 interface_known. In that case, we don't want to use the normal
10492 heuristics because someone will supply a #pragma implementation
10493 elsewhere, and deducing it here would produce a conflict. */
10494 comdat_linkage (decl1);
10495 DECL_EXTERNAL (decl1) = 0;
10496 DECL_INTERFACE_KNOWN (decl1) = 1;
10497 DECL_DEFER_OUTPUT (decl1) = 1;
10498 }
10499 else
10500 {
10501 /* This is a definition, not a reference.
10502 So clear DECL_EXTERNAL. */
10503 DECL_EXTERNAL (decl1) = 0;
10504
10505 if ((DECL_DECLARED_INLINE_P (decl1)
10506 || DECL_TEMPLATE_INSTANTIATION (decl1))
10507 && ! DECL_INTERFACE_KNOWN (decl1)
10508 /* Don't try to defer nested functions for now. */
10509 && ! decl_function_context (decl1))
10510 DECL_DEFER_OUTPUT (decl1) = 1;
10511 else
10512 DECL_INTERFACE_KNOWN (decl1) = 1;
10513 }
上面关于 interface_unknown 及 interface_only ,其细节参考章节 #pragma interface及 #pragma implementation 。对于我们的例子,没有使用“ #pragma interface ”及“ #pragma implementation ”,因此满足 10499 行。
5.12.3.2.1.2.1.1.2. 加入函数作用域
在退出该函数前,需要使所处理的函数作用域生效。注意到 sk_function_parms 专指包含函数参数的作用域。
start_function (continue)
10515 begin_scope (sk_function_parms, decl1);
10516
10517 ++function_depth ;
10518
10519 if (DECL_DESTRUCTOR_P (decl1))
10520 {
10521 dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);
10522 DECL_CONTEXT (dtor_label) = current_function_decl ;
10523 }
10524
10525 start_fname_decls ();
10526
10527 store_parm_decls (current_function_parms);
10528
10529 return 1;
10530 }
然后前端需要设立代表函数名的标识符,【 6 】给出如下细节:
5.43 函数名字符串
GCC 提供了三个魔术变量来保存作为当前函数名字的字符串。第一个是 __func__ ,它是 C99 标准的一部分:
标识符 __func__ 是由编译器隐式声明的,就仿佛直接跟在每个函数定义的开大括号后面的声明:
static const char __func__[] = "function-name";
此处 function-name 是词法意义上封闭的函数( the lexically-enclosing function )的名字。这个名字是未修饰的函数名。
__FUNCTION__ 是对应 __func__ 的另一个名字。旧版本的 GCC 只能识别这个名字。不过,它不是标准的。为了达到最大可移植性,建议使用 __func__ ,不过要通过预处理器提供一个后备定义:
#if __STDC_VERSION__ < 199901L
# if __GNUC__ >= 2
# define __func__ __FUNCTION__
# else
# define __func__ "<unknown>"
# endif
#endif
在 C 中, __PRETTY_FUNCTION__ 则是对应 __func__ 的另一个名字。不过,在 C++ 中, __RETTY_FUNCTION__ 除了基本的名字( bare name ),还包含了函数的类型签名( type signature )。例如,程序:
extern "C" {
extern int printf (char *, ...);
}
class a {
public :
void sub (int i) {
printf ("__FUNCTION__ = %s/n", __FUNCTION__);
printf ("__PRETTY_FUNCTION__ = %s/n", __PRETTY_FUNCTION__);
}
};
int
main (void) {
a ax;
ax.sub (0);
return 0;
}
给出输出:
__FUNCTION__ = sub
__PRETTY_FUNCTION__ = void a::sub(int)
这些标识符都不是预处理宏。在 GCC 3.3 及更早的版本,仅在 C 里, __FUNCTION__ 及 __PRETTY_FUNCTION__ 被处理作字符串;它们可以被用作字符数组的初始值,并且可以与其他字符串串接起来。 GCC 3.4 及更新的版本把它们处理作变量,比如 __func__ 。在 C++ 中, __FUNCTION__ 及 __PRETTY_FUNCTION__ 一直是变量。
991 void
992 start_fname_decls (void) in c-common.c
993 {
994 unsigned ix;
995 tree saved = NULL_TREE;
996
997 for (ix = 0; fname_vars [ix].decl; ix++)
998 {
999 tree decl = *fname_vars [ix].decl;
1000
1001 if (decl)
1002 {
1003 saved = tree_cons (decl, build_int_2 (ix, 0), saved);
1004 *fname_vars [ix].decl = NULL_TREE;
1005 }
1006 }
1007 if (saved || saved_function_name_decls)
1008 /* Normally they'll have been NULL, so only push if we've got a
1009 stack, or they are non-NULL. */
1010 saved_function_name_decls = tree_cons (saved, NULL_TREE,
1011 saved_function_name_decls);
1012 }
如上面所提及的,在高于 v3.4 的编译器中, __func__ , ___FUNCTION__ 及 __PRETTY_FUNCTION__ 都被实现作标识符。结构体 fname_var_t 保存这些标识符的信息。
689 struct fname_var_t in c-common.c
690 {
691 tree *const decl; /* pointer to the VAR_DECL. */
692 const unsigned rid; /* RID number for the identifier. */
693 const int pretty; /* How pretty is it? */
694 };
695
696 /* The three ways of getting then name of the current function. */
697
698 const struct fname_var_t fname_vars [] =
699 {
700 /* C99 compliant __func__, must be first. */
701 {&c99_function_name_decl_node, RID_C99_FUNCTION_NAME, 0},
702 /* GCC __FUNCTION__ compliant. */
703 {&function_name_decl_node, RID_FUNCTION_NAME, 0},
704 /* GCC __PRETTY_FUNCTION__ compliant. */
705 {&pretty_function_name_decl_node, RID_PRETTY_FUNCTION_NAME, 1},
706 {NULL, 0, 0},
707 };
显然,这些标识符必须是全局可见并且唯一,因此它们实际上被声明在 c_global_trees 里,并且具有 RID 标签来标记为由解析器识别的特殊符号(类似保留字)。注意其中的 decl 域, c99_function_name_decl_node , function_name_decl_node , pretty_function_name_decl_node 更像占位符,它们都是空指针。
因此看到在 start_fname_decl 的 1004 行,如果 fname_vars 中的 decl 不是 NULL ,这意味着在调用函数中使用了 __func__ 等,那么在进入被调用函数前,其内容需要被被缓存到全局栈 saved_function_name_decls 中。当从被调用函数返回时,这个保存的 decl 将被恢复入 fname_vars 中,使其在调用函数余下部分可用。
当该函数域成为 current_binding_level ,需要把其参数加入该作用域,使得随后的名字查找可以找出正确的项。现在 current_function_parms 指向该函数的参数链表。
10538 static void
10539 store_parm_decls (tree current_function_parms) in decl.c
10540 {
10541 tree fndecl = current_function_decl ;
10542 tree parm;
10543
10544 /* This is a chain of any other decls that came in among the parm
10545 declarations. If a parm is declared with enum {foo, bar} x;
10546 then CONST_DECLs for foo and bar are put here. */
10547 tree nonparms = NULL_TREE;
10548
10549 if (current_function_parms)
10550 {
10551 /* This case is when the function was defined with an ANSI prototype.
10552 The parms already have decls, so we need not do anything here
10553 except record them as in effect
10554 and complain if any redundant old-style parm decls were written. */
10555
10556 tree specparms = current_function_parms;
10557 tree next;
10558
10559 /* Must clear this because it might contain TYPE_DECLs declared
10560 at class level. */
10561 current_binding_level ->names = NULL;
10562
10563 /* If we're doing semantic analysis, then we'll call pushdecl
10564 for each of these. We must do them in reverse order so that
10565 they end in the correct forward order. */
10566 specparms = nreverse (specparms);
10567
10568 for (parm = specparms; parm; parm = next)
10569 {
10570 next = TREE_CHAIN (parm);
10571 if (TREE_CODE (parm) == PARM_DECL)
10572 {
10573 if (DECL_NAME (parm) == NULL_TREE
10574 || TREE_CODE (parm) != VOID_TYPE)
10575 pushdecl (parm);
10576 else
10577 error ("parameter `%D' declared void", parm);
10578 }
10579 else
10580 {
10581 /* If we find an enum constant or a type tag,
10582 put it aside for the moment. */
10583 TREE_CHAIN (parm) = NULL_TREE;
10584 nonparms = chainon (nonparms, parm);
10585 }
10586 }
10587
10588 /* Get the decls in their original chain order and record in the
10589 function. This is all and only the PARM_DECLs that were
10590 pushed into scope by the loop above. */
10591 DECL_ARGUMENTS (fndecl) = getdecls ();
10592 }
10593 else
10594 DECL_ARGUMENTS (fndecl) = NULL_TREE;
10595
10596 /* Now store the final chain of decls for the arguments
10597 as the decl-chain of the current lexical scope.
10598 Put the enumerators in as well, at the front so that
10599 DECL_ARGUMENTS is not modified. */
10600 current_binding_level ->names = chainon (nonparms, DECL_ARGUMENTS (fndecl));
10601
10602 /* Do the starting of the exception specifications, if we have any. */
10603 if (flag_exceptions && ! processing_template_decl
10604 && flag_enforce_eh_specs
10605 && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl )))
10606 current_eh_spec_block = begin_eh_spec_block ();
10607 }
这里在 10573 及 10574 行,再一次验证参数,如果参数是有效的,通过我们的老朋友 pushdecl 把它加入函数域。而在这一点上 current_function_decl 指向方法的 FUNCTION_DECL 节点。对于每个参数,以相反的次序调用 pushdecl 。因此对于第一次调用,“ const Host& ”的 PARM_DECL 节点是无名的。
566 tree
567 pushdecl (tree x) in name-lookup.c
568 {
569 tree t;
570 tree name;
571 int need_new_binding;
572
573 timevar_push (TV_NAME_LOOKUP);
574
575 need_new_binding = 1;
576
577 if (DECL_TEMPLATE_PARM_P (x))
578 /* Template parameters have no context; they are not X::T even
579 when declared within a class or namespace. */
580 ;
581 else
582 {
583 if (current_function_decl && x != current_function_decl
584 /* A local declaration for a function doesn't constitute
585 nesting. */
586 && TREE_CODE (x) != FUNCTION_DECL
587 /* A local declaration for an `extern' variable is in the
588 scope of the current namespace, not the current
589 function. */
590 && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
591 && !DECL_CONTEXT (x))
592 DECL_CONTEXT (x) = current_function_decl ;
593
594 /* If this is the declaration for a namespace-scope function,
595 but the declaration itself is in a local scope, mark the
596 declaration. */
597 if (TREE_CODE (x) == FUNCTION_DECL
598 && DECL_NAMESPACE_SCOPE_P (x)
599 && current_function_decl
600 && x != current_function_decl )
601 DECL_LOCAL_FUNCTION_P (x) = 1;
602 }
603
604 name = DECL_NAME (x);
605 if (name)
606 {
…
1007 }
1008
1009 if (need_new_binding)
1010 add_decl_to_level (x,
1011 DECL_NAMESPACE_SCOPE_P (x)
1012 ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
1013 : current_binding_level );
1014
1015 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
1016 }
因为参数是无名的,因此没有 cxx_binding 节点为这个参数创建,仅把它记录在 FUNCTION_DECL 的 names 域中。
( 点此打开 )
图 92 :加入“ const Host& ”的 PARM_DECL
对于我们的例子,最后一个处理的参数是“ const this* ”,它具有名字“ this ”。毫无疑问,“ this ”具有一个对应的 IDNETIFIER_NODE ,并且它需要被绑定入这个作用域。为了方便起见,我们在下面重新贴出 pushdecl 中相关的代码。可以看到加入具名参数与加入其它 DECL 节点没有什么不同。
566 tree
567 pushdecl (tree x) in name-lookup.c
568 {
569 tree t;
570 tree name;
571 int need_new_binding;
572
573 timevar_push (TV_NAME_LOOKUP);
574
575 need_new_binding = 1;
576
577 if (DECL_TEMPLATE_PARM_P (x))
578 /* Template parameters have no context; they are not X::T even
579 when declared within a class or namespace. */
580 ;
581 else
582 {
583 if (current_function_decl && x != current_function_decl
584 /* A local declaration for a function doesn't constitute
585 nesting. */
586 && TREE_CODE (x) != FUNCTION_DECL
587 /* A local declaration for an `extern' variable is in the
588 scope of the current namespace, not the current
589 function. */
590 && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
591 && !DECL_CONTEXT (x))
592 DECL_CONTEXT (x) = current_function_decl ;
593
594 /* If this is the declaration for a namespace-scope function,
595 but the declaration itself is in a local scope, mark the
596 declaration. */
597 if (TREE_CODE (x) == FUNCTION_DECL
598 && DECL_NAMESPACE_SCOPE_P (x)
599 && current_function_decl
600 && x != current_function_decl )
601 DECL_LOCAL_FUNCTION_P (x) = 1;
602 }
603
604 name = DECL_NAME (x);
605 if (name)
606 {
607 int different_binding_level = 0;
608
609 if (TREE_CODE (x) == FUNCTION_DECL || DECL_FUNCTION_TEMPLATE_P (x))
610 check_default_args (x);
611
612 if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
613 name = TREE_OPERAND (name, 0);
614
615 /* In case this decl was explicitly namespace-qualified, look it
616 up in its namespace context. */
617 if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
618 t = namespace_binding (name, DECL_CONTEXT (x));
619 else
620 t = lookup_name_current_level (name);
...
743 check_template_shadow (x);
...
828 /* This name is new in its binding level.
829 Install the new declaration and return it. */
830 if ( namespace_bindings_p ())
831 {
...
872 }
873 else
874 {
875 /* Here to install a non-global value. */
876 tree oldlocal = IDENTIFIER_VALUE (name);
877 tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
878
879 if (need_new_binding)
880 {
881 push_local_binding (name, x, 0);
882 /* Because push_local_binding will hook X on to the
883 current_binding_level's name list, we don't want to
884 do that again below. */
885 need_new_binding = 0;
886 }
...
898 if (oldlocal)
899 {
900 tree d = oldlocal;
901
902 while (oldlocal
903 && TREE_CODE (oldlocal) == VAR_DECL
904 && DECL_DEAD_FOR_LOCAL (oldlocal))
905 oldlocal = DECL_SHADOWED_FOR_VAR (oldlocal);
906
907 if (oldlocal == NULL_TREE)
908 oldlocal = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (d));
909 }
910
911 /* If this is an extern function declaration, see if we
912 have a global definition or declaration for the function. */
913 if (oldlocal == NULL_TREE
914 && DECL_EXTERNAL (x)
915 && oldglobal != NULL_TREE
916 && TREE_CODE (x) == FUNCTION_DECL
917 && TREE_CODE (oldglobal) == FUNCTION_DECL)
918 {
…
927 }
928 /* If we have a local external declaration,
929 and no file-scope declaration has yet been seen,
930 then if we later have a file-scope decl it must not be static. */
931 if (oldlocal == NULL_TREE
932 && oldglobal == NULL_TREE
933 && DECL_EXTERNAL (x)
934 && TREE_PUBLIC (x))
935 TREE_PUBLIC (name) = 1;
936
937 /* Warn if shadowing an argument at the top level of the body. */
938 if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x)
939 /* Inline decls shadow nothing. */
940 && !DECL_FROM_INLINE (x)
941 && TREE_CODE (oldlocal) == PARM_DECL
942 /* Don't check the `this' parameter. */
943 && !DECL_ARTIFICIAL (oldlocal))
944 {
…
971 }
972
973 /* Maybe warn if shadowing something else. */
974 else if (warn_shadow && !DECL_EXTERNAL (x)
975 /* No shadow warnings for internally generated vars. */
976 && ! DECL_ARTIFICIAL (x)
977 /* No shadow warnings for vars made for inlining. */
978 && ! DECL_FROM_INLINE (x))
979 {
…
1002 }
1003 }
1004
1005 if (TREE_CODE (x) == VAR_DECL)
1006 maybe_register_incomplete_var (x);
1007 }
1008
1009 if (need_new_binding)
1010 add_decl_to_level (x,
1011 DECL_NAMESPACE_SCOPE_P (x)
1012 ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
1013 : current_binding_level);
1014
1015 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
1016 }
上面在 881 行, push_local_binding 构建了 cxx_binding 节点,并且利用它把这个 IDENTIFIER_NODE 绑定在这个作用域中。当该标识符在代码中出现多于一次时,需要检查是否会引入危险。上面 876 行, IDENTIFIER_VALUE 返回在非名字空间作用域中的最后的同名声明,而 IDENTIFIER_NAMESPACE_VALUE 返回在最里层的起效名字空间作用域中的最后的同名声明。 那么 在 902 行, WHILE 循环跳过了声明在局部块(比如, FOR 块)中的变量。在 908 行,如果没有找到不在名字空间及局部块中的声明, oldlocal 将得到在名字空间作用域中的声明。参数“ const this* ”是由前端产生的,它设置了 DECL_ARTIFICIAL 标记。接着,通过 getdecls 更新 FUNCTION_DECL 的 arguments 域为绑定在该作用域的名字。
1533 tree
1534 getdecls (void) in name-lookup.c
1535 {
1536 return current_binding_level ->names;
1537 }
那么我们将得到如下的图形。注意,在 PARM_DECL 节点中的“ this ”表示对应的 IDENTIFIER_NODE 。从“ this ”到 cxx_binding 的连线,表示 IDENTIFIER_BINDING 。
( 点此打开 )
图 93 :加入“ const this* ”的 PARM_DECL