Studying note of GCC-3.4.6 source (127)

5.12.4.2.3.2.  Build nodes for base-clause

Notice that argument base refers to the BOUND_TEMPLATE_TEMPLATE_PARM node for our example, and access is access_public_node .

 

2242   tree

2243   finish_base_specifier (tree base, tree access, bool virtual_p)                 in semantics.c

2244   {

2245     tree result;

2246  

2247     if (base == error_mark_node)

2248     {

2249       error ("invalid base-class specification");

2250       result = NULL_TREE;

2251     }

2252     else if (! is_aggr_type (base, 1))

2253       result = NULL_TREE;

2254     else

2255     {

2256       if (cp_type_quals (base) != 0)

2257       {

2258         error ("base class `%T' has cv qualifiers", base);

2259         base = TYPE_MAIN_VARIANT (base);

2260       }

2261       result = build_tree_list (access, base);

2262       TREE_VIA_VIRTUAL (result) = virtual_p;

2263     }

2264  

2265     return result;

2266   }

 

After creating the node for the base, these bases are chained tegother to stand for the base-clause in the front-end.

5.12.4.2.3.2.1.          Fill up binfo

Back from cp_parser_base_clause , in cp_parser_class_head at line 12339, now bases refers to the node of BOUND_TEMPLATE_TEMPLATE_PARM just created, and type is the RECORD_TYPE for “SmallObject”. Remember when creating this RECORD_TYPE, an empty binfo node is created too. Now this node should be filled up according to the base-clause parsed.

 

9615   void

9616   xref_basetypes (tree ref, tree base_list)                                                             in decl.c

9617   {

9618     /* In the declaration `A : X, Y, ... Z' we mark all the types

9619       (A, X, Y, ..., Z) so we can check for duplicates.  */

9620     tree *basep;

9621  

9622     int i;

9623     enum tag_types tag_code;

9624  

9625     if (ref == error_mark_node)

9626       return ;

9627  

9628     if (TREE_CODE (ref) == UNION_TYPE)

9629     {

9630       error ("derived union `%T' invalid", ref);

9631       return ;

9632     }

9633  

9634     tag_code = (CLASSTYPE_DECLARED_CLASS (ref) ? class_type : record_type);

9635  

9636     /* First, make sure that any templates in base-classes are

9637       instantiated. This ensures that if we call ourselves recursively

9638       we do not get confused about which classes are marked and which

9639       are not.  */

9640     basep = &base_list;

9641     while (*basep)

9642     {

9643       tree basetype = TREE_VALUE (*basep);

9644       if (!(processing_template_decl && uses_template_parms (basetype))

9645           && !complete_type_or_else (basetype, NULL))

9646         /* An incomplete type. Remove it from the list.  */

9647         *basep = TREE_CHAIN (*basep);

9648       else

9649         basep = &TREE_CHAIN (*basep);

9650     }

9651  

9652     SET_CLASSTYPE_MARKED (ref);

9653     i = list_length (base_list);

9654     if (i)

9655     {

9656       tree binfo = TYPE_BINFO (ref);

9657       tree binfos = make_tree_vec (i);

9658       tree accesses = make_tree_vec (i);

9659        

9660       BINFO_BASETYPES (binfo) = binfos;

9661       BINFO_BASEACCESSES (binfo) = accesses;

9662    

9663       for (i = 0; base_list; base_list = TREE_CHAIN (base_list))

9664       {

9665         tree access = TREE_PURPOSE (base_list);

9666         int via_virtual = TREE_VIA_VIRTUAL (base_list);

9667         tree basetype = TREE_VALUE (base_list);

9668         tree base_binfo;

9669         

9670         if (access == access_default_node)

9671            /* The base of a derived struct is public by default.  */

9672           access = (tag_code == class_type

9673                   ? access_private_node : access_public_node);

9674         

9675         if (basetype && TREE_CODE (basetype) == TYPE_DECL)

9676           basetype = TREE_TYPE (basetype);

9677         if (!basetype

9678            || (TREE_CODE (basetype) != RECORD_TYPE

9679              && TREE_CODE (basetype) != TYPENAME_TYPE

9680              && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM

9681              && TREE_CODE (basetype) != BOUND_TEMPLATE_TEMPLATE_PARM))

9682         {

9683           error ("base type `%T' fails to be a struct or class type",

9684                 basetype);

9685           continue ;

9686         }

9687         

9688         if (CLASSTYPE_MARKED (basetype))

9689         {

9690            if (basetype == ref)

9691             error ("recursive type `%T' undefined", basetype);

9692           else

9693             error ("duplicate base type `%T' invalid", basetype);

9694           continue ;

9695         }

9696         

9697         if (TYPE_FOR_JAVA (basetype)

9698            && (current_lang_depth () == 0))

9699           TYPE_FOR_JAVA (ref) = 1;

9700         

9701         if (CLASS_TYPE_P (basetype))

9702         {

9703           base_binfo = TYPE_BINFO (basetype);

9704            /* This flag will be in the binfo of the base type, we must

9705              clear it after copying the base binfos.  */

9706            BINFO_DEPENDENT_BASE_P (base_binfo)

9707                 = dependent_type_p (basetype);

9708         }

9709         else

9710           base_binfo = make_binfo (size_zero_node, basetype,

9711                                 NULL_TREE, NULL_TREE);

9712         

9713         TREE_VEC_ELT (binfos, i) = base_binfo;

9714         TREE_VEC_ELT (accesses, i) = access;

9715         /* This flag will be in the binfo of the base type, we must

9716           clear it after copying the base binfos.  */

9717         TREE_VIA_VIRTUAL (base_binfo) = via_virtual;

9718         

9719         SET_CLASSTYPE_MARKED (basetype);

9720         

9721          /* We are free to modify these bits because they are meaningless

9722           at top level, and BASETYPE is a top-level type.  */

9723         if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype))

9724         {

9725           TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1;

9726            /* Converting to a virtual base class requires looking

9727              up the offset of the virtual base.  */

9728            TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;

9729         }

9730         

9731         if (CLASS_TYPE_P (basetype))

9732         {

9733           TYPE_HAS_NEW_OPERATOR (ref)

9734               |= TYPE_HAS_NEW_OPERATOR (basetype);

9735           TYPE_HAS_ARRAY_NEW_OPERATOR (ref)

9736               |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);

9737           TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);

