Studying note of GCC-3.4.6 source (63)

4.3.1.7.7.            C++ components with C++ linkage
4.3.1.7.7.1.      bad_alloc

current_lang_name indicates the language of the program, now it is updated to the identifier of C++ language. It determines the linkage of identifiers. For example, C++’s identifier has its name mangled, but not does C’s identifier.

 

cxx_init_decl_processing (continue)

 

3080     /* Now, C++.  */

3081     current_lang_name = lang_name_cplusplus;

3082  

3083     {

3084       tree bad_alloc_id;

3085       tree bad_alloc_type_node;

3086       tree bad_alloc_decl;

3087       tree newtype, deltype;

3088       tree ptr_ftype_sizetype;

3089  

3090       push_namespace (std_identifier);

3091       bad_alloc_id = get_identifier ("bad_alloc");

3092       bad_alloc_type_node = make_aggr_type (RECORD_TYPE);

3093       TYPE_CONTEXT (bad_alloc_type_node) = current_namespace ;

3094       bad_alloc_decl

3095         = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);

3096       DECL_CONTEXT (bad_alloc_decl) = current_namespace ;

3097       TYPE_STUB_DECL (bad_alloc_type_node) = bad_alloc_decl;

3098       pop_namespace ();

 

For C++, a very important operator new is offered within std namespace which is replacement for malloc in C. For the standard behavor of this operator, if no memory allocated exception std::bad_alloc will be thrown. Below bad_alloc type will be created, but it is somewhat like placeholder, because this is an empty type definition, not the real definition. Later if user uses bad_alloc (for example invoking new operator), by including header file <new>, the real bad_alloc definition will be parsed to generate the final correct node; while if nowhere to use bad_alloc , this fake definition will be left untouched.

 

859    tree

860    make_aggr_type (enum tree_code code)                                                           in lex.c

861    {

862      tree t = cxx_make_type (code);

863   

864      if (IS_AGGR_TYPE_CODE (code))

865        SET_IS_AGGR_TYPE (t, 1);

866   

867      return t;

868    }

 

Notice that the aggregate type (class/struct/union) created by make_aggr_type hasn’t any field. It is just an empty object definition.

 

808    tree

809    cxx_make_type (enum tree_code code)                                                             in lex.c

810    {

811       tree t = make_node (code);

812   

813      /* Create lang_type structure.  */

814      if (IS_AGGR_TYPE_CODE (code)

815          || code == BOUND_TEMPLATE_TEMPLATE_PARM)

816      {

817        struct lang_type *pi;

818   

819        pi = ggc_alloc_cleared (sizeof (struct lang_type));

820   

821        TYPE_LANG_SPECIFIC (t) = pi;

822        pi->u.c.h.is_lang_type_class = 1;

823   

824    #ifdef GATHER_STATISTICS

825        tree_node_counts [(int)lang_type] += 1;

826        tree_node_sizes [(int)lang_type] += sizeof (struct lang_type);

827    #endif

828      }

829   

830      /* Set up some flags that give proper default behavior.  */

831      if (IS_AGGR_TYPE_CODE (code))

832      {

833        SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown );

834        CLASSTYPE_INTERFACE_ONLY (t) = interface_only ;

835   

836        /* Make sure this is laid out, for ease of use later. In the

837          presence of parse errors, the normal was of assuring this

838          might not ever get executed, so we lay it out *immediately*.  */

839        build_pointer_type (t);

840      }

841      else

842        /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But,

843          TYPE_ALIAS_SET is initialized to -1 by default, so we must

844          clear it here.  */

845        TYPE_ALIAS_SET (t) = 0;

846   

847      /* We need to allocate a TYPE_BINFO even for TEMPLATE_TYPE_PARMs

848        since they can be virtual base types, and we then need a

849        canonical binfo for them. Ideally, this would be done lazily for

850        all types.  */

851      if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM

852          || code == BOUND_TEMPLATE_TEMPLATE_PARM

853          || code == TYPENAME_TYPE)

854        TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE);

855   

856      return t;

857    }

 

For language supporting object oriented programing, the aggregate type (struct/class/union in C++ for example) must find a way to record the relationship among it, its derived sub-classes and its inherited base-classes. It is the binfo node in the type. Here as we have mentioned, the binfo node created here is also empty.

