Studying note of GCC-3.4.6 source (132)

来源:互联网 发布:中国移动网络摄影机 编辑:程序博客网 时间:2024/05/29 14:12

5.12.5.2.2.2.1.2.    Createthe VAR_DECL

Next in cp_parser_simple_declaration, cp_parser_init_declaratoris invoked to parse the declarator part. With call-stack of cp_parser_declaratorà cp_parser_direct_declarator à cp_parser_declarator_idà cp_parser_id_expression à cp_parser_unqualified_idà cp_parser_identifier, it creates anIDENTIFIER_NODE for “object_”. Then continue in cp_parser_init_declaratorfollowing code snippet would be executed.

 

cp_parser_init_declarator (continue)

 

10095   /* Enter the newlydeclared entry in the symbol table. If we're

10096     processing a declaration in aclass-specifier, we wait until

10097     after processing the initializer.  */

10098   if (!member_p)

10099   {

10100     if(parser->in_unbraced_linkage_specification_p)

10101     {

10102       decl_specifiers = tree_cons(error_mark_node,

10103                              get_identifier("extern"),

10104                              decl_specifiers);

10105       have_extern_spec = false;

10106     }

10107     decl = start_decl(declarator, decl_specifiers,

10108                    is_initialized, attributes,prefix_attributes);

10109   }

 

“SmallObject<> object_” is a variable declaration. A new treenode needs be created to stand for this entity in the intermediate tree. Atthis invocation, argument intialized is false, attributes and prefix_attributes both are NULL.

 

3670   tree

3671   start_decl (tree declarator,                                                                               in decl.c

3672            tree declspecs,

3673            int initialized,

3674            tree attributes,

3675            tree prefix_attributes)

