Studying note of GCC-3.4.6 source (141 - cont 2)

    技术2022-06-26  33

    Then check_initializer is invoked to verify the initializers. Here argument flags is 0.

     

    4463   static tree

    4464   check_initializer (tree decl, tree init, int flags, tree *cleanup)                               in decl.c

    4465   {

    4466     tree type = TREE_TYPE (decl);

    4467     tree init_code = NULL;

    4468  

    4469     /* If `start_decl' didn't like having an initialization, ignore it now.  */

    4470     if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE)

    4471       init = NULL_TREE;

    4472  

    4473     /* If an initializer is present, DECL_INITIAL has been

    4474       error_mark_node, to indicate that an as-of-yet unevaluated

    4475       initialization will occur. From now on, DECL_INITIAL reflects

    4476       the static initialization -- if any -- of DECL.  */

    4477     DECL_INITIAL (decl) = NULL_TREE;

    4478  

    4479     /* Things that are going to be initialized need to have complete

    4480       type.  */

    4481     TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));

    4482  

    4483     if (type == error_mark_node)

    4484       /* We will have already complained.  */

    4485       init = NULL_TREE;

    4486     else if (init && COMPLETE_TYPE_P (type)

    4487            && !TREE_CONSTANT (TYPE_SIZE (type)))

    4488     {

    4489       error ("variable-sized object `%D' may not be initialized", decl);

    4490       init = NULL_TREE;

    4491     }

    4492     else if (TREE_CODE (type) == ARRAY_TYPE

    4493            && !COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))

    4494     {

    4495       error ("elements of array `%#D' have incomplete type", decl);

    4496       init = NULL_TREE;

    4497     }

    4498     else if (TREE_CODE (type) != ARRAY_TYPE && !COMPLETE_TYPE_P (type))

    4499     {

    4500       error ("`%D' has incomplete type", decl);

    4501       TREE_TYPE (decl) = error_mark_node;

    4502       init = NULL_TREE;

    4503     }

    4504  

    4505     if (TREE_CODE (decl) == CONST_DECL)

    4506     {

    4507       my_friendly_assert (TREE_CODE (decl) != REFERENCE_TYPE, 148);

    4508  

    4509       DECL_INITIAL (decl) = init;

    4510  

    4511       my_friendly_assert (init != NULL_TREE, 149);

    4512       init = NULL_TREE;

    4513     }

    4514     else if (!DECL_EXTERNAL (decl) && TREE_CODE (type) == REFERENCE_TYPE)

    4515       init = grok_reference_init (decl, type, init, cleanup);

    4516     else if (init)

    4517     {

    4518       if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))

    4519       {

    4520           /* [dcl.init] paragraph 13,

    4521            If T is a scalar type, then a declaration of the form

    4522            T x = { a };

    4523            is equivalent to

    4524            T x = a;

    4525       

    4526            reshape_init will complain about the extra braces,

    4527            and doesn't do anything useful in the case where TYPE is

    4528            scalar, so just don't call it.  */

    4529          if (CP_AGGREGATE_TYPE_P (type))

    4530            init = reshape_init (type, &init);

    4531  

    4532          if ((*targetm .vector_opaque_p) (type))

    4533          {

    4534            error ("opaque vector types cannot be initialized");

    4535            init = error_mark_node;

    4536          }

    4537       }

     

    One of clause of [dcl.init.aggr] of C++ standard specifies that:

    All implicit type conversions (clause 4) are considered when initializing the aggregate member with an initializer from an initializer-list. If the initializer can initialize a member, the member is initialized. Otherwise, if the member is itself a non-empty subaggregate, brace elision is assumed and the initializer is considered for the initialization of the first member of the subaggregate. For example:

    struct A {

    int i;

    operator int();

    };

    struct B {

    A a1, a2;

    int z;

    };

    A a;

    B b = { 4, a, a };

    Braces are elided around the initializer for b.a1.i. b.a1.i is initialized with 4, b.a2 is initialized with a, b.z is initialized with whatever a.operator int() returns.

    Routine reshape_init is invoked to transform the initializers list in form of {4, a, a } into the form of { {4, a}, a}. The rear one is what expected by the front-end.

    Here for our example, the VAR_DECL is the array of vtable_entry_type and initp refers to the CONSTRUCTOR node for the initializers, which is deliberately created with empty type. So code in block at line 4289 is executed. CONSTRUCTOR_ELTS returns the inits generated in above. These initializers are treated as if enclosed by braces.

     

    4267   static tree

    4268   reshape_init (tree type, tree *initp)                                                                    in decl.c

    4269   {

    4270     tree inits;

    4271     tree old_init;

    4272     tree old_init_value;

    4273     tree new_init;

    4274     bool brace_enclosed_p;

    4275     bool string_init_p;

    4276  

    4277     old_init = *initp;

    4278     old_init_value = (TREE_CODE (*initp) == TREE_LIST

    4279                    ? TREE_VALUE (*initp) : old_init);

    4280  

    4281     my_friendly_assert (old_init_value, 20030723);

    4282  

    4283     /* If the initializer is brace-enclosed, pull initializers from the

    4284       enclosed elements. Advance past the brace-enclosed initializer

    4285       now.  */

    4286     if (TREE_CODE (old_init_value) == CONSTRUCTOR

    4287        && TREE_TYPE (old_init_value) == NULL_TREE

    4288        && TREE_HAS_CONSTRUCTOR (old_init_value))

    4289     {

    4290       *initp = TREE_CHAIN (old_init);

    4291       TREE_CHAIN (old_init) = NULL_TREE;

    4292       inits = CONSTRUCTOR_ELTS (old_init_value);

    4293       initp = &inits;

    4294       brace_enclosed_p = true;

    4295     }

    4296     else

    4297     {

    4298       inits = NULL_TREE;

    4299       brace_enclosed_p = false;

    4300     }

    4301  

    4302     /* A non-aggregate type is always initialized with a single

    4303       initializer.  */

    4304     if (!CP_AGGREGATE_TYPE_P (type))

    4305     {

    4306       *initp = TREE_CHAIN (old_init);

    4307       TREE_CHAIN (old_init) = NULL_TREE;

    4308       /* It is invalid to initialize a non-aggregate type with a

    4309         brace-enclosed initializer.  */

    4310       if (brace_enclosed_p)

    4311       {

    4312         error ("brace-enclosed initializer used to initialize `%T'",

    4313               type);

    4314         if (TREE_CODE (old_init) == TREE_LIST)

    4315           TREE_VALUE (old_init) = error_mark_node;

    4316         else

    4317           old_init = error_mark_node;

    4318       }

    4319       

    4320       return old_init;

    4321     }

    4322  

    4323     /* [dcl.init.aggr]

    4324  

    4325       All implicit type conversions (clause _conv_) are considered when

    4326       initializing the aggregate member with an initializer from an

    4327       initializer-list. If the initializer can initialize a member,

    4328       the member is initialized. Otherwise, if the member is itself a

    4329       non-empty subaggregate, brace elision is assumed and the

    4330       initializer is considered for the initialization of the first

    4331       member of the subaggregate.  */

    4332     if (!brace_enclosed_p

    4333        && can_convert_arg (type, TREE_TYPE (old_init_value), old_init_value))

    4334     {

    4335       *initp = TREE_CHAIN (old_init);

    4336       TREE_CHAIN (old_init) = NULL_TREE;

    4337       return old_init;

    4338     }

    4339  

    4340     string_init_p = false;

    4341     if (TREE_CODE (old_init_value) == STRING_CST

    4342        && TREE_CODE (type) == ARRAY_TYPE

    4343        && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))

    4344     {

              …

    4356     }

    4357     else

    4358     {

    4359       /* Build a CONSTRUCTOR to hold the contents of the aggregate.  */ 

    4360       new_init = build_constructor (type, NULL_TREE);

    4361       TREE_HAS_CONSTRUCTOR (new_init) = 1;

    4362  

    4363       if (CLASS_TYPE_P (type))

    4364       {

                …

    4419       }

    4420       else if ((TREE_CODE (type) == ARRAY_TYPE)|| (TREE_CODE (type) == VECTOR_TYPE))

    4421       {

    4422          tree max_index;

    4423  

    4424          /* If the bound of the array is known, take no more initializers

    4425            than are allowed.  */

    4426          max_index = ((TYPE_DOMAIN (type) && (TREE_CODE (type) == ARRAY_TYPE))

    4427                      ? array_type_nelts (type) : NULL_TREE);

    4428          if (!reshape_init_array (TREE_TYPE (type), max_index,

    4429                              initp, new_init))

    4430            return error_mark_node;

    4431       }

    4432       else

    4433         abort ();

    4434  

    4435       /* The initializers were placed in reverse order in the

    4436          CONSTRUCTOR.  */

    4437       CONSTRUCTOR_ELTS (new_init) = nreverse (CONSTRUCTOR_ELTS (new_init));

    4438  

    4439       if (TREE_CODE (old_init) == TREE_LIST)

    4440         new_init = build_tree_list (TREE_PURPOSE (old_init), new_init);

    4441     }

    4442  

    4443     /* If there are more initializers than necessary, issue a

    4444       diagnostic.  */ 

    4445     if (*initp)

    4446     {

    4447       if (brace_enclosed_p)

    4448         error ("too many initializers for `%T'", type);

    4449       else if (warn_missing_braces && !string_init_p)

    4450         warning ("missing braces around initializer");

    4451     }

    4452  

    4453     return new_init;

    4454   }

     

    See for aggregate member, line 4333 verifies that type of the initializer can be converted to that of member. For array, below reshape_init_array iterates every element by reshape_init to verify and reshape the initializer. For non-aggregate member, the initializer is just returned.

     

    4203   static bool

    4204   reshape_init_array (tree elt_type, tree max_index,                                              in decl.c

    4205                   tree *initp, tree new_init)

    4206   {

    4207     bool sized_array_p = (max_index != NULL_TREE);

    4208     unsigned HOST_WIDE_INT max_index_cst = 0;

    4209     unsigned HOST_WIDE_INT index;

    4210  

    4211     if (sized_array_p)

    4212     {

    4213       if (host_integerp (max_index, 1))

    4214         max_index_cst = tree_low_cst (max_index, 1);

    4215        /* sizetype is sign extended, not zero extended.  */

    4216       else

    4217         max_index_cst = tree_low_cst (convert (size_type_node, max_index), 1);

    4218     }

    4219  

    4220     /* Loop until there are no more initializers.  */

    4221     for (index = 0;

    4222         *initp && (!sized_array_p || index <= max_index_cst);

    4223         ++index)

    4224     {

    4225       tree element_init;

    4226       tree designated_index;

    4227  

    4228       element_init = reshape_init (elt_type, initp);

    4229       if (element_init == error_mark_node)

    4230         return false;

    4231       TREE_CHAIN (element_init) = CONSTRUCTOR_ELTS (new_init);

    4232       CONSTRUCTOR_ELTS (new_init) = element_init;

    4233       designated_index = TREE_PURPOSE (element_init);

    4234       if (designated_index)

    4235       {

    4236          /* Handle array designated initializers (GNU extension).  */

    4237         if (TREE_CODE (designated_index) == IDENTIFIER_NODE)

    4238         {

    4239           error ("name `%D' used in a GNU-style designated "

    4240                "initializer for an array", designated_index);

    4241           TREE_PURPOSE (element_init) = NULL_TREE;

    4242         }

    4243         else

    4244           abort ();

    4245       }

    4246     }

    4247  

    4248     return true;

    4259   }

     

    Here TREE_PURPOSE of every initializer of our example is empty (TREE_PURPOSE is used for designated initializer, IBM’s XL C supports this feature, detail see here . See that the new CONSTRUCTOR generated has type assigned when compared with former one.

    Then in check_initializer at line 4532, under x86 machine, vector_opaque_p hook in targetm always returns false. And below maybe_deduce_size_from_array_init sets the size field in the node of array, for example: int a[] = { 1, 2, 3}; the function should set the size of 3 into the node.

     

    check_initializer (continue)

     

    4539       /* If DECL has an array type without a specific bound, deduce the

    4540          array size from the initializer.  */

    4541       maybe_deduce_size_from_array_init (decl, init);

    4542       type = TREE_TYPE (decl);

    4543       if (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))

    4544         TREE_TYPE (init) = type;

    4545  

    4546       if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type))

    4547       {

                …

    4579       }

    4580       else

    4581       {

    4582   dont_use_constructor:

    4583          if (TREE_CODE (init) != TREE_VEC)

    4584          {

    4585            init_code = store_init_value (decl, init);

    4586            init = NULL;

    4587          }

    4588       }

    4589     }

    4590     else if (DECL_EXTERNAL (decl))

    4591       ;

    4592     else if (TYPE_P (type) && TYPE_NEEDS_CONSTRUCTING (type))

    4593       goto initialize_aggr;

    4594     else if (IS_AGGR_TYPE (type))

    4595     {

    4596       tree core_type = strip_array_types (type);

    4597  

    4598       if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type))

    4599         error ("structure `%D' with uninitialized const members", decl);

    4600       if (CLASSTYPE_REF_FIELDS_NEED_INIT (core_type))

    4601         error ("structure `%D' with uninitialized reference members",

    4602               decl);

    4603  

    4604       check_for_uninitialized_const_var (decl);

    4605     }

    4606     else

    4607       check_for_uninitialized_const_var (decl);

    4608  

    4609     if (init && init != error_mark_node)

    4610       init_code = build (INIT_EXPR, type, decl, init);

    4611  

    4612     return init_code;

    4613   }

     

    Type of decl is vtbl_type_node which is ARRAY_TYPE of vtable_entry_type which in turn is a pointer of certain function type; of course no constructor is defined for this ARRAY_TYPE. So condition at line 4546 is false for type .

     

    410    tree

    411     store_init_value (tree decl, tree init)                                                           in typeck2.c

    412    {

    413      tree value, type;

    414   

    415      /* If variable's type was invalidly declared, just ignore it.  */

    416   

    417      type = TREE_TYPE (decl);

    418      if (TREE_CODE (type) == ERROR_MARK)

    419        return NULL_TREE;

    420   

    421      if (IS_AGGR_TYPE (type))

    422      {

              …

    432      }

    433      else if (TREE_CODE (init) == TREE_LIST

    434            && TREE_TYPE (init) != unknown_type_node)

    435      {

              …

    448      }

    449   

    450      /* Digest the specified initializer into an expression.  */

    451      value = digest_init (type, init, (tree *) 0);

    452      /* If the initializer is not a constant, fill in DECL_INITIAL with

    453        the bits that are constant, and then return an expression that

    454        will perform the dynamic initialization.  */

    455      if (value != error_mark_node

    456         && (! TREE_CONSTANT (value)

    457              || ! initializer_constant_valid_p (value, TREE_TYPE (value))))

    458        return split_nonconstant_init (decl, value);

    459      /* If the value is a constant, just put it in DECL_INITIAL. If DECL

    460        is an automatic variable, the middle end will turn this into a

    461        dynamic initialization later.  */

    462      DECL_INITIAL (decl) = value;

    463      return NULL_TREE;

    464    }

     

    Here argument type is the type of the VAR_DECL. Initializers needsn’t be the same type as corresponding member as long as appropriate convertor is found. The purpose of digest_init is to find the applicable convertor and generate necessary code for this conversion, if type and init can’t match exactly.

     

    476    tree

    477    digest_init (tree type, tree init, tree* tail)                                                    in typeck2.c

    478    {

    479      enum tree_code code = TREE_CODE (type);

    480      tree element = NULL_TREE;

    481      tree old_tail_contents = NULL_TREE;

    482      /* Nonzero if INIT is a braced grouping.  */

    483      int raw_constructor;

    484   

    485      /* By default, assume we use one element from a list.

    486        We correct this later in the sole case where it is not true.  */

    487   

    488      if (tail)

    489      {

    490        old_tail_contents = *tail;

    491        *tail = TREE_CHAIN (*tail);

    492      }

    493   

    494      if (init == error_mark_node || (TREE_CODE (init) == TREE_LIST

    495                               && TREE_VALUE (init) == error_mark_node))

    496        return error_mark_node;

    497   

    498      if (TREE_CODE (init) == ERROR_MARK)

    499        /* __PRETTY_FUNCTION__'s initializer is a bogus expression inside

    500          a template function. This gets substituted during instantiation.  */

    501        return init;

    502   

    503      /* We must strip the outermost array type when completing the type,

    504        because the its bounds might be incomplete at the moment.  */

    505      if (!complete_type_or_else (TREE_CODE (type) == ARRAY_TYPE

    506                             ? TREE_TYPE (type) : type, NULL_TREE))

    507        return error_mark_node;

    508     

    509      /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */

    510      if (TREE_CODE (init) == NON_LVALUE_EXPR)

    511         init = TREE_OPERAND (init, 0);

    512   

    513      raw_constructor = (TREE_CODE (init) == CONSTRUCTOR

    514                        && TREE_HAS_CONSTRUCTOR (init));

    515   

    516      if (raw_constructor

    517          && CONSTRUCTOR_ELTS (init) != 0

    518          && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0)

    519      {

    520        element = TREE_VALUE (CONSTRUCTOR_ELTS (init));

    521         /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue.  */

    522        if (element && TREE_CODE (element) == NON_LVALUE_EXPR)

    523          element = TREE_OPERAND (element, 0);

    524        if (element == error_mark_node)

    525          return element;

    526      }

    527   

    528      /* Initialization of an array of chars from a string constant

    529        optionally enclosed in braces.  */

    530   

    531      if (code == ARRAY_TYPE)

    532      {

    533        tree typ1;

    534   

    535        if (TREE_CODE (init) == TREE_LIST)

    536        {

    537          error ("initializing array with parameter list");

    538          return error_mark_node;

    539        }

    540   

    541        typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));

    542        if (char_type_p (typ1)

    543           && ((init && TREE_CODE (init) == STRING_CST)

    544                || (element && TREE_CODE (element) == STRING_CST)))

    545        {

                …

    577        }

    578      }

    579   

    580      /* Handle scalar types, including conversions,

    581        and signature pointers and references.  */

    582   

    583      if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE

    584           || code == ENUMERAL_TYPE || code == REFERENCE_TYPE

    585          || code == BOOLEAN_TYPE || code == COMPLEX_TYPE

    586          || TYPE_PTR_TO_MEMBER_P (type))

    587      {

    588        if (raw_constructor)

    589        {

    590          if (element == 0)

    591          {

    592            error ("initializer for scalar variable requires one element");

    593            return error_mark_node;

    594          }

    595          init = element;

    596        }

    597        while (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init))

    598        {

    599          pedwarn ("braces around scalar initializer for `%T'", type);

    600          init = CONSTRUCTOR_ELTS (init);

    601          if (TREE_CHAIN (init))

    602            pedwarn ("ignoring extra initializers for `%T'", type);

    603          init = TREE_VALUE (init);

    604        }

    605   

    606        return convert_for_initialization (0, type, init, LOOKUP_NORMAL,

    607                                   "initialization", NULL_TREE, 0);

    608      }

    609   

    610      /* Come here only for records and arrays (and unions with constructors).  */

    611    

    612      if (COMPLETE_TYPE_P (type) && ! TREE_CONSTANT (TYPE_SIZE (type)))

    613      {

    614        error ("variable-sized object of type `%T' may not be initialized",

    615              type);

    616        return error_mark_node;

    617      }

    618   

    619      if (code == ARRAY_TYPE || code == VECTOR_TYPE || IS_AGGR_TYPE_CODE (code))

    620      {

    621        if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)

    622           && TREE_HAS_CONSTRUCTOR (init))

    623        {

    624          error ("subobject of type `%T' must be initialized by constructor, not by `%E'",

    625                type, init);

    626          return error_mark_node;

    627        }

    628        else if (raw_constructor)

    629          return process_init_constructor (type, init, (tree *)0);

              …

    649      }

    650   

    651      error ("invalid initializer");

    652      return error_mark_node;

    653    }

     

    For the initializers of our example, at line 513, raw_constructor is nonzero; and code is ARRAY_TYPE. Then argument init is passed to process_init_constructor for handling.

     

    670    static tree

    671    process_init_constructor (tree type, tree init, tree* elts)                               in typeck2.c

    672    {

    673      tree tail;

    674      /* List of the elements of the result constructor,

    675        i n reverse order.  */

    676      tree members = NULL;

    677      tree next1;

    678      tree result;

    679      int allconstant = 1;

    680      int allsimple = 1;

    681      int erroneous = 0;

    682   

    683      /* Make TAIL be the list of elements to use for the initialization,

    684        no matter how the data was given to us.  */

    685   

    686      if (elts)

    687      {

    688        if (warn_missing_braces )

    689           warning ("aggregate has a partly bracketed initializer");

    690        tail = *elts;

    691      }

    692      else

    693        tail = CONSTRUCTOR_ELTS (init);

    694   

    695      /* Gobble as many elements as needed, and make a constructor or initial value

    696        for each element of this aggregate. Chain them together in result.

    697        If there are too few, use 0 for each scalar ultimate component.  */

    698   

    699      if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)

    700      {

    701        long len;

    702        int i;

    703   

    704        if (TREE_CODE (type) == ARRAY_TYPE)

    705        {

    706          tree domain = TYPE_DOMAIN (type);

    707          if (domain)

    708            len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain))

    709                  - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain))

    710                   + 1);

    711           else

    712            len = -1;  /* Take as many as there are.  */

    713        }

    714        else

    715        {

    716          /* Vectors are like simple fixed-size arrays.  */

    717          len = TYPE_VECTOR_SUBPARTS (type);

    718        }

    719   

    720        for (i = 0; len < 0 || i < len; i++)

    721        {

    722          if (tail)

    723          {

    724            if (TREE_PURPOSE (tail)

    725              && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST

    726                   || compare_tree_int (TREE_PURPOSE (tail), i) != 0))

    727              sorry ("non-trivial labeled initializers");

    728   

    729            if (TREE_VALUE (tail) != 0)

    730            {

    731              tree tail1 = tail;

    732              next1 = digest_init (TREE_TYPE (type),

    733                              TREE_VALUE (tail), &tail1);

    734              if (next1 == error_mark_node)

    735                return next1;

    736              my_friendly_assert

    737                   (same_type_ignoring_top_level_qualifiers_p

    738                         (TREE_TYPE (type), TREE_TYPE (next1)),

    739                         981123);

    740              my_friendly_assert (tail1 == 0

    741                               || TREE_CODE (tail1) == TREE_LIST, 319);

    742              if (tail == tail1 && len < 0)

    743              {

    744                error ("non-empty initializer for array of empty elements");

    745                /* Just ignore what we were supposed to use.  */

    746                tail1 = NULL_TREE;

    747              }

    748              tail = tail1;

    749            }

    750            else

    751            {

    752              next1 = error_mark_node;

    753              tail = TREE_CHAIN (tail);

    754            }

    755          }

    756          else if (len < 0)

    757            /* We're done.  */

    758            break ;

    759          else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type)))

    760          {

                  …

    771          }

    772           else if (! zero_init_p (TREE_TYPE (type)))

    773            next1 = build_zero_init (TREE_TYPE (type),

    774                                /*nelts=*/ NULL_TREE,

    775                                /*static_storage_p=*/ false);

    776          else

    777            /* The default zero-initialization is fine for us; don't

    778              add anything to the CONSTRUCTOR.  */

    779            break ;

    780   

    781          if (next1 == error_mark_node)

    782            erroneous = 1;

    783          else if (!TREE_CONSTANT (next1))

    784            allconstant = 0;

    785          else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1)))

    786            allsimple = 0;

    787          members = tree_cons (size_int (i), next1, members);

    788        }

    789      }

    790      else if (TREE_CODE (type) == RECORD_TYPE)

    791      {

              …

    908      }

    909      else if (TREE_CODE (type) == UNION_TYPE

    910            /* If the initializer was empty, use default zero initialization.  */

    911             && tail)

    912      {

              …

    977      }

    978   

    979      /* If arguments were specified as a list, just remove the ones we used.   */

    980      if (elts)

    981        *elts = tail;

    982      /* If arguments were specified as a constructor,

    983        complain unless we used all the elements of the constructor.  */

    984      else if (tail)

    985        pedwarn ("excess elements in aggregate initializer");

    986   

    987      if (erroneous)

    988        return error_mark_node;

    989   

    990      result = build_constructor (type, nreverse (members));

    991      if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)

    992        complete_array_type (type, result, /*do_default=*/ 0);

    993      if (init)

    994        TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init);

    995      if (allconstant) TREE_CONSTANT (result) = 1;

    996      if (allconstant && allsimple) TREE_STATIC (result) = 1;

    997      return result;

    998    }

     

    Not surprising, for each element of ARRAY_TYPE, digest_init is recursed. Note that in this invocation, argument tail is the initializers. If digest_init can process part of initializers successfully. This part will be removed from the list of initializers. At line 606, convert_for_initialization is invoked to do the possible conversion. Here in our example, no conversion is expected as we prepare init of type vtable_entry_type before hand. As a result, the function returns init as returned value.

    Exitting convert_for_initialization gets out of digest_init immediately, which means this (part) initializer is verified. At line 787, this returned value is chained into members . Next at line 990, new version CONSTRUCTOR is created. See that all elements of vtable should be constant. And this CONSTRUCTOR allocates static storage (i.e, initializes static member). Then at line 4902 in cp_finish_decl , store_init_value returns NULL

     

    cp_finish_decl (continue)

     

    4953     /* Add this declaration to the statement-tree. This needs to happen

    4954       after the call to check_initializer so that the DECL_STMT for a

    4955       reference temp is added before the DECL_STMT for the reference itself.  */

    4956     if (at_function_scope_p ())

    4957       add_decl_stmt (decl);

    4958  

    4959     if (TREE_CODE (decl) == VAR_DECL)

    4960       layout_var_decl (decl);

    4961  

    4962     /* Output the assembler code and/or RTL code for variables and functions,

    4963       unless the type is an undefined structure or union.

    4964       If not, it will get done when the type is completed.  */

    4965     if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)

    4966     {

    4967       if (TREE_CODE (decl) == VAR_DECL)

    4968         maybe_commonize_var (decl);

    4969  

    4970       make_rtl_for_nonlocal_decl (decl, init, asmspec);

    4971  

    4972       if (TREE_CODE (type) == FUNCTION_TYPE

    4973           || TREE_CODE (type) == METHOD_TYPE)

    4974         abstract_virtuals_error (decl,

    4975                              strip_array_types (TREE_TYPE (type)));

    4976       else if (POINTER_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)

    4977       {

    4978         /* If it's either a pointer or an array type, strip through all

    4979            of them but the last one. If the last is an array type, issue

    4980            an error if the element type is abstract.  */

    4981         while (POINTER_TYPE_P (TREE_TYPE (type))

    4982                || TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)

    4983            type = TREE_TYPE (type);

    4984         if (TREE_CODE (type) == ARRAY_TYPE)

    4985            abstract_virtuals_error (decl, TREE_TYPE (type));

    4986       }

    4987       else

    4988         abstract_virtuals_error (decl, type);

    4989  

    4990       if (TREE_CODE (decl) == FUNCTION_DECL

    4991           || TREE_TYPE (decl) == error_mark_node)

    4992         /* No initialization required.  */

    4993         ;

    4994       else if (DECL_EXTERNAL (decl)

    4995              && ! (DECL_LANG_SPECIFIC (decl)

    4996                    && DECL_NOT_REALLY_EXTERN (decl)))

    4997       {

    4998          if (init)

    4999            DECL_INITIAL (decl) = init;

    5000       }

    5001       else

    5002       {

    5003          /* A variable definition.  */

    5004          if (DECL_FUNCTION_SCOPE_P (decl))

    5005          {

    5006            /* This is a local declaration.  */

    5007              maybe_inject_for_scope_var (decl);

    5008            /* Initialize the local variable.  */

    5009            if (processing_template_decl )

    5010           {

    5011              if (init || DECL_INITIAL (decl) == error_mark_node)

    5012                DECL_INITIAL (decl) = init;

    5013           }

    5014            else if (!TREE_STATIC (decl))

    5015             initialize_local_var (decl, init);

    5016          }

    5017  

    5018          /* If a variable is defined, and then a subsequent

    5019             definintion with external linkage is encountered, we will

    5020             get here twice for the same variable. We want to avoid

    5021             calling expand_static_init more than once. For variables

    5022             that are not static data members, we can call

    5023             expand_static_init only when we actually process the

    5024             initializer. It is not legal to redeclare a static data

    5025             member, so this issue does not arise in that case.  */

    5026          if (var_definition_p && TREE_STATIC (decl))

    5027            expand_static_init (decl, init);

    5028       }

    5029   finish_end0:

    5030  

    5031        /* Undo call to `pushclass' that was done in `start_decl'

    5032          due to initialization of qualified member variable.

    5033         I.e., Foo::x = 10;  */

    5034       {

    5035         tree context = CP_DECL_CONTEXT (decl);

    5036         if (context

    5037             && TYPE_P (context)

    5038             && (TREE_CODE (decl) == VAR_DECL

    5039                /* We also have a pushclass done that we need to undo here

    5040                   if we're at top level and declare a method.  */

    5041                || TREE_CODE (decl) == FUNCTION_DECL)

    5042             /* If size hasn't been set, we're still defining it,

    5043               and therefore inside the class body; don't pop

    5044                  the binding level..  */

    5045               && COMPLETE_TYPE_P (context)

    5046               && context == current_class_type )

    5047             pop_nested_class ();

    5048       }

    5049     }

    5050  

    5051     /* If a CLEANUP_STMT was created to destroy a temporary bound to a

    5052       reference, insert it in the statement-tree now.  */

    5053     if (cleanup)

    5054       add_stmt (cleanup);

    5055  

    5056   finish_end:

    5057  

    5058     if (was_readonly)

    5059       TREE_READONLY (decl) = 1;

    5060  

    5061     /* If this was marked 'used', be sure it will be output.  */

    5062     if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))

    5063       mark_referenced (DECL_ASSEMBLER_NAME (decl));

    5064   }

     

    As in initialize_array at line 6809, context of decl is temperarily cleaned, at_function_scope_p at line 4956 returns false. Then maybe_commonize_var at line 4968 handles the situation in which a local static variable is declared in an inline function, or we have a weak definition, for which the compile must endeavor to create only one instance of the variable at link-time.

    Then back cp_finish_decl , at line 4970, within make_rtl_for_nonlocal_decl , the local variable defer_p is set as true at line 4658 as this VAR_DECL has flag DECL_VIRTUAL_P set; further at invocation, asmspec is NULL. So nothing non-trivial is done in this function.

    Next, as var_definition_p is true at line 5026, expand_static_init is invoked, however, as the ARRAY_TYPE of the vtable hasn’t flag TYPE_NEEDS_CONSTRUCTING set, the function exits immediately.

    At last, cleanup at line 5053 may be not NULL if we are handling referecne (here it is NULL). Exitting from cp_finish_decl , we go back finish_struct_1 in below.

     


    最新回复(0)