9738           /* If the base-class uses multiple inheritance, so do we.  */

9739           TYPE_USES_MULTIPLE_INHERITANCE (ref)

9740               |= TYPE_USES_MULTIPLE_INHERITANCE (basetype);

9741           /* Likewise, if converting to a base of the base may require

9742             code, then we may need to generate code to convert to a

9743             base as well.  */

9744           TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref)

9745               |= TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (basetype);

9746         }

9747         i++;

9748       }

9749       if (i)

9750         TREE_VEC_LENGTH (accesses) = TREE_VEC_LENGTH (binfos) = i;

9751       else

9752         BINFO_BASEACCESSES (binfo) = BINFO_BASETYPES (binfo) = NULL_TREE;

9753        

9754       if (i > 1)

9755       {

9756         TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1;

9757         /* If there is more than one non-empty they cannot be at the same

9758           address.  */

9759         TYPE_BASE_CONVS_MAY_REQUIRE_CODE_P (ref) = 1;

9760       }

9761     }

9762    

9763     /* Copy the base binfos, collect the virtual bases and set the

9764       inheritance order chain.  */

9765     copy_base_binfos (TYPE_BINFO (ref), ref, NULL_TREE);

9766     CLASSTYPE_VBASECLASSES (ref) = nreverse (CLASSTYPE_VBASECLASSES (ref));

9767  

9768     if (TYPE_FOR_JAVA (ref))

9769     {

9770       if (TYPE_USES_MULTIPLE_INHERITANCE (ref))

9771         error ("Java class '%T' cannot have multiple bases", ref);

9772       if (CLASSTYPE_VBASECLASSES (ref))

9773         error ("Java class '%T' cannot have virtual bases", ref);

9774     }

9775  

9776     /* Unmark all the types.  */

9777     while (i--)