3676   {

3677     tree decl;

3678     tree type, tem;

3679     tree context;

3680  

3681     /* This should onlybe done once on the top most decl.  */

3682     if (have_extern_spec)

3683     {

3684       declspecs = tree_cons (NULL_TREE,get_identifier ("extern"),

3685                         declspecs);

3686       have_extern_spec = false;

3687     }

3688  

3689     /* An objectdeclared as __attribute__((deprecated)) suppresses

3690       warnings of uses of otherdeprecated items.  */

3691     if (lookup_attribute ("deprecated",attributes))

3692       deprecated_state = DEPRECATED_SUPPRESS;

3693  

3694     attributes = chainon (attributes,prefix_attributes);

3695  

3696     decl = grokdeclarator (declarator, declspecs,NORMAL,initialized,

3697                        &attributes);

3698  

3699     deprecated_state = DEPRECATED_NORMAL;

3700  

3701     if (decl == NULL_TREE || TREE_CODE (decl) ==VOID_TYPE)

3702       returnerror_mark_node;

3703  

3704     type = TREE_TYPE (decl);

3705  

3706     if (type == error_mark_node)

3707       returnerror_mark_node;

3708  

3709     context = DECL_CONTEXT (decl);

3710  

3711     if (initialized && context &&TREE_CODE (context) == NAMESPACE_DECL

3712        && context != current_namespace&& TREE_CODE (decl) == VAR_DECL)

3713     {

3714       /* When parsingthe initializer, lookup should use the object's

3715         namespace.  */

3716       push_decl_namespace (context);

3717     }

3718  

3719     /* We are onlyinterested in class contexts, later.  */

3720     if (context && TREE_CODE (context) ==NAMESPACE_DECL)

3721       context = NULL_TREE;

 

Being a kind of declaration, ceratin DECL node is expected, so grokdeclaratoranalyses the part of decl-specifiers and declaractor to form this node.

 

6462   tree

6463   grokdeclarator(tree declarator,                                                                        in decl.c

6464                tree declspecs,

6465                enumdecl_context decl_context,

6466                int initialized,

6467                tree* attrlist)

6468   {

6469     RID_BIT_TYPE specbits;

6470     int nclasses = 0;

6471     tree spec;

6472     tree type = NULL_TREE;

6473     int longlong = 0;

6474     int type_quals;

6475     int virtualp, explicitp, friendp, inlinep,staticp;

6476     intexplicit_int = 0;

6477    int explicit_char = 0;

6478     int defaulted_int = 0;

6479     int extern_langp = 0;

6480     tree dependant_name = NULL_TREE;

6481    

6482     tree typedef_decl = NULL_TREE;

6483     const char*name;

6484     tree typedef_type = NULL_TREE;

6485     int funcdef_flag = 0;

6486     enumtree_code innermost_code = ERROR_MARK;

6487     int bitfield = 0;

6488   #if 0

6489     /* See the codebelow that used this.  */

6490     tree decl_attr = NULL_TREE;

6491   #endif

6492  

6493     /* Keep track ofwhat sort of function is being processed

6494       so that we can warn aboutdefault return values, or explicit

6495       return values which do notmatch prescribed defaults.  */

6496     special_function_kind sfk = sfk_none;

6497  

6498     tree dname = NULL_TREE;

6499     tree ctype = current_class_type;

6500     tree ctor_return_type = NULL_TREE;

6501     enum overload_flags flags = NO_SPECIAL;

6502     tree quals = NULL_TREE;

6503     tree raises = NULL_TREE;

6504     int template_count = 0;

6505     tree in_namespace = NULL_TREE;

6506     tree returned_attrs = NULL_TREE;

6507     tree scope = NULL_TREE;

6508     tree parms = NULL_TREE;

6509  

6510     RIDBIT_RESET_ALL (specbits);

6511     if (decl_context == FUNCDEF)

6512       funcdef_flag = 1, decl_context = NORMAL;

6513     else if (decl_context == MEMFUNCDEF)

6514       funcdef_flag = -1, decl_context = FIELD;

6515     else if (decl_context == BITFIELD)

6516       bitfield = 1, decl_context = FIELD;

6517  

6518     /* Look inside adeclarator for the name being declared

6519       and get it as a string, for anerror message.  */

6520     {

6521       tree *next = &declarator;

6522       tree decl;

6523       name = NULL;

6524  

6525       while (next&& *next)

6526       {

6527          decl = *next;

6528          switch(TREE_CODE (decl))

6529          {

              

6629            caseIDENTIFIER_NODE:

6630              if (TREE_CODE (decl) == IDENTIFIER_NODE)

6631                dname = decl;

6632  

6633              next =0;

6634  

6635              if (C_IS_RESERVED_WORD (dname))

6636              {

                   

6640              }

6641             else if (!IDENTIFIER_TYPENAME_P (dname))

6642                name = IDENTIFIER_POINTER (dname);

               

6654              break;

6655      

6656           }

6657       }

6658     }

       

6828    /* Look through thedecl specs and record which ones appear.

6829       Some typespecs are defined asbuilt-in typenames.

6830       Others, the ones that aremodifiers of other types,

6831       are represented by bits inSPECBITS: set the bits for

6832       the modifiers that appear.Storage class keywords are also in SPECBITS.

6833  

6834       If there is a typedef name ora type, store the type in TYPE.

6835       This includes builtin typedefssuch as `int'.

6836  

6837       Set EXPLICIT_INT if the typeis `int' or `char' and did not

6838       come from a user typedef.

6839  

6840       Set LONGLONG if `long' ismentioned twice.

6841  

6842       For C++, constructors anddestructors have their own fast treatment. */

6843  

6844     for (spec =declspecs; spec; spec = TREE_CHAIN (spec))

6845     {

6846       int i;

6847       tree id;

6848  

6849       /* Certain parseerrors slip through. For example,

6850         `int class;' is not caughtby the parser. Try

6851         weakly to recover here.  */

6852       if (TREE_CODE (spec) != TREE_LIST)

6853         return 0;

6854  

6855       id = TREE_VALUE (spec);

6856  

6857       /* If the entiredeclaration is itself tagged as deprecated then

6858         suppress reports ofdeprecated items.  */

6859       if (!adding_implicit_members && id &&TREE_DEPRECATED (id))

6860       {

6861         if (deprecated_state != DEPRECATED_SUPPRESS)

6862           warn_deprecated_use (id);

6863       }

6864  

6865       if (TREE_CODE (id) == IDENTIFIER_NODE)

6866       {

           

6933       }

6934       else if (TREE_CODE (id) == TYPE_DECL)

6935       {

6936         if (type)

6937           error ("multiple declarations `%T'and `%T'", type,

6938                 TREE_TYPE (id));

6939         else

6940         {

6941           type = TREE_TYPE (id);

6942           TREE_VALUE (spec) = type;

6943           typedef_decl = id;

6944         }

6945         gotofound;

6946       }

6947       if (type)

6948         error ("two or more data types indeclaration of `%s'", name);

6949       else if (TREE_CODE (id) == IDENTIFIER_NODE)

6950       {

           

6960       }

6961       else if (id != error_mark_node)

6962         /* Can't changeCLASS nodes into RECORD nodes here!  */

6963         type = id;

6964  

6965   found: ;

6966     }

6967  

6968   #if 0

6969     /* See the codebelow that used this.  */

6970     if (typedef_decl)

6971       decl_attr = DECL_ATTRIBUTES (typedef_decl);

6972   #endif

6973     typedef_type = type;

       

7019     ctype = NULL_TREE;

       

7337     scope = get_scope_of_declarator (declarator);

7338  

7339     /* Now figure outthe structure of the declarator proper.

7340       Descend through it, creatingmore complex types, until we reach

7341       the declared identifier (orNULL_TREE, in an abstract declarator). */

7342  

7343     while(declarator && TREE_CODE (declarator) != IDENTIFIER_NODE

7344           && TREE_CODE (declarator) !=TEMPLATE_ID_EXPR)

7345     {

         

7840     }

       

8163     {

8164       tree decl;

8165  

8166       if (decl_context == PARM)

8167       {

           

8172       }

8173       else if (decl_context == FIELD)

8174       {

           

8427       }

8428       else if (TREE_CODE (type) == FUNCTION_TYPE

8429             || TREE_CODE (type) == METHOD_TYPE)

8430       {

           

8514       }

8515       else

8516       {

8517         /* It's avariable.  */

8518  

8519         /* Anuninitialized decl with `extern' is a reference.  */

8520         decl = grokvardecl(type, declarator, &specbits,

8521                         initialized,

8522                         (type_quals &TYPE_QUAL_CONST) != 0,

8523                         ctype ? ctype : in_namespace);

8524         bad_specifiers(decl, "variable", virtualp, quals != NULL_TREE,

8525                      inlinep, friendp, raises !=NULL_TREE);

8526  

8527         if (ctype)

8528         {

             

8547         }

8548       }

8549  

8550       my_friendly_assert (!RIDBIT_SETP(RID_MUTABLE, specbits), 19990927);

8551  

8552       /* Record`register' declaration for warnings on &

8553         and in case doing stupidregister allocation.  */

8554  

8555       if (RIDBIT_SETP (RID_REGISTER, specbits))

8556         DECL_REGISTER (decl) = 1;

8557  

8558       if (RIDBIT_SETP (RID_EXTERN, specbits))

8559         DECL_THIS_EXTERN (decl) = 1;

8560  

8561       if (RIDBIT_SETP (RID_STATIC, specbits))

8562         DECL_THIS_STATIC (decl) = 1;

8563  

8564       /* Recordconstancy and volatility. There's no need to do this

8565         when processing a template;we'll do this for the instantiated

8566         declaration based on thetype of DECL.  */

8567       if (!processing_template_decl)

8568         c_apply_type_quals_to_decl (type_quals, decl);

8569  

8570       returndecl;

8571     }

8572   }

 

In above code, it is very clearly that code of WHILE block at line 6525 verifies the declarator part; and code of FOR block at line 6844 verifies andretrieves the corresponding type-specifier. Note that at line 6941, typerefers to the RECORD_TYPE created in last section.

Next typeand declaratorshould be combined to form the VAR_DECL by grokvardecl. Note that for our case, duringinvocation, argument scope is NULL, constp is false, initializedis false, and specbits_incontains 0.

 

5885   static tree

5886   grokvardecl (tree type,                                                                                    in decl.c

5887              tree name,

5888              RID_BIT_TYPE * specbits_in,

5889              int initialized,

5890              int constp,

5891              tree scope)

5892   {

5893     tree decl;

5894     tree explicit_scope;

5895     RID_BIT_TYPE specbits;

5896  

5897     my_friendly_assert (!name || TREE_CODE (name)== IDENTIFIER_NODE,

5898                      20020808);

5899  

5900     specbits = *specbits_in;

5901  

5902     /* Compute thescope in which to place the variable, but remember

5903       whether or not that scope wasexplicitly specified by the user.  */

5904     explicit_scope = scope;

5905     if (!scope)

5906     {

5907       /* An explicit"extern" specifier indicates a namespace-scope

5908         variable.  */

5909       if (RIDBIT_SETP (RID_EXTERN, specbits))

5910         scope = current_namespace;

5911       else if (!at_function_scope_p ())

5912       {

5913         scope = current_scope ();

5914         if(!scope)

5915           scope = current_namespace;

5916       }

5917     }

5918  

5919     if (scope

5920        && (/*If the variable is a namespace-scope variable declared in a

5921              template, we needDECL_LANG_SPECIFIC.  */

5922             (TREE_CODE (scope)== NAMESPACE_DECL && processing_template_decl)

5923              /*Similarly for namespace-scope variables with language linkage

5924                other than C++.  */

5925              || (TREE_CODE (scope) ==NAMESPACE_DECL

5926                && current_lang_name !=lang_name_cplusplus)

5927             /*Similarly for static data members.  */

5928             || TYPE_P (scope)))

5929       decl = build_lang_decl (VAR_DECL, name,type);

5930     else

5931       decl = build_decl(VAR_DECL, name, type);

5932  

5933     if (explicit_scope && TREE_CODE(explicit_scope) == NAMESPACE_DECL)

5934       set_decl_namespace (decl, explicit_scope,0);

5935     else

5936       DECL_CONTEXT (decl) = scope;

5937  

5938     if (name && scope && current_lang_name!= lang_name_c)

5939       /* We can't mangle lazily here because wedon't have any

5940         way to recover whether ornot a variable was `extern

5941         "C"' later.  */

5942       mangle_decl (decl);

5943  

5944     if (RIDBIT_SETP (RID_EXTERN, specbits))

5945     {

5946       DECL_THIS_EXTERN (decl) = 1;

5947       DECL_EXTERNAL (decl) = !initialized;

5948     }

5949  

5950     /* In classcontext, static means one per class,

5951       public access, and staticstorage.  */

5952     if (DECL_CLASS_SCOPE_P (decl))

5953     {

5954       TREE_PUBLIC (decl) = 1;

5955       TREE_STATIC (decl) = 1;

5956       DECL_EXTERNAL (decl) = 0;

5957     }

5958     /* At top level,either `static' or no s.c.makes a definition

5959       (perhaps tentative), andabsence of `static' makes it public.  */

5960     else if (toplevel_bindings_p ())

5961     {

5962       TREE_PUBLIC (decl) = (RIDBIT_NOTSETP(RID_STATIC, specbits)

5963                            &&(DECL_THIS_EXTERN (decl) || ! constp));

5964       TREE_STATIC (decl) = ! DECL_EXTERNAL(decl);

5965     }

5966     /* Not at toplevel, only `static' makes a static definition. */

5967     else

5968     {

5969       TREE_STATIC (decl) = !! RIDBIT_SETP(RID_STATIC, specbits);

5970       TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);

5971     }

5972  

5973     if (RIDBIT_SETP (RID_THREAD, specbits))

5974     {

5975       if (targetm.have_tls)

5976         DECL_THREAD_LOCAL (decl) = 1;

5977       else

5978         /* A merewarning is sure to result in improper semantics

5979           at runtime. Don't botherto allow this to compile.  */

5980         error ("thread-local storage notsupported for this target");

5981     }

5982  

5983     if (TREE_PUBLIC (decl))

5984     {

5985       /* [basic.link]:A name with no linkage (notably, the name of a class

5986         or enumeration declared in alocal scope) shall not be used to

5987         declare an entity withlinkage.

5988  

5989         Only check this for publicdecls for now.  */

5990       tree t = no_linkage_check (TREE_TYPE(decl));

5991       if (t)

5992       {

5993         if (TYPE_ANONYMOUS_P (t))

5994           /* Ignore fornow; `enum { foo } e' is pretty common. */;

5995         else

5996           pedwarn ("non-local variable `%#D'uses local type `%T'",

5997                    decl, t);

5998       }

5999     }

6000  

6001     return decl;

6002   }

 

