Now we have definition of “SmallObject”, we use following “main” function to use this class, and see what’s immediate tree will be created.
using namespace Loki;
int main ()
{
SmallObject<> object_;
return 1;
}
Assuming that this “main” function lies in a separate source, which is a translation-unit, so the parser begins with following calls, cp_parser_translation_unit à cp_parser_declaration_seq_opt , in which the WHILE loop will process statements in turn.
For first statement of the using-directive, the call stack further goes down from cp_parser_declaration à cp_parser_block_declaration à cp_parser_using_directive à parse_using_directive à do_using_directive .
3350 void
3351 do_using_directive (tree namespace) in name-lookup.c
3352 {
3353 if (namespace == error_mark_node)
3354 return ;
3355
3356 my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 20050830);
3357
3358 if (building_stmt_tree ())
3359 add_stmt (build_stmt (USING_STMT, namespace));
3360 namespace = ORIGINAL_NAMESPACE (namespace);
3361
3362 if (!toplevel_bindings_p ())
3363 push_using_directive (namespace);
3364 else
3365 /* direct usage */
3366 add_using_namespace ( current_namespace , namespace, 0);
3367 }
If building_stmt_tree is nonzero, it means we are generating statements for function, block etc, so the using-directive should have USING_STMT generated for. Here argument namespace is the associated NAMESPACE_DECL. At line 3362, toplevel_bindings_p returns nonzero if the innermost effective non-class binding scope is a namespace (using-directive is not allowed within class scope but can in method scope). For example:
namespace A {
int i;
}
class B {
int func() {
using namespace A;
return i;
}
};
For those using-directives under namespace scope, in the NAMESPACE_DECL node for the namespace scope, field DECL_NAMESPACE_USING will be a tree_list to chain the using-directives tegother by add_using_namespace .
3275 static void
3276 add_using_namespace (tree user, tree used, bool indirect) in name-lookup.c
3277 {
3278 tree t;
3279 timevar_push (TV_NAME_LOOKUP);
3280 /* Using oneself is a no-op. */
3281 if (user == used)
3282 {
3283 timevar_pop (TV_NAME_LOOKUP);
3284 return ;
3285 }
3286 my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380);
3287 my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380);
3288 /* Check if we already have this. */
3290 t = purpose_member (used, DECL_NAMESPACE_USING (user));
3291 if (t != NULL_TREE)
3292 {
3293 if (!indirect)
3294 /* Promote to direct usage. */
3295 TREE_INDIRECT_USING (t) = 0;
3296 timevar_pop (TV_NAME_LOOKUP);
3297 return ;
3298 }
3299
3300 /* Add used to the user's using list. */
3301 DECL_NAMESPACE_USING (user)
3302 = tree_cons (used, namespace_ancestor (user, used),
3303 DECL_NAMESPACE_USING (user));
3304
3305 TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect;
3306
3307 /* Add user to the used's users list. */
3308 DECL_NAMESPACE_USERS (used)
3309 = tree_cons (user, 0, DECL_NAMESPACE_USERS (used));
3310
3311 /* Recursively add all namespaces used. */
3312 for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
3313 /* indirect usage */
3314 add_using_namespace (user, TREE_PURPOSE (t), 1);
3315
3316 /* Tell everyone using us about the new used namespaces. */
3317 for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t))
3318 add_using_namespace (TREE_PURPOSE (t), used, 1);
3319 timevar_pop (TV_NAME_LOOKUP);
3320 }
In section 5.12.4.1.1.2.1.3.2. Other names , see that using-directive shouldn’t garble the namespaces’ level, and at name-lookup, the front-end will do the search according to the level strictly. add_using_namespace needs record necessary information. Here namespace_ancestor finds out the closet common ancestor of ns1 and ns2. Notice that all namespace scopes have same ancient ancestor – global namespace. (For the using of the list grown here, refers to routine lookup_using_namespace ).
3194 static tree
3195 namespace_ancestor (tree ns1, tree ns2) in name-lookup.c
3196 {
3197 timevar_push (TV_NAME_LOOKUP);
3198 if (is_ancestor (ns1, ns2))
3199 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1);
3200 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
3201 namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2));
3202 }
Here argument root is current namespace scope, and child is the namespace specified by the using-directive. Then is_ancestor continuously to retrieve the context starting at child till finds out root or exhausts the tree. For the previous case, root is the ancestor of child , and the routine returns nonzero value; otherwise it returns zero.
2502 bool
2503 is_ancestor (tree root, tree child) in name-lookup.c
2504 {
2505 my_friendly_assert ((TREE_CODE (root) == NAMESPACE_DECL
2506 || TREE_CODE (root) == FUNCTION_DECL
2507 || CLASS_TYPE_P (root)), 20030307);
2508 my_friendly_assert ((TREE_CODE (child) == NAMESPACE_DECL
2509 || CLASS_TYPE_P (child)),
2510 20030307);
2511
2512 /* The global namespace encloses everything. */
2513 if (root == global_namespace )
2514 return true;
2515
2516 while (true)
2517 {
2518 /* If we've run out of scopes, stop. */
2519 if (!child)
2520 return false;
2521 /* If we've reached the ROOT, it encloses CHILD. */
2522 if (root == child)
2523 return true;
2524 /* Go out one level. */
2525 if (TYPE_P (child))
2526 child = TYPE_NAME (child);
2527 child = DECL_CONTEXT (child);
2528 }
2529 }
So for our example, global namespace chains “Loki” in its DECL_NAMESPACE_USERS field.
For the main function, cp_parser_declaration again invokes cp_parser_block_declaration à cp_parser_simple_declaration . Under our context, argument function_definition_allowed_p is true which means we also recognize a function-definition as a simple-declaration.
The grammar of block-declaration is:
block-declaration:
simple-declaration | asm-definition | namespace-alias-definition | using-declaration |
using-directive
GNU Extension:
block-declaration: __extension__ block-declaration | label-declaration
6370 static void
6371 cp_parser_block_declaration (cp_parser *parser, in parser.c
6372 bool statement_p)
6373 {
6374 cp_token *token1;
6375 int saved_pedantic;
6376
6377 /* Check for the `__extension__' keyword. */
6378 if (cp_parser_extension_opt (parser, &saved_pedantic))
6379 {
…
6386 }
6387
6388 /* Peek at the next token to figure out which kind of declaration is
6389 present. */
6390 token1 = cp_lexer_peek_token (parser->lexer);
6391
6392 /* If the next keyword is `asm', we have an asm-definition. */
6393 if (token1->keyword == RID_ASM)
6394 {
…
6398 }
6399 /* If the next keyword is `namespace', we have a
6400 namespace-alias-definition. */
6401 else if (token1->keyword == RID_NAMESPACE)
6402 cp_parser_namespace_alias_definition (parser);
6403 /* If the next keyword is `using', we have either a
6404 using-declaration or a using-directive. */
6405 else if (token1->keyword == RID_USING)
6406 {
…
6419 }
6420 /* If the next keyword is `__label__' we have a label declaration. */
6421 else if (token1->keyword == RID_LABEL)
6422 {
…
6426 }
6427 /* Anything else must be a simple-declaration. */
6428 else
6429 cp_parser_simple_declaration (parser, !statement_p);
6430 }
Grammar for simple-declaration is:
simple-declaration:
decl-specifier-seq [opt] init-declarator-list [opt] ;
init-declarator-list:
init-declarator | init-declarator-list , init-declarator
See simple-declaration may lie in a block-declaraition which in turn may within a function scope or class-method scope, which requires access control, so a new deferred access control instance is expected. And stop_deferring_access_checks at line 6475 prevents adding more deferred access check by perform_or_defer_access_check , but access checking is required for both decl-specifier-seq and init-declarator-list, so for the later one it will resume the checking by resume_deferring_access_checks .
6444 static void
6445 cp_parser_simple_declaration (cp_parser* parser, in parser.c
6446 bool function_definition_allowed_p)
6447 {
6448 tree decl_specifiers;
6449 tree attributes;
6450 int declares_class_or_enum;
6451 bool saw_declarator;
6452
6453 /* Defer access checks until we know what is being declared; the
6454 checks for names appearing in the decl-specifier-seq should be
6455 done as if we were in the scope of the thing being declared. */
6456 push_deferring_access_checks (dk_deferred);
6457
6458 /* Parse the decl-specifier-seq. We have to keep track of whether
6459 or not the decl-specifier-seq declares a named class or
6460 enumeration type, since that is the only case in which the
6461 init-declarator-list is allowed to be empty.
6462
6463 [dcl.dcl]
6464
6465 I n a simple-declaration, the optional init-declarator-list can be
6466 omitted only when declaring a class or enumeration, that is when
6467 the decl-specifier-seq contains either a class-specifier, an
6468 elaborated-type-specifier, or an enum-specifier. */
6469 decl_specifiers
6470 = cp_parser_decl_specifier_seq (parser,
6471 CP_PARSER_FLAGS_OPTIONAL,
6472 &attributes,
6473 &declares_class_or_enum);
6474 /* We no longer need to defer access checks. */
6475 stop_deferring_access_checks ();
6476
6477 /* In a block scope, a valid declaration must always have a
6478 decl-specifier-seq. By not trying to parse declarators, we can
6479 resolve the declaration/expression ambiguity more quickly. */
6480 if (!function_definition_allowed_p && !decl_specifiers)
6481 {
6482 cp_parser_error (parser, "expected declaration");
6483 goto done;
6484 }
6485
6486 /* If the next two tokens are both identifiers, the code is
6487 erroneous. The usual cause of this situation is code like:
6488
6489 T t;
6490
6491 where "T" should name a type -- but does not. */
6492 if (cp_parser_diagnose_invalid_type_name (parser))
6493 {
6494 /* If parsing tentatively, we should commit; we really are
6495 looking at a declaration. */
6496 cp_parser_commit_to_tentative_parse (parser);
6497 /* Give up. */
6498 goto done;
6499 }
As we see before, cp_parser_decl_specifier_seq will parse the return type of the function; so here decl_specifiers is a tree_list with TREE_VALUE field referring to the node of integer_type_node . Note that a function-definition may haven’t return type (it defaults to int).
1950 static bool
1951 cp_parser_diagnose_invalid_type_name (cp_parser *parser) in parser.c
1952 {
1953 /* If the next two tokens are both identifiers, the code is
1954 erroneous. The usual cause of this situation is code like:
1955
1956 T t;
1957
1958 where "T" should name a type -- but does not. */
1959 if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
1960 && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
1961 {
1962 tree name;
1963
1964 /* If parsing tentatively, we should commit; we really are
1965 looking at a declaration. */
1966 /* Consume the first identifier. */
1967 name = cp_lexer_consume_token (parser->lexer)->value;
1968 /* Issue an error message. */
1969 error ("`%s' does not name a type", IDENTIFIER_POINTER (name));
1970 /* If we're in a template class, it's possible that the user was
1971 referring to a type from a base class. For example:
1972
1973 template <typename T> struct A { typedef T X; };
1974 template <typename T> struct B : public A<T> { X x; };
1975
1976 The user should have said "typename A<T>::X". */
1977 if (processing_template_decl && current_class_type )
1978 {
1979 tree b;
1980
1981 for (b = TREE_CHAIN (TYPE_BINFO (current_class_type ));
1982 b;
1983 b = TREE_CHAIN (b))
1984 {
1985 tree base_type = BINFO_TYPE (b);
1986 if (CLASS_TYPE_P (base_type)
1987 && dependent_type_p (base_type))
1988 {
1989 tree field;
1990 /* Go from a particular instantiation of the
1991 template (which will have an empty TYPE_FIELDs),
1992 to the main version. */
1993 base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
1994 for (field = TYPE_FIELDS (base_type);
1995 field;
1996 field = TREE_CHAIN (field))
1997 if (TREE_CODE (field) == TYPE_DECL
1998 && DECL_NAME (field) == name)
1999 {
2000 error ("(perhaps `typename %T::%s' was intended)",
2001 BINFO_TYPE (b), IDENTIFIER_POINTER (name));
2002 break ;
2003 }
2004 if (field)
2005 break ;
2006 }
2007 }
2008 }
2009 /* Skip to the end of the declaration; there's no point in
2010 trying to process it. */
2011 cp_parser_skip_to_end_of_statement (parser);
2012
2013 return true;
2014 }
2015
2016 return false;
2017 }
Being proper form, the core part of decl-specifier-seq should name a type. That type found following name-lookup rule will be returned to decl-specifiers ; and if no appropriate type is found, this token stays as identifier, and cp_parser_diagnose_invalid_type_name diagnoses this error case, and gives out diagnostic message.
cp_parser_simple_declaration (continue)
6501 /* If we have seen at least one decl-specifier, and the next token
6502 is not a parenthesis, then we must be looking at a declaration.
6503 (After "int (" we might be looking at a functional cast.) */
6504 if (decl_specifiers
6505 && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
6506 cp_parser_commit_to_tentative_parse (parser);
6507
6508 /* Keep going until we hit the `;' at the end of the simple
6509 declaration. */
6510 saw_declarator = false;
6511 while (cp_lexer_next_token_is_not (parser->lexer,
6512 CPP_SEMICOLON))
6513 {
6514 cp_token *token;
6515 bool function_definition_p;
6516 tree decl;
6517
6518 saw_declarator = true;
6519 /* Parse the init-declarator. */
6520 decl = cp_parser_init_declarator (parser, decl_specifiers, attributes,
6521 function_definition_allowed_p,
6522 /*member_p=*/ false,
6523 declares_class_or_enum,
6524 &function_definition_p);
6525 /* If an error occurred while parsing tentatively, exit quickly.
6526 (That usually happens when in the body of a function; each
6527 statement is treated as a declaration-statement until proven
6528 otherwise.) */
6529 if (cp_parser_error_occurred (parser))
6530 goto done;
6531 /* Handle function definitions specially. */
6532 if (function_definition_p)
6533 {
6534 /* If the next token is a `,', then we are probably
6535 processing something like:
6536
6537 void f() {}, *p;
6538
6539 which is erroneous. */
6540 if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
6541 error ("mixing declarations and function-definitions is forbidden");
6542 /* Otherwise, we're done with the list of declarators. */
6543 else
6544 {
6545 pop_deferring_access_checks ();
6546 return ;
6547 }
6548 }
…
6580 }
…
6593 /* Consume the `;'. */
6594 cp_parser_require (parser, CPP_SEMICOLON, "`;'");
6595
6596 done:
6597 pop_deferring_access_checks ();
6598 }
Notice that argument declares_class_or_enum is 0 as the type-specifier is not class-specifier, enum-specifier, nor is elaborated-type-specifier. The content of init-declarator includes:
init-declarator:
declarator initializer [opt]
function-definition:
decl-specifier-seq [opt] declarator ctor-initializer [opt] function-body
decl-specifier-seq [opt] declarator function-try-block
GNU Extension:
init-declarator:
declarator asm-specification [opt] attributes [opt] initializer [opt]
function-definition:
__extension__ function-definition
Note ctor-initializer is used only in constructor.
9933 static tree
9934 cp_parser_init_declarator (cp_parser* parser, in parser.c
9935 tree decl_specifiers,
9936 tree prefix_attributes,
9937 bool function_definition_allowed_p,
9938 bool member_p,
9939 int declares_class_or_enum,
9940 bool* function_definition_p)
9941 {
9942 cp_token *token;
9943 tree declarator;
9944 tree attributes;
9945 tree asm_specification;
9946 tree initializer;
9947 tree decl = NULL_TREE;
9948 tree scope;
9949 bool is_initialized;
9950 bool is_parenthesized_init;
9951 bool is_non_constant_init;
9952 int ctor_dtor_or_conv_p;
9953 bool friend_p;
9954 bool pop_p = false;
9955
9956 /* Assume that this is not the declarator for a function
9957 definition. */
9958 if (function_definition_p)
9959 *function_definition_p = false;
9960
9961 /* Defer access checks while parsing the declarator; we cannot know
9962 what names are accessible until we know what is being
9963 declared. */
9964 resume_deferring_access_checks ();
9965
9966 /* Parse the declarator. */
9967 declarator
9968 = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
9969 &ctor_dtor_or_conv_p,
9970 /*parenthesized_p=*/ NULL,
9971 /*member_p=*/ false);
9972 /* Gather up the deferred checks. */
9973 stop_deferring_access_checks ();
The part “main ()” is the declarator, which contains “main” as declarator-id, and “()” as parameter-list. So in cp_parser_declarator , cp_parser_direct_declarator iterates its major WHILE loop twice. In first time invoking: cp_parser_declarator_id à cp_parser_id_expression à cp_parser_identifier which returns the IDENTIFIER_NODE of “main”. And in second time, invoking: cp_parser_parameter_declaration_clause which returns void_list_node for the empty parameter-list. And then the declarator-id and parameter-list are assembled tegother by make_call_declarator to form a CALL_EXPR as below (it mostly like parsing class-method we see before).