9778     {

9779       tree basetype = BINFO_TYPE (BINFO_BASETYPE (TYPE_BINFO (ref), i));

9780        

9781       CLEAR_CLASSTYPE_MARKED (basetype);

9782       if (CLASS_TYPE_P (basetype))

9783       {

9784         TREE_VIA_VIRTUAL (TYPE_BINFO (basetype)) = 0;

9785         BINFO_DEPENDENT_BASE_P (TYPE_BINFO (basetype)) = 0;

9786       }

9787     }

9788     CLEAR_CLASSTYPE_MARKED (ref);

9789   }

 

Notice that at line 9645, incomplete type can’t appear in base-clause. And at line 9765, the bases themselves may also inherit from other classes, so it needs deep copy to get all related binfos. See that for specified class, the binfos form a list with deep-first, left-to-right order.

 

577    tree

578    copy_base_binfos (tree binfo, tree t, tree prev)                                                         in tree.c

579    {

580      tree binfos = BINFO_BASETYPES (binfo);

581      int n, ix;

582   

583      if (prev)

584        TREE_CHAIN (prev) = binfo;

585      prev = binfo;

586     

587      if (binfos == NULL_TREE)

588        return prev;

589   

590      n = TREE_VEC_LENGTH (binfos);

591     

592      /* Now copy the structure beneath BINFO.  */

593      for (ix = 0; ix != n; ix++)

594      {

595        tree base_binfo = TREE_VEC_ELT (binfos, ix);

596        tree new_binfo = NULL_TREE;

597   

598        if (!CLASS_TYPE_P (BINFO_TYPE (base_binfo)))

599        {

600          my_friendly_assert (binfo == TYPE_BINFO (t), 20030204);

601          

602          new_binfo = base_binfo;

603          TREE_CHAIN (prev) = new_binfo;

604          prev = new_binfo;

605          BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;

606          BINFO_DEPENDENT_BASE_P (new_binfo) = 1;

607        }

608        else if (TREE_VIA_VIRTUAL (base_binfo))

609        {

610          new_binfo = purpose_member (BINFO_TYPE (base_binfo),

611                                     CLASSTYPE_VBASECLASSES (t));

612          if (new_binfo)

613            new_binfo = TREE_VALUE (new_binfo);

614        }

615         

616        if (!new_binfo)

617        {

618          new_binfo = make_binfo (BINFO_OFFSET (base_binfo),

619                                base_binfo, NULL_TREE,

620                                BINFO_VIRTUALS (base_binfo));

621          prev = copy_base_binfos (new_binfo, t, prev);

622          if (TREE_VIA_VIRTUAL (base_binfo))

623          {

624            CLASSTYPE_VBASECLASSES (t)

625                 = tree_cons (BINFO_TYPE (new_binfo), new_binfo,

626                           CLASSTYPE_VBASECLASSES (t));

627            TREE_VIA_VIRTUAL (new_binfo) = 1;

628            BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);

629          }

630          else

631            BINFO_INHERITANCE_CHAIN (new_binfo) = binfo;

632        }

633        TREE_VEC_ELT (binfos, ix) = new_binfo;

634      }

635   

636      return prev;

637    }

 

The execption is the virtual inheritage, for which only one instance of virtual inherited base should be present in the tree. So a reference instead of copy is created if the instance already exists (note that every class has its own inheritent tree). For example:

class A { … };

class B: virtual public A { … };

class C: virtual public A { … };

class D: public B, C { … };

In class D, only one binfo of A exists. And in class B and C there are also single binfo of A (class D, C, B have different inheritent tree, in inheritent tree of D there is copy binfo of C and B).

Note that CLASS_TYPE_P returns false for BOUND_TEMPLATE_TEMPLATE_PARM. This is the implicit created aggregate type, no needs real copy. As result, the binfo of “SmallObject” and “ThreadingModel” are filled as following.

(Click here for open )

Figure 114 : fill up binfo

5.12.4.3.              Parse class-definition

Then following, the parser will take up the class-definition. It is the procedure mostly the same as we have seen in previous section. We just skip it.

 

你可能感兴趣的:(Studying note of GCC-3.4.6 source (127))