After this step,we get following VAR_DECL as below figure. Note that context field of the node is NULLas we are not within class scope.

(Clickhere for open)

 

start_decl (continue)

 

3832     /* Enter thisdeclaration into the symbol table.  */

3833     tem = maybe_push_decl (decl);

3834  

3835     if (processing_template_decl)

3836       tem = push_template_decl (tem);

3837     if (tem == error_mark_node)

3838       returnerror_mark_node;

3839  

3840   #if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)

3841     /* Tell theback-end to use or not use .common as appropriate. If we say

3842       -fconserve-space, we want thisto save .data space, at the expense of

3843       wrong semantics. If we say-fno-conserve-space, we want this to

3844       produce errors about redefs;to do this we force variables into the

3845       data segment.  */

3846     DECL_COMMON (tem) = ((TREE_CODE (tem) !=VAR_DECL

3847                              ||!DECL_THREAD_LOCAL (tem))

3848                            && (flag_conserve_space|| ! TREE_PUBLIC (tem)));

3849   #endif

3850  

3851     if (! processing_template_decl)

3852       start_decl_1 (tem);

3853  

3854     return tem;

3855   }

 

Being a VAR_DECL node containing context field of NULL, maybe_push_decl invokes pushdeclfor decl.And for our case, start_decl_1 at line 3852 does nothing.

 