Also notice that, this created fake bad_alloc node is not inserted into the namespace really, but set this node’s context by the namespace. It is because this type is undefined and not usable.

4.3.1.7.7.2.      Details of binfo and basetype

In C++, non-virtual drivation always leads to layout as following, for example X derives from Y, then Y from Z.

39

Figure 39 : layout with non-virtual inheritage

While for virtual drivation, for example X derives from Y, then Y virtually from Z. The layout will look like:

40

Figure 40 : layout with virtual inheritage

A basetype means a particular usage of a data type for inheritance in another type. Each such basetype usage has its own binfo object to describe it. The binfo object is a TREE_VEC node. Inheritance is represented by the binfo nodes allocated for a given type. For example, given types X and Y, such that Y is inherited by X, 3 binfo nodes will be allocated: one for describing the binfo properties of X, similarly one for Y, and one for describing the binfo properties of Y as a base type for X. Thus, given a pointer to class X, one can get a pointer to the binfo of Y acting as a basetype for X by looking at X's binfo's basetypes .

41

Figure 41 : relation of binfos

The content of binfo as TREE_VEC for C++ is (content enclosed by [] indicates the macros to access the fields):

Pos 0: [BINFO_INHERITANCE_CHAIN ] Slot used to build a chain that represents a use of inheritance. For example, if X is derived from Y, and Y is derived from Z, then this field can be used to link the binfo node for X to the binfo node for X's Y to represent the use of inheritance from X to Y. Similarly, this slot of the binfo node for X's Y can point to the Z from which Y is inherited (in X's inheritance hierarchy). In this fashion, one can represent and traverse specific uses of inheritance using the binfo nodes themselves (instead of consing new space pointing to binfo nodes). It is up to the language-dependent front-ends to maintain this information as necessary.

Pos 1: [BINFO_OFFSET ] The offset where this basetype appears in its containing type. The slot holds the offset (in bytes) from the base of the complete object to the base of the part of the object that is allocated on behalf of this type. This is always 0 except when there are multiple inheritances.

Pos 2: [BINFO_VTABLE ] The virtual function table belonging to this basetype . Virtual function tables provide a mechanism for run-time method dispatching. The entries of a virtual function table are language-dependent.

Pos 3: [BINFO_VIRTUALS ] The virtual functions in the virtual function table. It is a tree_list that is used as an initial approximation for building a virtual function table for this basetype.

Pos 4: [BINFO_BASETYPES ] A vector of binfos for the direct basetypes inherited by this basetype . If this basetype describes type D as inherited in C, and if the basetypes of D are E and F, then this vector contains binfos for inheritance of E and F by C.

Pos 5: [BINFO_VPTR_FIELD ] A binfo record describing a virtual base class, i.e., one where TREE_VIA_VIRTUAL is set, this field assists in locating the virtual base. The actual contents are language-dependent. In the C++ front-end this field is an INTEGER_CST giving an offset into the vtable where the offset to the virtual base can be found.

Pos 6: [BINFO_BASEACCESSES ] Indicates the accesses this binfo has to its bases. The values are access_public_node , access_proected_node or access_private_node . If this array is not present, public access is implied.

Pos 7: [BINFO_SUBVTT_INDEX ] The index in the VTT where this subobject's sub-VTT can be found. NULL_TREE if there is no subVTT (C++ specific).

A class requires a VTT if it has virtual bases. This holds:

1 - primary virtual pointer for complete object of the class.

2 - secondary VTTs for each direct non-virtual base of the class which requires a VTT

3 - secondary virtual pointers for each direct or indirect base of the class which has virtual bases or is reachable via a virtual path from the class.

4 - secondary VTTs for each direct or indirect virtual base of the class.

Secondary VTTs look like complete object VTTs without part 4.

Pos 8: [BINFO_VPTR_INDEX ] The index in the VTT where the vptr for this subobject can be found. NULL_TREE if there is no secndary vptr in the VTT (C++ specific). It is the primary vptr mentioned in Pos 7 above.

Pos 9: [BINFO_PRIMARY_BASE_OF ] The binfo of which node is a primary base. It is different from BINFO_INHERITANCE_CHAIN for virtual base because a virtual base is sometimes a primary base for a class for which it is not an immediate base (C++ specific).

make_binfo is a very basic function for creating binfo. For preparing binfo for normal “large” class that appears in program, the function will be xref_basetypes which invokes make_binfo when new binfo is expected.

 

771    tree

772    make_binfo (tree offset, tree binfo, tree vtable, tree virtuals)                       in cp/tree.c

773    {

774      tree new_binfo = make_tree_vec (BINFO_LANG_ELTS);

775      tree type;

776   

777      if (TREE_CODE (binfo) == TREE_VEC)

778      {

779        type = BINFO_TYPE (binfo);

780        BINFO_DEPENDENT_BASE_P(new_binfo)=BINFO_DEPENDENT_BASE_P(binfo);

781      }

782      else

783      {

784        type = binfo;

785        binfo = NULL_TREE;

786        BINFO_DEPENDENT_BASE_P (new_binfo) = 1;

787      }

788   

789      TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type);

790      BINFO_OFFSET (new_binfo) = offset;

791      BINFO_VTABLE (new_binfo) = vtable;

792      BINFO_VIRTUALS (new_binfo) = virtuals;

793   

794      if (binfo && !BINFO_DEPENDENT_BASE_P (binfo)

795          && BINFO_BASETYPES (binfo) != NULL_TREE)

796      {

797        BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo));

