Studying note of GCC-3.4.6 source (104)
来源:互联网 发布:qq同步mac电脑版 编辑:程序博客网 时间:2024/05/16 12:01
5.12.3.2.1.1.3.5.3. Finish
With returned arg_typesand parms,at line 7601 in grokdeclarator, build_function_type createsnode of FUNCTION_TYPE as following.
(Clickhere for open)
Figure 81:FUNCTION_TYPE created
Now nodesrelated to CALL_EXPR are useless, as no reference to CALL_EXPR node. Then atline 8240 in grokdeclarator,build_method_type_directly creates node of METHOD_TYPE as following.
(Clickhere for open)
Figure 82:METHOD_TYPE created
Immediately atline 8250 in grokdeclarator,grokfndecl creates node of FUNCTION_DECL as below.
(Clickhere for open)
Figure 83:FUNCTION_DECL created
When returnsback start_method,after pushing corresponding nodes of template declaration, it gets followingintermediate tree.
(Clickhere for open)
Figure 84:TEMPLATE_DECL created
Next at line 11087 in start_method and within grok_special_member_properties,copy_fn_preturns value to indicate the characteristics of the constructor or assignmentoperator.
Assuming D is a constructor or overloaded `operator='. Let T be theclass in which D is declared. Then, this function returns:
-1, if D's is an ill-formed constructor or copy assignment operator whosefirst parameter is of type `T'.
0, if D is not a copy constructor or copy assignment operator.
1, if D is a copy constructor or copy assignment operator whosefirst parameter is a reference to const qualified T.
2, if D is a copy constructor or copy assignment operator whosefirst parameter is a reference to non-const qualified T.
8853 int
8854 copy_fn_p (tree d) in decl.c
8855 {
8856 tree args;
8857 tree arg_type;
8858 int result = 1;
8859
8860 my_friendly_assert(DECL_FUNCTION_MEMBER_P (d), 20011208);
8861
8862 if (DECL_TEMPLATE_INFO (d) &&is_member_template (DECL_TI_TEMPLATE (d)))
8863 /*Instantiations of template member functions are never copy
8864 functions. Note that member functions of templated classes are
8865 represented as template functionsinternally, and we must
8866 accept those as copy functions. */
8867 return0;
8868
8869 args = FUNCTION_FIRST_USER_PARMTYPE (d);
8870 if (!args)
8871 return0;
8872
8873 arg_type = TREE_VALUE(args);
8874
8875 if (TYPE_MAIN_VARIANT(arg_type) == DECL_CONTEXT (d))
8876 {
8877 /*Pass by value copy assignment operator. */
8878 result = -1;
8879 }
8880 else if (TREE_CODE(arg_type) == REFERENCE_TYPE
8881 &&TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) == DECL_CONTEXT (d))
8882 {
8883 if (CP_TYPE_CONST_P(TREE_TYPE (arg_type)))
8884 result = 2;
8885 }
8886 else
8887 return0;
8888
8889 args = TREE_CHAIN (args);
8890
8891 if (args && args !=void_list_node && !TREE_PURPOSE (args))
8892 /*There are more non-optional args. */
8893 return0;
8894
8895 returnresult;
8896 }
No doubt, for our copy constructor, result will be 0, as theparameter is not of type “Lock”. So nothing is done in grok_special_member_properties.
5.12.3.2.1.1.3.1. Finishparsing
After parsing the non-default constructor, we come to the end of theclass. It must be “};” to ending the definition. As GNU extension allowsdeclaring attributes for the class after token “}” and before “;”, it needs tryparsing this optional attributes.
cp_parser_class_specifier (continue)
11913 cp_parser_require(parser, CPP_CLOSE_BRACE, "`}'");
11914 /*We get better error messages by noticing a common problem: a
11915 missing trailing `;'. */
11916 token = cp_lexer_peek_token (parser->lexer);
11917 has_trailing_semicolon =(token->type == CPP_SEMICOLON);
11918 /*Look for trailing attributes to apply to this class. */
11919 if(cp_parser_allow_gnu_extensions_p (parser))
11920 {
11921 tree sub_attr =cp_parser_attributes_opt (parser);
11922 attributes = chainon(attributes, sub_attr);
11923 }
11924 if (type !=error_mark_node)
11925 type = finish_struct (type, attributes);
11926 if (pop_p)
11927 pop_scope (scope);
If everything runs smoothly, it can finialize the parsing of theclass, and install the attributes for the class at the same time.
5228 tree
5229 finish_struct (tree t, tree attributes) in class.c
5230 {
5231 location_t saved_loc = input_location;
5232
5233 /* Now that we'vegot all the field declarations, reverse everything
5234 as necessary. */
5235 unreverse_member_declarations(t);
5236
5237 cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
5238
5239 /* Nadger thecurrent location so that diagnostics point to the start of
5240 the struct, not the end. */
5241 input_location = DECL_SOURCE_LOCATION (TYPE_NAME(t));
As we have seen before, the nodes for declarator of the methods arechained in the reverse order of the declaration, so it now restore the orderback now by reversing again.
5197 void
5198 unreverse_member_declarations (tree t) in class.c
5199 {
5200 tree next;
5201 tree prev;
5202 tree x;
5203
5204 /* The followinglists are all in reverse order. Put them in
5205 declaration order now. */
5206 TYPE_METHODS (t) = nreverse (TYPE_METHODS(t));
5207 CLASSTYPE_DECL_LIST (t) = nreverse(CLASSTYPE_DECL_LIST (t));
5208
5209 /* Actually, forthe TYPE_FIELDS, only the non TYPE_DECLs are in
5210 reverse order, so we can'tjust use nreverse. */
5211 prev = NULL_TREE;
5212 for (x =TYPE_FIELDS (t);
5213 x && TREE_CODE (x) != TYPE_DECL;
5214 x = next)
5215 {
5216 next = TREE_CHAIN (x);
5217 TREE_CHAIN (x) = prev;
5218 prev = x;
5219 }
5220 if (prev)
5221 {
5222 TREE_CHAIN (TYPE_FIELDS (t)) = x;
5223 if (prev)
5224 TYPE_FIELDS (t) = prev;
5225 }
5226 }
At line 5237, cplus_decl_attributes installs the optionalattributes of the class, for the struct Lock, class level attribute is absent.
finish_struct (continue)
5243 if (processing_template_decl)
5244 {
5245 finish_struct_methods(t);
5246 TYPE_SIZE (t) = bitsize_zero_node;
5247 TYPE_SIZE_UNIT (t) = size_zero_node;
5248 }
5249 else
5250 finish_struct_1 (t);
5251
5252 input_location = saved_loc;
5253
5254 TYPE_BEING_DEFINED (t) = 0;
5255
5256 if (current_class_type)
5257 popclass ();
5258 else
5259 error ("trying to finish struct, butkicked out due to previous parse errors");
5260
5261 if (processing_template_decl&& at_function_scope_p ())
5262 add_stmt(build_min (TAG_DEFN, t));
5263
5264 return t;
5265 }
If we are handling class-template, the details of the class whichwill be determined at point of instantiation (for example, if it inherits froma class-template, the derivation can only be known at point of instantiation).So only limited operation needs be taken by finish_struct_methods, and see that even thesize of the class is temperary declared as zero at line 5246 and 5247.
1718 static void
1719 finish_struct_methods (tree t) in class.c
1720 {
1721 tree fn_fields;
1722 tree method_vec;
1723 int slot, len;
1724
1725 if (!TYPE_METHODS (t))
1726 {
1727 /* Clear thesefor safety; perhaps some parsing error could set
1728 these incorrectly. */
1729 TYPE_HAS_CONSTRUCTOR (t) = 0;
1730 TYPE_HAS_DESTRUCTOR (t) = 0;
1731 CLASSTYPE_METHOD_VEC (t) = NULL_TREE;
1732 return;
1733 }
1734
1735 method_vec = CLASSTYPE_METHOD_VEC (t);
1736 my_friendly_assert (method_vec != NULL_TREE,19991215);
1737 len = TREE_VEC_LENGTH (method_vec);
1738
1739 /* First fill inentry 0 with the constructors, entry 1 with destructors,
1740 and the next few with typeconversion operators (if any). */
1741 for(fn_fields = TYPE_METHODS (t); fn_fields;
1742 fn_fields = TREE_CHAIN (fn_fields))
1743 /* Clear out thisflag. */
1744 DECL_IN_AGGR_P (fn_fields) = 0;
1745
1746 if (TYPE_HAS_DESTRUCTOR (t) &&!CLASSTYPE_DESTRUCTORS (t))
1747 /* We thought there was a destructor, butthere wasn't. Some
1748 parse errors cause thisanomalous situation. */
1749 TYPE_HAS_DESTRUCTOR (t) = 0;
1750
1751 /* Issue warningsabout private constructors and such. If there are
1752 no methods, then some publicdefaults are generated. */
1753 maybe_warn_about_overly_private_class (t);
1754
1755 /* Now sort themethods. */
1756 while (len> 2 && TREE_VEC_ELT (method_vec, len-1) == NULL_TREE)
1757 len--;
1758 TREE_VEC_LENGTH (method_vec) = len;
1759
1760 /* The typeconversion ops have to live at the front of the vec, so we
1761 can't sort them. */
1762 for (slot =2; slot < len; ++slot)
1763 {
1764 tree fn = TREE_VEC_ELT (method_vec, slot);
1765
1766 if (!DECL_CONV_FN_P (OVL_CURRENT (fn)))
1767 break;
1768 }
1769 if (len - slot > 1)
1770 qsort (&TREE_VEC_ELT (method_vec,slot), len-slot, sizeof (tree),
1771 method_name_cmp);
1772 }
Seeing that this limited handling just includes correcting flagsincorrectly set by error statements encountered by parser. Sometimes, whenwriting a simple class like “Lock” here, it may be mistakenly written as:
cass Lock {
Lock();
Lock(const Host&);
};
As it missing the access-specifier “public”, the constructors can’tbe invoked. The parser can give out warning about it. However, when the classhas friend, or has other public methods (static or non-static), it is diffcultto tell whether the constructors can be invoked outside. The parser justassumes that them can, and will issue error if them can’t be invoked later incode. At line 1753, maybe_warn_about_overly_private_class doesthe checking.
And now all methods of the class are known, to accelerate thesearching speed for the method, the methods must be sorted so binary search canbe applied (line 1770).
- Studying note of GCC-3.4.6 source (104)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- 程序员的十层楼--(1~3层)
- redo_群集条件下的redo管理
- 快换工作了,整理一下以前乱写的东西
- Ghost版xp升级到sp3后报错 错误代码ox80070002
- GCC-3.4.6源代码学习笔记 (104)
- Studying note of GCC-3.4.6 source (104)
- zt自己动手用工行U盾加密自己私有文件
- Jode Decompiler插件
- NI LabWindows CVI 中调用 DLL 的几种方法
- C语言迷题
- C# 圆角控件设计
- 选择
- CISCO一路同行--记我的安全CCIE历程
- Linux教程- Vi的进入与退出