566    tree

567    pushdecl (treex)                                                                               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        /* Templateparameters have no context; they are not X::T even

579          when declaredwithin a class or namespace.  */

580        ;

581      else

582      {

583        if (current_function_decl && x != current_function_decl

584           /* A localdeclaration for a function doesn't constitute

585            nesting.  */

586           && TREE_CODE (x) !=FUNCTION_DECL

587           /* A localdeclaration for an `extern' variable is in the

588             scope of thecurrent 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;

         

602      }

603   

604      name = DECL_NAME (x);

605      if (name)

606      {

607        int different_binding_level = 0;

         

615        /* In case thisdecl was explicitly namespace-qualified, look it

616          up in itsnamespace 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);

         

828        /* This name isnew in its binding level.

829          Install the newdeclaration and return it.  */

830        if (namespace_bindings_p())

831        {

           

872        }

873        else

874        {

875          /* Here toinstall 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 thatagain below.  */

885            need_new_binding = 0;

886          }

           

1003       }

1004  

1005       if (TREE_CODE (x) == VAR_DECL)

1006          maybe_register_incomplete_var (x);

1007     }

       

1015     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);

1016   }

 

We have seen pushdeclmany times; again we just put the executed code of the function in above. Notethat maybe_register_incomplete_varat line 1006 does nothing for non-external VAR_DECL. At the exit of start_declwe get following intermediate tree.

