Studying note of GCC-3.4.6 source (129 continue)

  • Post author:
  • Post category:其他



Below DECL_MAIN_P returns nonzero to indicate encountering “main” function, it is interesting to see some limitation about its definition. See that main function can’t be declared as inline, and always public accessible.



grokfndecl (continue)




5642



if (ctype == NULL_TREE && DECL_MAIN_P (decl))



5643



{



5644



if (processing_template_decl)



5645



error (“cannot declare `::main’ to be a template”);



5646



if (inlinep)



5647



error (“cannot declare `::main’ to be inline”);



5648



if (!publicp)



5649



error (“cannot declare `::main’ to be static”);



5650



if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),



5651



integer_type_node))



5652



error (“`main’ must return `int'”);



5653



inlinep = 0;



5654



publicp = 1;



5655



}



5656



5657




/* Members of anonymous types and local classes have no linkage; make



5658



them internal.  */



5659



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



5660



if (ctype && (TYPE_ANONYMOUS_P (ctype)



5661



|| decl_function_context (TYPE_MAIN_DECL (ctype))))



5662



publicp = 0;



5663



5664



if (publicp)



5665



{



5666




/* [basic.link]: A name with no linkage (notably, the name of a class



5667



or enumeration declared in a local scope) shall not be used to



5668



declare an entity with linkage.



5669



5670



Only check this for public decls for now. See core 319, 389.  */



5671



t = no_linkage_check (TREE_TYPE (decl));



5672



if (t)



5673



{



5674



if (TYPE_ANONYMOUS_P (t))



5675



{



5676



if (DECL_EXTERN_C_P (decl))



5677




/* Allow this; it’s pretty common in C.  */;



5678



else



5679



{



5680



pedwarn (“non-local function `%#D’ uses anonymous type”,



5681



decl);



5682



if (DECL_ORIGINAL_TYPE (TYPE_NAME (t)))



5683



cp_pedwarn_at (“/



5684



`%#D’ does not refer to the unqualified type, so it is not used for linkage”,



5685



TYPE_NAME (t));



5686



}



5687



}



5688



else



5689



pedwarn (“non-local function `%#D’ uses local type `%T'”,



5690



decl, t);



5691



}



5692



}



5693



5694



TREE_PUBLIC (decl) = publicp;





5710



DECL_EXTERNAL (decl) = 1;





5870



if (ctype == NULL_TREE || check)



5871




return

decl;





5877



}




[3]



, section [basic.link] gives a detail description about linkage of entities.


A program consists of one or more translation units linked together.


Ÿ




A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope:


— When a name has external linkage, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.


— When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.


— When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.


Ÿ




A name having namespace scope (3.3.5) has internal linkage if it is the name of


— an object, reference, function or function template that is explicitly declared static or,


— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage; or


— a data member of an anonymous union.


Ÿ




A name having namespace scope has external linkage if it is the name of


— an object or reference, unless it has internal linkage; or


— a function, unless it has internal linkage; or


