Studying note of GCC-3.4.6 source (129 continue)

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 0th 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 )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值