Studying note of GCC-3.4.6 source (108)

5.12.3.2.1.2.1.1.1.            Prepare data before function handling

Next, it prepares structure for expanding statements within the body. Notice that argument t in begin_stmt_tree refers to the address of field DECL_SAVED_TREE of the RESULT_DECL.

 

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      }

 

The chain of statements must be ended by a fake EXPR_STMT before processing. 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)                            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    }

 

Now, as it is handling method, cfun is already allocated in allocate_struct_function at line 10360 in start_function . So here, we see what cfun looks like.

 

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   }

 

Refer to section Evaluate cost for arithmatic operatoins – Create dummy function context for some details. For the invocation, the argument fndecl points to the node FUNCTION_DECL. Above, init_stmt_for_function and init_eh_for_function just create instance of stmt_status and eh_status for cfun .

Then at line 6453, for C++ front-end, cxx_push_function_context is registered into function.init within lang_hooks . It initializes the variables used during compilation of a C++ function.

 

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 }

 

Below cp_function_chain returns field language of cfun .

 

802  #define cp_function_chain (cfun ->language)                                                        in cp-tree.h

 

Then DECL_SAVED_FUNCTION_DATA returns the address of saved_language_function for 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 function redefinition. In fact, argument f is cfun created at line 6439, which doesn’t satisfy condition at line 11301, so for C++, code from line 11302 to 11320 won’t be 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      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    };

 

As C++ accommendates grammar of C, the structure contains c_language_function to hold status of C relevant. And other fields are for C++ solely.

 

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    };

 

Also, generating code for different machine must take the characteristic of machine into account, and this information should be used during instruction emission for the machine.

 

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 }

 

See that machine_function defined for x86 machine will record the snapshot of the machine at point executing the function.

 

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   };

 

Below stmt_tree_s is used to store the statements within in function. See that at line 73 in begin_stmt_tree , x_last_stmt will be the chain of 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 ;

 

Then at line 6460 in allocate_struct_function , DECL_SAVED_INSNS points to cfun . See that when handling next function, cfun will be recreated at line 6439, and DECL_SAVED_INSNS will be the solely reference to this function instance.

Further, if the function returns aggregate type, more code needs be generated to pass address instead, and certain optimization may be applied. For example:

struct A { … };

A func() { return A(); }

int main() {

  A a = func();

}

An opportunity of optimization is to make func to manipulate a directly.

In short, function returning aggregate type needs specially handling, 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 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   }

 

Above at line 10374, announce_function just prints out the message about going to compile the function. At line 10416, if ctype is not NULL, it ensures that it is processing method. And if the method is not static, then DECL_ARGUMENTS at line 10422 returns “const this*”. To tell out method from function and for quick accessing the “this” instance, it is better to save the reference and pointer within the function structure. That is why we see x_current_class_ref and x_current_class_ptr at 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       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   }

 

Above at line 2094, decay_conversion does nothing but just returns ptr - the node of PARM_DECL of “const this*”. And at line 2107, canonical_type_variant is just a simple wrapper of cp_build_qualified_type to create cv-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 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   }

 

Refers to section #pragma interface & #pragma implementation for the details. For our example, without specifying “#pragma interface” and “#pragma implementation”, condition at line 10499 is satisfied.

5.12.3.2.1.2.1.1.2.            Push function scope

Before exitting the routine, it should push the scope of the function into effect. Notice that sk_function_parms specifies that the scope containing 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   return 1;

10530 }

 

Then the front-end needs setup following identifers, [6] gives the details:

5.43 Function Names as Strings

GCC provides three magic variables which hold the name of the current function, as a string. The first of these is __func__, which is part of the C99 standard:

The identifier __func__ is implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

static const char __func__[] = "function-name";

appeared, where function-name is the name of the lexically-enclosing function. This name is the unadorned name of the function.

__FUNCTION__ is another name for __func__. Older versions of GCC recognize only this name. However, it is not standardized. For maximum portability, we recommend you use __func__, but provide a fallback definition with 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 well as 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 and earlier, in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as string literals; they could be used to initialize char arrays, and they could be concatenated with other string literals. GCC 3.4 and later treat them as variables, like __func__. In C++, __FUNCTION__ and __PRETTY_FUNCTION__ have always 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 the information of these identifiers.

 

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    };

 

Of course, these identifiers must be global visible and unique, so they are in fact declared within c_global_trees , and with associated RID tag marked as a special token (like reserved words) recognized by parser. Note that c99_function_name_decl_node , function_name_decl_node , pretty_function_name_decl_node are 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 means using __func__ etc in the caller function, then at time entering the callee function, it should be cached within global stack of saved_function_name_decls . And when exitting from the callee function, the cached decl would be restored to make it usable in the rest of caller function.

When the function scope becomes the current_binding_level , it needs to push the parameters into the scope so later name-lookup can find out the proper item. Now current_function_parms refers to the chain of the parameters of the function.

 

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 }

 

Here at line 10573 and 10574, validates the parameters again, if the parameter 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 the method. For every parameter, pushdecl is invoked in reverse order. So for first invocation, the PARM_DECL of “const Host&” is nameless.

 

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   }

 

As the parameter is nameless, so no cxx_binding node is created for the parameter but just records it in names field of the FUNCTION_DECL.

(Click here for open )

Figure 92 : pushing PARM_DECL of const Host&

For our case, last parameter handled is “const this*”, which has name of “this”. No doubt, “this” has an associated IDNETIFIER_NODE, and it is needed to be bound with the scope. For convience, we post the related code of pushdecl again at below. Can see pushing named parameters is not different than pushing other node of 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   }

 

Above at line 881, push_local_binding creates the cxx_binding node and binds the IDENTIFIER_NODE with its scope by this node. When the identifier appears in more than once in the source, it needs to check any possible danger introduced. Above at line 876, IDENTIFIER_VALUE returns the last declaration within non-namespace scope, IDENTIFIER_NAMESPACE_VALUE returns the last declaration within the innermost effective namespace scope. Then at line 902, the WHILE loop skips variable declared within local block (i.e, FOR block). If no non-namespace non-local declaration is found, at line 908, oldlocal will get the declaration within namespace scope. Parameter “const this*” is front-end generated argument with DECL_ARTIFICIAL flag set. Next, it updates arguments field of the FUNCTION_DECL to names bound within the scope by getdecls .

 

1533   tree

1534   getdecls (void)                                                                                  in name-lookup.c

1535   {

1536     return current_binding_level ->names;

1537   }

 

Then we will get following figure. Note, in PARM_DECL node, “this” represents the matching IDENTIFIER_NODE. Connection from “this” to cxx_binding indicates IDENTIFIER_BINDING.

(Click here for open )

Figure 93 : pushing PARM_DECL of “const this*”

 

你可能感兴趣的:(function,tree,null,interface,binding,Instantiation)