— a named class (clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes (7.1.3); or


— a named enumeration (7.2), or an unnamed enumeration defined in a typedef declaration in which the enumeration has the typedef name for linkage purposes (7.1.3); or


— an enumerator belonging to an enumeration with external linkage; or


— a template, unless it is a function template that has internal linkage (clause 14); or


— a namespace (7.3), unless it is declared within an unnamed namespace.


Ÿ




In addition, a member function, static data member, class or enumeration of class scope has external linkage if the name of the class has external linkage.


Ÿ




The name of a function declared in block scope, and the name of an object declared by a block scope


extern


declaration, have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity receives external linkage. [Example:


static


void f();


static


int i = 0;

//1


void g() {


extern


void f();

// internal linkage


int i;

//2: i has no linkage


{


extern


void f();

// internal linkage


extern


int i;

//3: external linkage


}


}


There are three objects named i in this program. The object with internal linkage introduced by the declaration in global scope (line //1), the object with automatic storage duration and no linkage introduced by the declaration on line //2, and the object with static storage duration and external linkage introduced by the declaration on line //3. ]


Ÿ




When a block scope declaration of an entity with linkage is not found to refer to some other declaration, then that entity is a member of the innermost enclosing namespace. However such a declaration does not introduce the member name in its namespace scope. [Example:


namespace


X {


void p() {


q();

//error: q not yet declared


extern


void q();

// q is a member of namespace X


}



void middle() {


q();

//error: q not yet declared


}


void q() {

/* … */

}

// definition of X::q


}


void q() {

/* … */

}

// some other, unrelated q


Ÿ




Names not covered by these rules have no linkage. Moreover, except as noted, a name declared in a local scope (3.3.2) has no linkage. A name with no linkage (notably, the name of a class or enumeration declared in a local scope (3.3.2)) shall not be used to declare an entity with linkage. If a declaration uses a typedef name, it is the linkage of the type name to which the typedef refers that is considered. [Example:


void f() {


struct


A { int x; };

// no linkage


extern


A a;

// ill-formed


typedef


A B;


extern


B b;

// ill-formed


}


This implies that names with no linkage cannot be used as template arguments (14.3).


Ÿ




Two names that are the same (clause 3) and that are declared in different scopes shall denote the same object, reference, function, type, enumerator, template or namespace if


— both names have external linkage or else both names have internal linkage and are declared in the same translation unit; and


— both names refer to members of the same namespace or to members, not by inheritance, of the same class; and


— when both names denote functions, the function types are identical for purposes of overloading; and


— when both names denote function templates, the signatures (14.5.5.1) are the same.


Ÿ




After all adjustments of types (during which typedefs (7.1.3) are replaced by their definitions), the types specified by all declarations referring to a given object or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound (8.3.4). A violation of this rule on type identity does not require a diagnostic.


It is interesting to see that comment at line 5659 is removed in V4.3.0 without changing the code. Because mentioned by clause 8 (the program written before this rule worked out), typedef name should obey the same rule; in previous section about processing typedef declaration, we can see that typedef declaration will have a TYPE_DECL node created and will be placed within the same scope as the type being typedefed. Later when we use this typedef name, we refer to this TYPE_DECL node but condition in the function can still work. Above at line 5661, decl_function_context returns the innermost enclosing function scope if there any otherwise returns null.



grokdeclarator (continue)




8550



my_friendly_assert (!RIDBIT_SETP (RID_MUTABLE, specbits), 19990927);



8551



8552




/* Record `register’ declaration for warnings on &



8553



and in case doing stupid register allocation.  */



8554



8555



if (RIDBIT_SETP (RID_REGISTER, specbits))



8556



DECL_REGISTER (decl) = 1;



8557



8558



if (RIDBIT_SETP (RID_EXTERN, specbits))



8559



DECL_THIS_EXTERN (decl) = 1;



8560



8561



if (RIDBIT_SETP (RID_STATIC, specbits))



8562



DECL_THIS_STATIC (decl) = 1;



8563



8564




/* Record constancy and volatility. There’s no need to do this



8565



when processing a template; we’ll do this for the instantiated



8566



declaration based on the type of DECL.  */



8567



if (!processing_template_decl)



8568





c_apply_type_quals_to_decl (type_quals, decl);



8569



8570




return

decl;



8571



}



8572



}



See


decl


is returned to


decl1


below, which is the FUNCTION_DECL. So below


fntype


refers to this FUNCTION_TYPE node, and


restype


refers to the


integer_type_node


node.



start_function(continue)




10229




/* If the declarator is not suitable for a function definition,



10230



cause a syntax error.  */



10231



if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)



10232




return

0;



10233



10234



cplus_decl_attributes (&decl1, attrs, 0);



10235



10236




/* If #pragma weak was used, mark the decl weak now.  */



10237



if (global_scope_p (




current_binding_level




))



10238



maybe_apply_pragma_weak (decl1);



10239



10240



fntype = TREE_TYPE (decl1);



10241



10242



restype = TREE_TYPE (fntype);



10243



10244



if (TREE_CODE (fntype) == METHOD_TYPE)



10245



ctype = TYPE_METHOD_BASETYPE (fntype);



10246



else if (DECL_MAIN_P (decl1))



10247



{



10248




/* If this doesn’t return integer_type, or a typedef to



10249



integer_type, complain.  */



10250



if (!same_type_p (TREE_TYPE (TREE_TYPE (decl1)), integer_type_node))



10251



{



10252



if (


pedantic


||


warn_return_type


)



10253



pedwarn (“return type for `main’ changed to `int'”);



10254



TREE_TYPE (decl1) = fntype = default_function_type;



10255



}



10256



}



10257



}





10306




/* Make the init_value nonzero so pushdecl knows this is not tentative.



10307



error_mark_node is replaced below (in poplevel) with the BLOCK.  */



10308



if (!DECL_INITIAL (decl1))



10309



DECL_INITIAL (decl1) = error_mark_node;



10310



10311




/* This function exists in static storage.



10312



(This does not mean `static’ in the C sense!)  */



10313



TREE_STATIC (decl1) = 1;





10326




/* We are now in the scope of the function being defined.  */



10327







current_function_decl


= decl1;



10328



10329



/* Save the parm names or decls from this function’s declarator



10330



where store_parm_decls will find them.  */



10331







current_function_parms


= DECL_ARGUMENTS (decl1);



10332



10333






/* Make sure the parameter and return types are reasonable. When



10334



you declare a function, these types can be incomplete, but they



10335



must be complete when you define the function.  */



10336





if (!

processing_template_decl

)



10337





check_function_type (decl1, current_function_parms);



10338






/* Make sure no default arg is missing.  */



10339





check_default_args (decl1);



Now the FUNCTION_DECL and some references are updated as below figure.


t3


For our “main” function,



check_function_type



just checks if the parameter type and return type are complete types (not just declared). And



check_default_args



does nothing as we havn’t default argument.



start_function(continue)




10341




/* Build the return declaration for the function.  */



10342



restype = TREE_TYPE (fntype);



10343




/* Promote the value to int before returning it.  */



10344



if (

c_promoting_integer_type_p

(restype))



10345



restype = type_promotes_to (restype);



10346



if (DECL_RESULT (decl1) == NULL_TREE)



10347



{



10348



DECL_RESULT (decl1)



10349



=



build_decl



(RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype));



10350





c_apply_type_quals_to_decl (cp_type_quals (restype),



10351



DECL_RESULT (decl1));



10352



}



10353



10354




/* Initialize RTL machinery. We cannot do this until



10355



CURRENT_FUNCTION_DECL and DECL_RESULT are set up. We do this



10356



even when processing a template; this is how we get



10357



CFUN set up, and our per-function variables initialized.



10358



FIXME factor out the non-RTL stuff.  */



10359



bl = current_binding_level;



10360




allocate_struct_function

(decl1);



10361



current_binding_level = bl;



10362



10363




/* Even though we’re inside a function body, we still don’t want to



10364



call expand_expr to calculate the size of a variable-sized array.



10365



We haven’t necessarily assigned RTL to all variables yet, so it’s



10366



not safe to try to expand expressions involving them.  */



10367





immediate_size_expand


= 0;



10368





cfun


->x_dont_save_pending_sizes_p = 1;



10369



10370




/* Start the statement-tree, start the tree now.  */



10371




begin_stmt_tree

(&DECL_SAVED_TREE (decl1));



10372



10373




/* Let the user know we’re compiling this function.  */



10374



announce_function (decl1);



We have seen above routines in section

5.12.3.2.1.2.1.1. Start function handling

and refer to that section for the detail description about these routines. In short, before going on we get following sub-tree. Note: in the figure, “(0)” or “(1)” means the field contains “0” or “1”, and “[0]” means 0

th

element of tree_vec, this rule applies to all figures.


(

Click here for open

)



start_function(continue)




10376




/* Record the decl so that the function name is defined.



10377



If we already have a decl for this name, and it is a FUNCTION_DECL,



10378



use the old decl.  */



10379



if (!

processing_template_decl

&& !(flags & SF_PRE_PARSED))



10380



{



10381




/* A specialization is not used to guide overload resolution.  */



10382



if (!DECL_FUNCTION_MEMBER_P (decl1)



10383



&& !(DECL_USE_TEMPLATE (decl1) &&



10384



PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl1))))