798        /* We do not need to copy the accesses, as they are read only.  */

799        BINFO_BASEACCESSES (new_binfo) = BINFO_BASEACCESSES (binfo);

800      }

801      return new_binfo;

802    }

 

At line 786, BINFO_DEPENDENT_BASE_P marks the binfo is a dependent base, and should not be searched within the inheritance link. The examples are bad_alloc_type_node here, template type parameters, and typename types. After creating bad_alloc_type_node , it is not finished. Remember in C++, you don't have to write struct S when refer to S ; you can just use S . We accomplish this by create_implicit_typedef to create a TYPE_DECL as if the user had written typedef struct S S .

 

930    tree

931    create_implicit_typedef (tree name, tree type)                                                   in decl.c

932    {

933      tree decl;

934   

935      decl = build_decl (TYPE_DECL, name, type);

936      DECL_ARTIFICIAL (decl) = 1;

937      /* There are other implicit type declarations, like the one *within*

938        a class that allows you to write `S::S'. We must distinguish

939        amongst these.  */

940      SET_DECL_IMPLICIT_TYPEDEF_P (decl);

941      TYPE_NAME (type) = decl;

942   

943      return decl;

944    }

 

And, in the front-end, class/struct will both be created into RECORD_TYPE (that is why some C++ course acclaims that struct and class havn’t essential difference), thus at line 864 in make_aggr_type , IS_AGGR_TYPE_CODE returns true for RECORD_TYPE and UNION_TYPE.

4.3.1.7.7.2.      Operator new and delete

Exception bad_alloc though you can use it in your program, initially it just associates with operator new and new[] for C++, which is part of the standard. It needs bind bad_alloc with these operators. In section Initialize data for operators , nodes of identifiers have been created, but not nodes of declaraction. Thus at line 3100, new and new[] are created as type of void* f(size_t) .

 

cxx_init_decl_processing (continue)

 

3100       ptr_ftype_sizetype

3101         = build_function_type (ptr_type_node,

3102                            tree_cons (NULL_TREE,

3103                                     size_type_node,

3104                                     void_list_node));

3105       newtype = build_exception_variant

3106                     (ptr_ftype_sizetype, add_exception_specifier

3107                                      (NULL_TREE, bad_alloc_type_node, -1));

3108       deltype = build_exception_variant (void_ftype_ptr, empty_except_spec);

3109       push_cp_library_fn (NEW_EXPR, newtype);

3110       push_cp_library_fn (VEC_NEW_EXPR, newtype);

3111       global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);

3112       push_cp_library_fn (VEC_DELETE_EXPR, deltype);

3113     }

 

However type void* f(size_t) is not the exact one, the correct one should be void* f(size_t) throw bad_alloc . This variant declaration is created by build_exception_variant . As a function can throw more than one kind exception, the second parameter of build_exception_variant should be a tree_list, which is prepared by add_exception_specifier .

 

1277   tree

1278   add_exception_specifier (tree list, tree spec, int complain)                           in typeck2.c