( Clickhere for open)

 

cp_parser_init_declarator (continue)

 

10111   /* Enter the SCOPE.That way unqualified names appearing in the

10112     initializer will be looked up inSCOPE.  */

10113   if (scope)

10114     pop_p = push_scope (scope);

10115

10116   /* Perform deferredaccess control checks, now that we know in which

10117     SCOPE the declared entity resides.  */

10118   if (!member_p && decl)

10119   {

10120     tree saved_current_function_decl =NULL_TREE;

10121

10122     /* If the entitybeing declared is a function, pretend that we

10123       arein its scope. If it is a `friend', it may have access to

10124       things that would not otherwise beaccessible.  */

10125     if (TREE_CODE (decl) == FUNCTION_DECL)

10126     {

10127       saved_current_function_decl = current_function_decl;

10128       current_function_decl = decl;

10129     }

10130     

10131     /* Perform theaccess control checks for the declarator and the

10132       the decl-specifiers.  */

10133     perform_deferred_access_checks();

10134

10135     /* Restore thesaved value.  */

10136     if (TREE_CODE (decl) == FUNCTION_DECL)

10137       current_function_decl =saved_current_function_decl;

10138   }

10139

10140   /* Parse theinitializer.  */

10141   if (is_initialized)

10142     initializer = cp_parser_initializer(parser,

10143                                &is_parenthesized_init,

10144                                &is_non_constant_init);

10145   else

10146   {

10147     initializer = NULL_TREE;

10148     is_parenthesized_init = false;

10149     is_non_constant_init = true;

10150   }

         

10178   /* Finish processing the declaration. But,skip friend

10179     declarations.  */

10180   if (!friend_p && decl)

10181     cp_finish_decl(decl,

10182                  initializer,

10183                  asm_specification,

10184                     /* Ifthe initializer is in parentheses, then this is

10185                     a direct-initialization, which means that an

10186                     `explicit' constructor is OK.Otherwise, an

10187                     `explicit' constructorcannot be used.  */

10188                  ((is_parenthesized_init ||!is_initialized)

10189                  ? 0 : LOOKUP_ONLYCONVERTING));

10190

10191   /* Remember whetheror not variables were initialized by

10192     constant-expressions.  */

10193   if (decl && TREE_CODE (decl) ==VAR_DECL

10194       && is_initialized &&!is_non_constant_init)

10195     DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P(decl) = true;

10196

10197   return decl;

10198 }

 

Notice that after creating the nodes for template-id and VAR_DECL,it is time to perform the deferred access checking for the related declaratorand decl-specifier. See that error in access checking will not stop the parser.

 

原创粉丝点击