10385



{



10386



tree olddecl = pushdecl (decl1);



10387



10388



if (olddecl == error_mark_node)



10389




/* If something went wrong when registering the declaration,



10390



use DECL1; we have to have a FUNCTION_DECL to use when



10391



parsing the body of the function.  */



10392



;



10393



else



10394




/* Otherwise, OLDDECL is either a previous declaration of



10395



the same function or DECL1 itself.  */



10396



decl1 = olddecl;



10397



}



10398



else



10399



{



10400




/* We need to set the DECL_CONTEXT.  */



10401



if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))



10402



DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));



10403



}



10404



fntype = TREE_TYPE (decl1);



10405



}



10406



10407




/* Reset these in case the call to pushdecl changed them.  */



10408





current_function_decl


= decl1;



10409





cfun


->decl = decl1;



As


current_function_decl


is set to


decl1


at line 10327, and main function is new in global namespace,



pushdecl



just chains the FUNCTION_DECL into the


name


field of cxx_scope node of global namespace. At line 10386


olddecl


is the same as


decl1


.



start_function(continue)




10411




/* If we are (erroneously) defining a function that we have already



10412



defined before, wipe out what we knew before.  */



10413



if (!DECL_PENDING_INLINE_P (decl1))



10414



DECL_SAVED_FUNCTION_DATA (decl1) = NULL;



