Studying note of GCC-3.4.6 source (108)
来源:互联网 发布:淘宝定贝排名在线查询 编辑:程序博客网 时间:2024/05/21 14:46
5.12.3.2.1.2.1.1.1. Prepare databefore function handling
Next, it prepares structure for expanding statements within thebody. Notice that argument t in begin_stmt_tree refers to the address offield DECL_SAVED_TREE of the RESULT_DECL.
67 void
68 begin_stmt_tree (tree *t) inc-semantics.c
69 {
70 /*We create a trivial EXPR_STMT so that last_tree is never NULL in
71 whatfollows. 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 }
The chain of statements must be ended by a fake EXPR_STMT beforeprocessing. And this EXPR_STMT will be removed when the process finished.Above, last_* are macros accessing relevant fields of the binding scope.
300 #define last_tree (current_stmt_tree()->x_last_stmt) inc-common.h
316 stmt_tree
317 current_stmt_tree (void) insemantics.c
318 {
319 return(cfun
320 ? &cfun->language->base.x_stmt_tree
321 : &scope_chain->x_stmt_tree);
322 }
Now, as it is handling method, cfun is already allocated in allocate_struct_function atline 10360 in start_function.So here, we see what cfun looks like.
6434 void
6435 allocate_struct_function (tree fndecl) infunction.c
6436 {
6437 tree result;
6438
6439 cfun = ggc_alloc_cleared (sizeof (structfunction));
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 }
Refer to section Evaluate cost forarithmatic operatoins – Create dummy function context for some details. Forthe invocation, the argument fndecl points to the node FUNCTION_DECL. Above, init_stmt_for_functionand init_eh_for_functionjust create instance of stmt_status and eh_status for cfun.
Then at line 6453, for C++ front-end, cxx_push_function_context isregistered into function.initwithinlang_hooks. It initializes the variables used during compilation ofa C++ function.
11290 void
11291 cxx_push_function_context (struct function * f) indecl.c
11292 {
11293 structlanguage_function *p
11294 = ggc_alloc_cleared (sizeof (structlanguage_function));
11295 f->language = p;
11296
11297 /*Whenever we start a new function, we destroy temporaries in the
11298 usualway. */
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 }
Below cp_function_chainreturns field languageof cfun.
802 #define cp_function_chain (cfun->language) in cp-tree.h
Then DECL_SAVED_FUNCTION_DATA returns the address of saved_language_functionfor the FUNCTION_DECL, which is filled when finishes parsing the function. However,if DECL_SAVED_FUNCTION_DATA is not null, it means there is an error of functionredefinition. In fact, argument f is cfun created at line 6439, which doesn’tsatisfy condition at line 11301, so for C++, code from line 11302 to 11320 won’tbe run (in current version, it is the only point to invoke cxx_push_function_context).To record status of function for the C++ language, below structure is defined.
771 struct language_function GTY(()) in cp-tree.h
772 {
773 structc_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 structnamed_label_use_list *x_named_label_uses;
793 structnamed_label_list *x_named_labels;
794 structcp_binding_level *bindings;
795 varray_type x_local_names;
796
797 constchar *cannot_inline;
798 };
As C++ accommendates grammar of C, the structure containsc_language_function to hold status of C relevant. And other fields are for C++solely.
289 struct c_language_function GTY(()) { inc-common.h
290 /*While we are parsing the function, this contains information
291 aboutthe statement-tree that we are building. */
292 structstmt_tree_s x_stmt_tree;
293 /*The stack of SCOPE_STMTs for the current function. */
294 tree x_scope_stmt_stack;
295 };
Also, generating code for different machine must take thecharacteristic of machine into account, and this information should be usedduring instruction emission for the machine.
11911 static struct machine_function *
11912 ix86_init_machine_status (void) ini386.c
11913 {
11914 structmachine_function *f;
11915
11916 f = ggc_alloc_cleared (sizeof (structmachine_function));
11917 f->use_fast_prologue_epilogue_nregs= -1;
11918
11919 returnf;
11920 }
See that machine_function defined for x86 machine will record thesnapshot of the machine at point executing the function.
3167 struct machine_function GTY(()) in i386.h
3168 {
3169 structstack_local_entry *stack_locals;
3170 constchar *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 intuse_fast_prologue_epilogue;
3177 /*Number of saved registers USE_FAST_PROLOGUE_EPILOGUE has been computed
3178 for. */
3179 intuse_fast_prologue_epilogue_nregs;
3180 };
Below stmt_tree_s is used to store the statements within infunction. See that at line 73 in begin_stmt_tree, x_last_stmt will be the chain ofEXPR_STMT.
259 struct stmt_tree_s GTY(()) { inc-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 neededto implement the statement-expression extension.) */
264 tree x_last_expr_type;
265 /*The last filename we recorded. */
266 constchar *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 ofa statement we should destroy any temporaries created
270 during that statement. Similarly, if, at theend of a block, we
271 shoulddestroy 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 treestructure, we use statement-expressions. The statements
277 withinthe statement expression should not result in cleanups
278 beingrun until the entire enclosing statement is complete.
279
280 Thisflag has no effect in C. */
281 int stmts_are_full_exprs_p;
282 };
283
284 typedef struct stmt_tree_s *stmt_tree;
Then at line 6460 in allocate_struct_function, DECL_SAVED_INSNSpoints to cfun.See that when handling next function, cfun will be recreated at line 6439, andDECL_SAVED_INSNS will be the solely reference to this function instance.
Further, if the function returns aggregate type, more code needs begenerated to pass address instead, and certain optimization may be applied. Forexample:
struct A { … };
A func() { return A(); }
int main() {
A a = func();
}
An opportunity of optimization is to make func to manipulate adirectly.
In short, function returning aggregate type needs speciallyhandling, here find out them by aggregate_value_p which we will see later.
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 wealready have a decl for this name, and it is a FUNCTION_DECL,
10378 usethe 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 evilparse errors may
10420 never get us to that point. Here we keep theconsistency
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 anddestructors need to know whether they're "in
10434 charge" of initializing virtual baseclasses. */
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 }
Above at line 10374, announce_function just prints out the messageabout going to compile the function. At line 10416, if ctype is not NULL, it ensures thatit is processing method. And if the method is not static, then DECL_ARGUMENTSat line 10422 returns “const this*”. To tell out method from function and forquick accessing the “this” instance, it is better to save the reference andpointer within the function structure. That is why we see x_current_class_refand x_current_class_ptrat line 10429 and 10431.
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 returnerror_mark_node;
2089
2090 if (ptr ==current_class_ptr)
2091 returncurrent_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 Ifthe type of the expression is "pointer to T," the type
2102 ofthe result is "T."
2103
2104 Wemust use the canonical variant because certain parts of
2105 theback 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 nota pointer-to-object type", type);
2114 returnerror_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 returnTREE_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 sothat we get the proper error message if the result is used
2127 toassign 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 returnref;
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 useof `%s' on pointer to member", errorstring);
2139 else if (pointer != error_mark_node)
2140 {
2141 if (errorstring)
2142 error ("invalidtype argument of `%s'", errorstring);
2143 else
2144 error ("invalid type argument");
2145 }
2146 returnerror_mark_node;
2147 }
Above at line 2094, decay_conversion does nothing but justreturns ptr- the node of PARM_DECL of “const this*”. And at line 2107, canonical_type_variantis just a simple wrapper of cp_build_qualified_type to createcv-qualifier qualified type
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 itbelongs to someone else's interface, it is also external.
10464 Thisonly 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 wealso 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 butnot
10491 interface_known. In that case, we don't wantto use the normal
10492 heuristics because someone will supply a#pragma implementation
10493 elsewhere, and deducing it here would producea 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 Soclear 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 todefer nested functions for now. */
10509 && ! decl_function_context (decl1))
10510 DECL_DEFER_OUTPUT (decl1)= 1;
10511 else
10512 DECL_INTERFACE_KNOWN(decl1) = 1;
10513 }
Refers to section #pragmainterface & #pragma implementation for the details. For our example,without specifying “#pragma interface” and “#pragma implementation”, conditionat line 10499 is satisfied.
5.12.3.2.1.2.1.1.2. Push functionscope
Before exitting the routine, it should push the scope of the functioninto effect. Notice that sk_function_parms specifies that the scopecontaining function parameters.
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 return1;
10530 }
Then the front-end needs setup following identifers, [6] gives thedetails:
5.43 Function Names asStrings
GCC provides three magic variables which hold the name of thecurrent function, as a string. The first of these is __func__, which is part ofthe C99 standard:
The identifier __func__ is implicitly declared by the translator asif, immediately following the opening brace of each function definition, thedeclaration
static constchar __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosingfunction. This name is the unadorned name of the function.
__FUNCTION__ is another name for __func__. Older versions of GCCrecognize only this name. However, it is not standardized. For maximumportability, we recommend you use __func__, but provide a fallback definitionwith the preprocessor:
#if __STDC_VERSION__ <199901L
# if __GNUC__ >= 2
# define __func____FUNCTION__
# else
# define __func__"<unknown>"
# endif
#endif
In C, __PRETTY_FUNCTION__ is yet another name for __func__. However,in C++, __RETTY_FUNCTION__ contains the type signature of the function as wellas its bare name. For example, this program:
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;
}
gives this output:
__FUNCTION__ =sub
__PRETTY_FUNCTION__= void a::sub(int)
These identifiers are not preprocessor macros. In GCC 3.3 andearlier, in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as stringliterals; they could be used to initialize char arrays, and they could beconcatenated with other string literals. GCC 3.4 and later treat them asvariables, like __func__. In C++, __FUNCTION__ and __PRETTY_FUNCTION__ havealways been variables.
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 }
As mentioned above, __func__, ___FUNCTION__ and __PRETTY_FUNCTION__are all implmented as identifiers after v3.4. Struct fname_var_t carries theinformation of these identifiers.
689 struct fname_var_t in c-common.c
690 {
691 tree *const decl; /* pointer to the VAR_DECL. */
692 constunsigned rid; /*RID number for the identifier. */
693 constint pretty; /*How pretty is it? */
694 };
695
696 /* The three ways of getting then name of thecurrent 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 };
Of course, these identifiers must be global visible and unique, sothey are in fact declared within c_global_trees, and with associated RID tagmarked as a special token (like reserved words) recognized by parser. Note thatc99_function_name_decl_node,function_name_decl_node,pretty_function_name_decl_nodeare more like placeholder. They are all null pointer.
So see that at line 1004 in start_fname_decl, if decl of fname_vars is non-null, which meansusing __func__ etc in the caller function, then at time entering the calleefunction, it should be cached within global stack of saved_function_name_decls. And whenexitting from the callee function, the cached decl would be restored to make itusablein the rest of caller function.
When the function scope becomes the current_binding_level, it needs topush the parameters into the scope so later name-lookup can find out the properitem. Now current_function_parmsrefers to the chain of the parameters of the function.
10538 static void
10539 store_parm_decls (tree current_function_parms) indecl.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 thenCONST_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 Theparms already have decls, so we need not do anything here
10553 except record them as in effect
10554 andcomplain 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 atclass 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 inreverse order so that
10565 theyend 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 thedecl-chain of the current lexical scope.
10598 Putthe 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 }
Here at line 10573 and 10574, validates the parameters again, if theparameter is valid, pushes it into the function scope by our old friend pushdecl.And at this point current_function_decl refers to the FUNCTION_DECL of themethod. For every parameter, pushdecl is invoked in reverse order. So forfirst invocation, the PARM_DECL of “const Host&” is nameless.
566 tree
567 pushdecl (tree x) inname-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 whendeclared 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 thedeclaration 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 }
As theparameter is nameless, so no cxx_binding node is created for the parameter butjust records it in names field of the FUNCTION_DECL.
(Clickhere for open)
Figure 92:pushing PARM_DECL of const Host&
For our case, last parameter handled is “const this*”, which hasname of “this”. No doubt, “this” has an associated IDNETIFIER_NODE, and it isneeded to be bound with the scope. For convience, we post the related code ofpushdecl again at below. Can see pushing named parameters is not different thanpushing other node of DECL.
566 tree
567 pushdecl (tree x) inname-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 whendeclared 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 butthe 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 intdifferent_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 upin 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 /* Becausepush_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 declsshadow 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 }
Above at line 881, push_local_binding creates the cxx_bindingnode and binds the IDENTIFIER_NODE with its scope by this node. When theidentifier appears in more than once in the source, it needs to check anypossible danger introduced. Above at line 876, IDENTIFIER_VALUE returns thelast declaration within non-namespace scope, IDENTIFIER_NAMESPACE_VALUE returns the lastdeclaration within the innermost effective namespace scope. Then at line 902,the WHILE loop skips variabledeclared within local block (i.e, FORblock). If no non-namespace non-local declaration is found, at line 908, oldlocal will get the declaration within namespace scope. Parameter “constthis*” is front-end generated argument with DECL_ARTIFICIAL flag set. Next, itupdates arguments field of the FUNCTION_DECL to names bound within the scope bygetdecls.
1533 tree
1534 getdecls (void) in name-lookup.c
1535 {
1536 returncurrent_binding_level->names;
1537 }
Then we willget following figure. Note, in PARM_DECL node, “this” represents the matchingIDENTIFIER_NODE. Connection from “this” to cxx_binding indicates IDENTIFIER_BINDING.
(Clickhere for open)
Figure 93:pushing PARM_DECL of “const this*”
- Studying note of GCC-3.4.6 source (108)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- error:unknown command "loadfont"
- Oracle中的表操作-创建、修改,增减列
- 设置ip脚本
- 同步与异步区别之我见(一)
- 数据库中的锁
- Studying note of GCC-3.4.6 source (108)
- 支付宝接口asp.net转帖
- sed 借个使用的例子及特殊符号说明
- v4l2驱动编写篇
- 使用XP自带网络连接登陆网通
- SQL Server 数据库操作实用技巧锦集
- GCC-3.4.6源代码学习笔记(109)
- 支付宝接口(ASP.NET)
- 10 个值得采用的 UNIX 命令行习惯[z]