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).

 

原创粉丝点击