10415



10416



if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))



10417



{





10447



}



10448



10449



if (DECL_INTERFACE_KNOWN (decl1))



10450



{





10461



}



10462




/* If this function belongs to an interface, it is public.



10463



If it belongs to someone else’s interface, it is also external.



10464



This only affects inlines and template instantiations.  */



10465



else if (


interface_unknown


== 0



10466



&& ! DECL_TEMPLATE_INSTANTIATION (decl1))



10467



{





10485



}



10486



else if (


interface_unknown


&&


interface_only




10487



&& ! DECL_TEMPLATE_INSTANTIATION (decl1))



10488



{





10498



}



10499



else



10500



{



10501




/* This is a definition, not a reference.



10502



So clear DECL_EXTERNAL.  */



10503



DECL_EXTERNAL (decl1) = 0;



10504



10505



if ((DECL_DECLARED_INLINE_P (decl1)



10506



|| DECL_TEMPLATE_INSTANTIATION (decl1))



10507



&& ! DECL_INTERFACE_KNOWN (decl1)



10508




/* Don’t try to defer nested functions for now.  */



10509



&& ! decl_function_context (decl1))



10510



DECL_DEFER_OUTPUT (decl1) = 1;



10511



else



10512



DECL_INTERFACE_KNOWN (decl1) = 1;



10513



}



10514



10515






begin_scope



(sk_function_parms, decl1);



10516



10517



++


function_depth


;



10518



10519



if (DECL_DESTRUCTOR_P (decl1))



10520



{



10521



dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE);



10522



DECL_CONTEXT (dtor_label) =


current_function_decl


;



10523



}



10524



10525




start_fname_decls

();



10526





10527




store_parm_decls

(current_function_parms);



10528



10529




return

1;



10530



}



When returned from



start_function



, we get following nodes.


(

Click here for open

)



版权声明:本文为wuhui_gdnt原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。