GCC-3.4.6源代码学习笔记(127)

来源:互联网 发布:视频剪辑软件下载 编辑:程序博客网 时间:2024/06/07 00:28

5.12.4.2.3.2. base-clause构建节点

注意参数base在我们的例子中指向的BOUND_TEMPLATE_TEMPLATE_PARM节点,accessaccess_public_node

 

2242   tree

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

2244   {

2245     tree result;

2246  

2247     if (base == error_mark_node)

2248     {

2249       error ("invalid base-classspecification");

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 cvqualifiers", 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     returnresult;

2266   }

 

在为基类构建了节点后,在前端中这些基类被串接在一起来代表base-clause

5.12.4.2.3.2.1.         填充binfo

cp_parser_base_clause返回,在cp_parser_class_head12339行,由bases指向先前所构建的节点BOUND_TEMPLATE_TEMPLATE_PARM,而type则是代表“SmallObject”的RECORD_TYPE。记得在构建这个RECORD_TYPE时,还构建了一个空的binfo节点。现在这个节点将根据刚才解析的base-clause来填充。

 

9615   void

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

9617   {

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

9619       (A, X, Y, ..., Z) so we cancheck 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 surethat any templates in base-classes are

9637       instantiated. This ensuresthat if we call ourselves recursively

9638       we do not get confused aboutwhich 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 incompletetype. 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 bydefault.  */

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 bea 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 flagwill be in the binfo of the base type, we must

9705              clear it after copyingthe 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 flagwill be in the binfo of the base type, we must

9716           clear it after copying thebase binfos.  */

9717        TREE_VIA_VIRTUAL (base_binfo) = via_virtual;

9718         

9719         SET_CLASSTYPE_MARKED (basetype);

9720         

9721         /* We are free to modify these bits becausethey are meaningless

9722           at top level, and BASETYPEis 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 thevirtual 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 thebase-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 needto 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 ismore 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 basebinfos, 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 havemultiple bases", ref);

9772       if (CLASSTYPE_VBASECLASSES (ref))

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

9774     }

9775  

9776     /* Unmark all thetypes.  */

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   }

 

注意在9645行,在base-clause不能出现未完成的类。而在9765行,基类本身有可能从其他类派生,因此需要深拷贝所有相关的binfo。看到对于指定的类,binfo节点,以深度优先、由左至右为序,形成了一个链表。

 

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

 

虚拟继承是例外,在这个情形下,被虚拟继承的基类只能有一个实例出现在派生树中。因此如果该实例已经存在,创建一个引用而不是拷贝(注意每个类都有自己的派生树)。例如:

class A { … };

class B: virtual public A { …};

class C: virtual public A { …};

class D: public B, C { … };

在类D中,仅含有一个Abinfo。而在类BC中,同样都有一个Abinfo(类DCB具有不同的派生树,在D的派生树中,有CBbinfo的拷贝)。

注意到对于BOUND_TEMPLATE_TEMPLATE_PARM.节点,CLASS_TYPE_P返回false。这是隐含构建的聚合类型,不需要真正的拷贝。那么“SmallObject”和“ThreadingModel”的binfo填充如下。

点此打开

114:填充binfo

5.12.4.3.             解析class-definition

那么接下来,解析器将处理class-definition部分。它与我们在前面章节所看到处理过程几乎一样。这里我们跳过它。

 

原创粉丝点击