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

5.12.3.2.1.1.1.4.    加入类的TYPE_DECL

现在d是被TEMPLATE_DECLresults域所指向的TYPE_DECL,并由push_template_decl_real所返回。而b是在函数开头就找到的名字空间“Loki”的作用域。

 

pushtag (continue)

 

4659       if (b->kind == sk_class)

4660       {

4661         if (!PROCESSING_REAL_TEMPLATE_DECL_P ())

4662            /* Put this TYPE_DECL on the TYPE_FIELDS list for the

4663              class. But if it's a member template class, we

4664              want the TEMPLATE_DECL, not the TYPE_DECL, so this

4665              is done later.  */

4666            finish_member_declaration (d);

4667         else

4668            pushdecl_class_level (d);

4669       }

4670       else

4671         d = pushdecl_with_scope (d, b);

 

再一次,我们将进入pushdecl,这一次是执行以下的代码。参数x是由pushdecl_with_scope传递的d

 

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;

       

604      name = DECL_NAME (x);

605      if (name)

606      {

        

772        /* If declaring a type as a typedef, copy the type (unless we're

773          at line 0), and install this TYPE_DECL as the new type's typedef

774          name. See the extensive comment in ../c-decl.c (pushdecl).  */

775        if (TREE_CODE (x) == TYPE_DECL)

776        {

777          tree type = TREE_TYPE (x);

           

797          if (type != error_mark_node

798             && TYPE_NAME (type)

799             && TYPE_IDENTIFIER (type))

800            set_identifier_type_value (DECL_NAME (x), x);

801        }

        

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   }

 

这里的TYPE_DECLTEMPLATE_DECL共享同一个名字,而且这个名字在push_template_decl_real3006行,已经被加入到名字空间中;因此,上面的t指向TEMPLATE_DECL。然后上面的set_identifier_type_value在找到这个TEMPLATE_DECLcxx_binding对象后,调用supplement_binding以下面的方式更新这个cxx_binding对象。

 

431    static bool

432    supplement_binding (cxx_binding *binding, tree decl)                         in name-lookup.c

433    {

434      tree bval = binding->value;

435      bool ok = true;

436   

437      timevar_push (TV_NAME_LOOKUP);

438      if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))

439        /* The new name is the type name.  */

440        binding->type = decl;

441      else if (/* BVAL is null when push_class_level_binding moves an

442              inherited type-binding out of the way to make room for a

443              new value binding.  */

444            !bval

445            /* BVAL is error_mark_node when DECL's name has been used

446              in a non-class scope prior declaration. In that case,

447              we should have already issued a diagnostic; for graceful

448              error recovery purpose, pretend this was the intended

449              declaration for that name.  */

450            || bval == error_mark_node

451            /* If BVAL is a built-in that has not yet been declared,

452              pretend it is not there at all.  */

453            || (TREE_CODE (bval) == FUNCTION_DECL

454               && DECL_ANTICIPATED (bval)))

455        binding->value = decl;

456      else if (TREE_CODE (bval) == TYPE_DECL && DECL_ARTIFICIAL (bval))

457      {

458        /* The old binding was a type name. It was placed in

459          VALUE field because it was thought, at the point it was

460          declared, to be the only entity with such a name. Move the

461          type name into the type slot; it is now hidden by the new

462          binding.  */

463        binding->type = bval;

464        binding->value = decl;

465        binding->value_is_inherited = false;

466      }

       

518      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);

519    }

 

看到438行的条件被满足。接下来,在1010add_decl_to_levelTYPE_DECL记录到作用域的names域中。那么当从pushdecl_with_scope返回时,中间树看起来就像:

 

点此打开

57:加入类SingleThreaded的标签第四步

注意到在这一步,TYPE_DECLTEMPLATE_DECL被“Loki”的cxx_scope对象的names域串接在一起,它们表示在该域中可见的项。

 

pushtag (continue)

 

4673       /* FIXME what if it gets a name from typedef?  */

4674       if (ANON_AGGRNAME_P (name))

4675         DECL_IGNORED_P (d) = 1;

4676

4677       TYPE_CONTEXT (type) = DECL_CONTEXT (d);

4678

4679       /* If this is a local class, keep track of it. We need this

4680         information for name-mangling, and so that it is possible to find

4681         all function definitions in a translation unit in a convenient

4682         way. (It's otherwise tricky to find a member function definition

4683         it's only pointed to from within a local class.)  */

4684       if (TYPE_CONTEXT (type)

4685          && TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL

4686          && !processing_template_decl)

4687         VARRAY_PUSH_TREE (local_classes, type);

4688     }

4689     if (b->kind == sk_class

4690        && !COMPLETE_TYPE_P (current_class_type))

4691     {

4692       maybe_add_class_template_decl_list (current_class_type,

4693                                      type, /*friend_p=*/0);

4694       CLASSTYPE_NESTED_UTDS (current_class_type) = b->type_decls;

4695     }

4696   }

4697

4698   if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)

4699     /* Use the canonical TYPE_DECL for this node.  */

4700     TYPE_STUB_DECL (type) = TYPE_NAME (type);

4701   else

4702   {

4703     /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE

4704       will be the tagged type we just added to the current

4705       binding level. This fake NULL-named TYPE_DECL node helps

4706       dwarfout.c to know when it needs to output a

4707       representation of a tagged type, and it also gives us a

4708       convenient place to record the "scope start" address for

4709       the tagged type.  */

4710

4711     tree d = build_decl (TYPE_DECL, NULL_TREE, type);

4712     TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b);

4713   }

4714   timevar_pop (TV_NAME_LOOKUP);

4715 }

 

那么余下代码的重要操作就是更新RECORD_TYPEcontext域。

 

点此打开

58:加入类SingleThreaded的标签第五步

 

cp_parser_class_head (continue)

 

12317   /* Indicate whether this class was declared as a `class' or as a

12318     `struct'.  */

12319   if (TREE_CODE (type) == RECORD_TYPE)

12320     CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);

12321   cp_parser_check_class_key (class_key, type);

12322

12323   /* Enter the scope containing the class; the names of base classes

12324     should be looked up in that context. For example, given:

12325

12326        struct A { struct B {}; struct C; };

12327        struct A::C : B {};

12328

12329     is valid.  */

12330   if (nested_name_specifier)

12331     pop_p = push_scope (nested_name_specifier);

12332  /* Now, look for the base-clause.  */

12333   token = cp_lexer_peek_token (parser->lexer);

12334   if (token->type == CPP_COLON)

12335   {

12336     tree bases;

12337

12338     /* Get the list of base-classes.  */

12339     bases = cp_parser_base_clause (parser);

12340     /* Process them.  */

12341     xref_basetypes (type, bases);

12342   }

12343   /* Leave the scope given by the nested-name-specifier. We will

12344     enter the class scope itself while processing the members.  */

12345   if (pop_p)

12346     pop_scope (nested_name_specifier);

12347

12348 done:

12349   if (invalid_explicit_specialization_p)

12350   {

12351     end_specialization ();

12352     --parser->num_template_parameter_lists;

12353   }

12354   *attributes_p = attributes;

12355   return type;

12356 }

 

对于我们的例子,在类名及“{”之间没有符号出现,并且因为没有nested-name-specifier 部分nested_name_specifierNULL,上面的代码仅是在1231912320行重新检查声明的有效性。看到变量type是由xref_tag返回的RECORD_TYPE节点。并且它又被这里的函数返回给其调用者。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值