1279   {

1280     bool ok;

1281     tree core = spec;

1282     bool is_ptr;

1283     int diag_type = -1; /* none */

1284    

1285     if (spec == error_mark_node)

1286       return list;

1287    

1288     my_friendly_assert (spec && (!list || TREE_VALUE (list)), 19990317);

1289    

1290     /* [except.spec] 1, type in an exception specifier shall not be

1291       incomplete, or pointer or ref to incomplete other than pointer

1292       to cv void.  */

1293     is_ptr = TREE_CODE (core) == POINTER_TYPE;

1294     if (is_ptr || TREE_CODE (core) == REFERENCE_TYPE)

1295       core = TREE_TYPE (core);

1296     if (complain < 0)

1297       ok = true;

1298     else if (VOID_TYPE_P (core))

1299       ok = is_ptr;

1300     else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)

1301       ok = true;

1302     else if (processing_template_decl)

1303       ok = true;

1304     else

1305     {

1306       ok = true;

1307       /* 15.4/1 says that types in an exception specifier must be complete,

1308         but it seems more reasonable to only require this on definitions

1309         and calls. So just give a pedwarn at this point; we will give an

1310         error later if we hit one of those two cases.  */

1311       if (!COMPLETE_TYPE_P (complete_type (core)))

1312         diag_type = 2; /* pedwarn */

1313     }

1314  

1315     if (ok)

1316     {

1317       tree probe;

1318        

1319       for (probe = list; probe; probe = TREE_CHAIN (probe))

1320         if (same_type_p (TREE_VALUE (probe), spec))

1321            break ;

1322       if (!probe)

1323         list = tree_cons (NULL_TREE, spec, list);

1324     }

1325     else

1326       diag_type = 0; /* error */

1327      

1328     if (diag_type >= 0 && complain)

1329       cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type);

1330  

1331     return list;

1332   }

 

As the type node is ready, it should create declaration node for the operators and push the created declarations into the “std” namespace. The library functions here have C++ linkage.

 

3370   static tree

3371   push_cp_library_fn (enum tree_code operator_code, tree type)                           in decl.c

3372   {

3373     tree fn = build_cp_library_fn (ansi_opname (operator_code),

3374                             operator_code,

3375                             type);

3376     pushdecl (fn);

3377     return fn;

3378   }

 

ansi_opname fetches node of identifier for the operator.

 

868    #define ansi_opname (CODE) /                                                                  in cp-tree.h

869      (operator_name_info [(int) (CODE)].identifier)

 

3327   static tree

3328   build_cp_library_fn (tree name, enum tree_code operator_code, tree type)           in decl.c

3329   {

3330     tree fn = build_library_fn_1 (name, operator_code, type);

3331     TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);

3332     DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);

3333     SET_DECL_LANGUAGE (fn, lang_cplusplus);

3334     set_mangled_name_for_decl (fn);

3335     return fn;

3336   }

 

set_mangled_name_for_decl above will create the mangled name for the function and set it into DECL_ASSEMBLER_NAME. Then the created FUNCTION_DECL is pushed into std namespace by pushdecl exactly as section Push the FUNCTION_DECL Into current namespace .

 

 

 

 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
for Policy and Practice, 2018, 17(2): 179-195. In this article, Victor Wang Chen Neo examines the implementation of school-based curriculum development (SBCD) in Singapore. SBCD is a process where schools are given greater autonomy to develop and implement their own curriculum, rather than following a standardized national curriculum. The author begins by providing an overview of the history of curriculum development in Singapore, and how the shift towards SBCD came about. He then presents the findings of a study that he conducted, which involved interviews with school leaders who had implemented SBCD in their schools. The author identifies several factors that influenced the successful implementation of SBCD in these schools. These include strong leadership, a clear vision and direction for the school, and a focus on student learning and development. The author also highlights the importance of teacher training and support, as well as collaboration and communication among all stakeholders involved in the curriculum development process. However, the author also notes some challenges that schools face when implementing SBCD. These include a lack of resources, such as time and funding, as well as the need to balance autonomy with accountability to ensure that the curriculum developed meets national standards. Overall, the author suggests that SBCD has the potential to improve the quality of education in Singapore by allowing schools to tailor their curriculum to the needs and interests of their students. However, he also calls for continued support and guidance from the government to ensure that schools are able to implement SBCD effectively.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值