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.
In C++, non-virtual drivation always leads to layout as following, for example X derives from Y, then Y from Z.
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:
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 .
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.
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 .