5.12.5.2.2.2.1.2. 构建 VAR_DECL
接下来在 cp_parser_simple_declaration 中,调用 cp_parser_init_declarator 来解析声明符部分。调用栈 cp_parser_declarator à cp_parser_direct_declarator à cp_parser_declarator_id à cp_parser_id_expression à cp_parser_unqualified_id à cp_parser_identifier ,为“ object_ ”构建了一个 IDENTIFIER_NODE 。接着在 cp_parser_init_declarator 中,以下代码片段将被执行。
cp_parser_init_declarator (continue)
10095 /* Enter the newly declared entry in the symbol table. If we're
10096 processing a declaration in a class-specifier, we wait until
10097 after processing the initializer. */
10098 if (!member_p)
10099 {
10100 if (parser->in_unbraced_linkage_specification_p)
10101 {
10102 decl_specifiers = tree_cons (error_mark_node,
10103 get_identifier ("extern"),
10104 decl_specifiers);
10105 have_extern_spec = false;
10106 }
10107 decl = start_decl (declarator, decl_specifiers,
10108 is_initialized, attributes, prefix_attributes);
10109 }
“ SmallObject<> object_ ”是一个变量声明。一个新的树节点需要在中间树中创建来代表这个实体。在这次调用中,实参 intialized 是 false , attributes 及 prefix_attributes 都是 NULL 。
3670 tree
3671 start_decl (tree declarator, in decl.c
3672 tree declspecs,
3673 int initialized,
3674 tree attributes,
3675 tree prefix_attributes)
3676 {
3677 tree decl;
3678 tree type, tem;
3679 tree context;
3680
3681 /* This should only be done once on the top most decl. */
3682 if (have_extern_spec )
3683 {
3684 declspecs = tree_cons (NULL_TREE, get_identifier ("extern"),
3685 declspecs);
3686 have_extern_spec = false;
3687 }
3688
3689 /* An object declared as __attribute__((deprecated)) suppresses
3690 warnings of uses of other deprecated items. */
3691 if (lookup_attribute ("deprecated", attributes))
3692 deprecated_state = DEPRECATED_SUPPRESS;
3693
3694 attributes = chainon (attributes, prefix_attributes);
3695
3696 decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
3697 &attributes);
3698
3699 deprecated_state = DEPRECATED_NORMAL;
3700
3701 if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE)
3702 return error_mark_node;
3703
3704 type = TREE_TYPE (decl);
3705
3706 if (type == error_mark_node)
3707 return error_mark_node;
3708
3709 context = DECL_CONTEXT (decl);
3710
3711 if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL
3712 && context != current_namespace && TREE_CODE (decl) == VAR_DECL)
3713 {
3714 /* When parsing the initializer, lookup should use the object's
3715 namespace. */
3716 push_decl_namespace (context);
3717 }
3718
3719 /* We are only interested in class contexts, later. */
3720 if (context && TREE_CODE (context) == NAMESPACE_DECL)
3721 context = NULL_TREE;
作为声明的一种,期望的是某种 DECL 节点,因此需要 grokdeclarator 分析 decl-specifiers 及声明符部分来构成这个节点。
6462 tree
6463 grokdeclarator (tree declarator, in decl.c
6464 tree declspecs,
6465 enum decl_context decl_context,
6466 int initialized,
6467 tree* attrlist)
6468 {
6469 RID_BIT_TYPE specbits;
6470 int nclasses = 0;
6471 tree spec;
6472 tree type = NULL_TREE;
6473 int longlong = 0;
6474 int type_quals;
6475 int virtualp, explicitp, friendp, inlinep, staticp;
6476 int explicit_int = 0;
6477 int explicit_char = 0;
6478 int defaulted_int = 0;
6479 int extern_langp = 0;
6480 tree dependant_name = NULL_TREE;
6481
6482 tree typedef_decl = NULL_TREE;
6483 const char *name;
6484 tree typedef_type = NULL_TREE;
6485 int funcdef_flag = 0;
6486 enum tree_code innermost_code = ERROR_MARK;
6487 int bitfield = 0;
6488 #if 0
6489 /* See the code below that used this. */
6490 tree decl_attr = NULL_TREE;
6491 #endif
6492
6493 /* Keep track of what sort of function is being processed
6494 so that we can warn about default return values, or explicit
6495 return values which do not match prescribed defaults. */
6496 special_function_kind sfk = sfk_none;
6497
6498 tree dname = NULL_TREE;
6499 tree ctype = current_class_type;
6500 tree ctor_return_type = NULL_TREE;
6501 enum overload_flags flags = NO_SPECIAL;
6502 tree quals = NULL_TREE;
6503 tree raises = NULL_TREE;
6504 int template_count = 0;
6505 tree in_namespace = NULL_TREE;
6506 tree returned_attrs = NULL_TREE;
6507 tree scope = NULL_TREE;
6508 tree parms = NULL_TREE;
6509
6510 RIDBIT_RESET_ALL (specbits);
6511 if (decl_context == FUNCDEF)
6512 funcdef_flag = 1, decl_context = NORMAL;
6513 else if (decl_context == MEMFUNCDEF)
6514 funcdef_flag = -1, decl_context = FIELD;
6515 else if (decl_context == BITFIELD)
6516 bitfield = 1, decl_context = FIELD;
6517
6518 /* Look inside a declarator for the name being declared
6519 and get it as a string, for an error message. */
6520 {
6521 tree *next = &declarator;
6522 tree decl;
6523 name = NULL;
6524
6525 while (next && *next)
6526 {
6527 decl = *next;
6528 switch (TREE_CODE (decl))
6529 {
…
6629 case IDENTIFIER_NODE:
6630 if (TREE_CODE (decl) == IDENTIFIER_NODE)
6631 dname = decl;
6632
6633 next = 0;
6634
6635 if (C_IS_RESERVED_WORD (dname))
6636 {
…
6640 }
6641 else if (!IDENTIFIER_TYPENAME_P (dname))
6642 name = IDENTIFIER_POINTER (dname);
…
6654 break ;
6655
6656 }
6657 }
6658 }
…
6828 /* Look through the decl specs and record which ones appear.
6829 Some typespecs are defined as built-in typenames.
6830 Others, the ones that are modifiers of other types,
6831 are represented by bits in SPECBITS: set the bits for
6832 the modifiers that appear. Storage class keywords are also in SPECBITS.
6833
6834 If there is a typedef name or a type, store the type in TYPE.
6835 This includes builtin typedefs such as `int'.
6836
6837 Set EXPLICIT_INT if the type is `int' or `char' and did not
6838 come from a user typedef.
6839
6840 Set LONGLONG if `long' is mentioned twice.
6841
6842 For C++, constructors and destructors have their own fast treatment. */
6843
6844 for (spec = declspecs; spec; spec = TREE_CHAIN (spec))
6845 {
6846 int i;
6847 tree id;
6848
6849 /* Certain parse errors slip through. For example,
6850 `int class;' is not caught by the parser. Try
6851 weakly to recover here. */
6852 if (TREE_CODE (spec) != TREE_LIST)
6853 return 0;
6854
6855 id = TREE_VALUE (spec);
6856
6857 /* If the entire declaration is itself tagged as deprecated then
6858 suppress reports of deprecated items. */
6859 if (!adding_implicit_members && id && TREE_DEPRECATED (id))
6860 {
6861 if (deprecated_state != DEPRECATED_SUPPRESS)
6862 warn_deprecated_use (id);
6863 }
6864
6865 if (TREE_CODE (id) == IDENTIFIER_NODE)
6866 {
…
6933 }
6934 else if (TREE_CODE (id) == TYPE_DECL)
6935 {
6936 if (type)
6937 error ("multiple declarations `%T' and `%T'", type,
6938 TREE_TYPE (id));
6939 else
6940 {
6941 type = TREE_TYPE (id);
6942 TREE_VALUE (spec) = type;
6943 typedef_decl = id;
6944 }
6945 goto found;
6946 }
6947 if (type)
6948 error ("two or more data types in declaration of `%s'", name);
6949 else if (TREE_CODE (id) == IDENTIFIER_NODE)
6950 {
…
6960 }
6961 else if (id != error_mark_node)
6962 /* Can't change CLASS nodes into RECORD nodes here! */
6963 type = id;
6964
6965 found: ;
6966 }
6967
6968 #if 0
6969 /* See the code below that used this. */
6970 if (typedef_decl)
6971 decl_attr = DECL_ATTRIBUTES (typedef_decl);
6972 #endif
6973 typedef_type = type;
…
7019 ctype = NULL_TREE;
…
7337 scope = get_scope_of_declarator (declarator);
7338
7339 /* Now figure out the structure of the declarator proper.
7340 Descend through it, creating more complex types, until we reach
7341 the declared identifier (or NULL_TREE, in an abstract declarator). */
7342
7343 while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE
7344 && TREE_CODE (declarator) != TEMPLATE_ID_EXPR)
7345 {
…
7840 }
…
8163 {
8164 tree decl;
8165
8166 if (decl_context == PARM)
8167 {
…
8172 }
8173 else if (decl_context == FIELD)
8174 {
…
8427 }
8428 else if (TREE_CODE (type) == FUNCTION_TYPE
8429 || TREE_CODE (type) == METHOD_TYPE)
8430 {
…
8514 }
8515 else
8516 {
8517 /* It's a variable. */
8518
8519 /* An uninitialized decl with `extern' is a reference. */
8520 decl = grokvardecl (type, declarator, &specbits,
8521 initialized,
8522 (type_quals & TYPE_QUAL_CONST) != 0,
8523 ctype ? ctype : in_namespace);
8524 bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE,
8525 inlinep, friendp, raises != NULL_TREE);
8526
8527 if (ctype)
8528 {
…
8547 }
8548 }
8549
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 }
在上面的代码中,显然 6525 行的 WHILE 块验证声明符部分;而 6844 行的 FOR 块验证并提前对应的 type-specifier 。注意到在 6941 行, type 指向上一节中所构建的 RECORD_TYPE 。
接着 type 及 declarator 将被组合起来由 grokvardecl 来构成期望的 VAR_DECL 。注意到对于我们的情形,在调用期间,参数 scope 是 NULL , constp 是 false , initialized 是 false ,而 specbits_in 包含了 0 。
5885 static tree
5886 grokvardecl (tree type, in decl.c
5887 tree name,
5888 RID_BIT_TYPE * specbits_in,
5889 int initialized,
5890 int constp,
5891 tree scope)
5892 {
5893 tree decl;
5894 tree explicit_scope;
5895 RID_BIT_TYPE specbits;
5896
5897 my_friendly_assert (!name || TREE_CODE (name) == IDENTIFIER_NODE,
5898 20020808);
5899
5900 specbits = *specbits_in;
5901
5902 /* Compute the scope in which to place the variable, but remember
5903 whether or not that scope was explicitly specified by the user. */
5904 explicit_scope = scope;
5905 if (!scope)
5906 {
5907 /* An explicit "extern" specifier indicates a namespace-scope
5908 variable. */
5909 if (RIDBIT_SETP (RID_EXTERN, specbits))
5910 scope = current_namespace;
5911 else if (!at_function_scope_p ())
5912 {
5913 scope = current_scope ();
5914 if (!scope)
5915 scope = current_namespace;
5916 }
5917 }
5918
5919 if (scope
5920 && (/* If the variable is a namespace-scope variable declared in a
5921 template, we need DECL_LANG_SPECIFIC. */
5922 (TREE_CODE (scope) == NAMESPACE_DECL && processing_template_decl)
5923 /* Similarly for namespace-scope variables with language linkage
5924 other than C++. */
5925 || (TREE_CODE (scope) == NAMESPACE_DECL
5926 && current_lang_name != lang_name_cplusplus)
5927 /* Similarly for static data members. */
5928 || TYPE_P (scope)))
5929 decl = build_lang_decl (VAR_DECL, name, type);
5930 else
5931 decl = build_decl (VAR_DECL, name, type);
5932
5933 if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL)
5934 set_decl_namespace (decl, explicit_scope, 0);
5935 else
5936 DECL_CONTEXT (decl) = scope;
5937
5938 if (name && scope && current_lang_name != lang_name_c)
5939 /* We can't mangle lazily here because we don't have any
5940 way to recover whether or not a variable was `extern
5941 "C"' later. */
5942 mangle_decl (decl);
5943
5944 if (RIDBIT_SETP (RID_EXTERN, specbits))
5945 {
5946 DECL_THIS_EXTERN (decl) = 1;
5947 DECL_EXTERNAL (decl) = !initialized;
5948 }
5949
5950 /* In class context, static means one per class,
5951 public access, and static storage. */
5952 if (DECL_CLASS_SCOPE_P (decl))
5953 {
5954 TREE_PUBLIC (decl) = 1;
5955 TREE_STATIC (decl) = 1;
5956 DECL_EXTERNAL (decl) = 0;
5957 }
5958 /* At top level, either `static' or no s.c. makes a definition
5959 (perhaps tentative), and absence of `static' makes it public. */
5960 else if (toplevel_bindings_p ())
5961 {
5962 TREE_PUBLIC (decl) = (RIDBIT_NOTSETP (RID_STATIC, specbits)
5963 && (DECL_THIS_EXTERN (decl) || ! constp));
5964 TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
5965 }
5966 /* Not at top level, only `static' makes a static definition. */
5967 else
5968 {
5969 TREE_STATIC (decl) = !! RIDBIT_SETP (RID_STATIC, specbits);
5970 TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
5971 }
5972
5973 if (RIDBIT_SETP (RID_THREAD, specbits))
5974 {
5975 if (targetm .have_tls)
5976 DECL_THREAD_LOCAL (decl) = 1;
5977 else
5978 /* A mere warning is sure to result in improper semantics
5979 at runtime. Don't bother to allow this to compile. */
5980 error ("thread-local storage not supported for this target");
5981 }
5982
5983 if (TREE_PUBLIC (decl))
5984 {
5985 /* [basic.link]: A name with no linkage (notably, the name of a class
5986 or enumeration declared in a local scope) shall not be used to
5987 declare an entity with linkage.
5988
5989 Only check this for public decls for now. */
5990 tree t = no_linkage_check (TREE_TYPE (decl));
5991 if (t)
5992 {
5993 if (TYPE_ANONYMOUS_P (t))
5994 /* Ignore for now; `enum { foo } e' is pretty common. */;
5995 else
5996 pedwarn ("non-local variable `%#D' uses local type `%T'",
5997 decl, t);
5998 }
5999 }
6000
6001 return decl;
6002 }
在这一步之后,我们得到下图中的 VAR_DECL 。看到该节点的 context 域是 NULL ,因为我们不在类作用域中。
( 点此打开 )
start_decl (continue)
3832 /* Enter this declaration into the symbol table. */
3833 tem = maybe_push_decl (decl);
3834
3835 if (processing_template_decl)
3836 tem = push_template_decl (tem);
3837 if (tem == error_mark_node)
3838 return error_mark_node;
3839
3840 #if ! defined ( ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS)
3841 /* Tell the back-end to use or not use .common as appropriate. If we say
3842 -fconserve-space, we want this to save .data space, at the expense of
3843 wrong semantics. If we say -fno-conserve-space, we want this to
3844 produce errors about redefs; to do this we force variables into the
3845 data segment. */
3846 DECL_COMMON (tem) = ((TREE_CODE (tem) != VAR_DECL
3847 || !DECL_THREAD_LOCAL (tem))
3848 && (flag_conserve_space || ! TREE_PUBLIC (tem)));
3849 #endif
3850
3851 if (! processing_template_decl)
3852 start_decl_1 (tem);
3853
3854 return tem;
3855 }
作为一个 context 域为 NULL 的 VAR_DECL 节点, maybe_push_decl 为 decl 调用 pushdecl 。而对于我们的例子,在 3852 行的 start_decl_1 不做任何事。
566 tree
567 pushdecl (tree x) in name-lookup.c
568 {
569 tree t;
570 tree name;
571 int need_new_binding;
572
573 timevar_push (TV_NAME_LOOKUP);
574
575 need_new_binding = 1;
576
577 if (DECL_TEMPLATE_PARM_P (x))
578 /* Template parameters have no context; they are not X::T even
579 when declared within a class or namespace. */
580 ;
581 else
582 {
583 if (current_function_decl && x != current_function_decl
584 /* A local declaration for a function doesn't constitute
585 nesting. */
586 && TREE_CODE (x) != FUNCTION_DECL
587 /* A local declaration for an `extern' variable is in the
588 scope of the current namespace, not the current
589 function. */
590 && !(TREE_CODE (x) == VAR_DECL && DECL_EXTERNAL (x))
591 && !DECL_CONTEXT (x))
592 DECL_CONTEXT (x) = current_function_decl ;
…
602 }
603
604 name = DECL_NAME (x);
605 if (name)
606 {
607 int different_binding_level = 0;
…
615 /* In case this decl was explicitly namespace-qualified, look it
616 up in its namespace context. */
617 if (DECL_NAMESPACE_SCOPE_P (x) && namespace_bindings_p ())
618 t = namespace_binding (name, DECL_CONTEXT (x));
619 else
620 t = lookup_name_current_level (name);
…
828 /* This name is new in its binding level.
829 Install the new declaration and return it. */
830 if (namespace_bindings_p ())
831 {
…
872 }
873 else
874 {
875 /* Here to install a non-global value. */
876 tree oldlocal = IDENTIFIER_VALUE (name);
877 tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name);
878
879 if (need_new_binding)
880 {
881 push_local_binding (name, x, 0);
882 /* Because push_local_binding will hook X on to the
883 current_binding_level's name list, we don't want to
884 do that again below. */
885 need_new_binding = 0;
886 }
…
1003 }
1004
1005 if (TREE_CODE (x) == VAR_DECL)
1006 maybe_register_incomplete_var (x);
1007 }
…
1015 POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
1016 }
我们已经多次看过 pushdecl ;再次我们在上面给出该函数得到执行部分的代码。看到在 1006 行的 maybe_register_incomplete_var 对非外部的 VAR_DECL 不做处理。在退出 start_decl 时,我们得到如下的中间树。
( 点此打开 )
cp_parser_init_declarator (continue)
10111 /* Enter the SCOPE. That way unqualified names appearing in the
10112 initializer will be looked up in SCOPE. */
10113 if (scope)
10114 pop_p = push_scope (scope);
10115
10116 /* Perform deferred access control checks, now that we know in which
10117 SCOPE the declared entity resides. */
10118 if (!member_p && decl)
10119 {
10120 tree saved_current_function_decl = NULL_TREE;
10121
10122 /* If the entity being declared is a function, pretend that we
10123 are in its scope. If it is a `friend', it may have access to
10124 things that would not otherwise be accessible. */
10125 if (TREE_CODE (decl) == FUNCTION_DECL)
10126 {
10127 saved_current_function_decl = current_function_decl ;
10128 current_function_decl = decl;
10129 }
10130
10131 /* Perform the access control checks for the declarator and the
10132 the decl-specifiers. */
10133 perform_deferred_access_checks ();
10134
10135 /* Restore the saved value. */
10136 if (TREE_CODE (decl) == FUNCTION_DECL)
10137 current_function_decl = saved_current_function_decl;
10138 }
10139
10140 /* Parse the initializer. */
10141 if (is_initialized)
10142 initializer = cp_parser_initializer (parser,
10143 &is_parenthesized_init,
10144 &is_non_constant_init);
10145 else
10146 {
10147 initializer = NULL_TREE;
10148 is_parenthesized_init = false;
10149 is_non_constant_init = true;
10150 }
…
10178 /* Finish processing the declaration. But, skip friend
10179 declarations. */
10180 if (!friend_p && decl)
10181 cp_finish_decl (decl,
10182 initializer,
10183 asm_specification,
10184 /* If the initializer is in parentheses, then this is
10185 a direct-initialization, which means that an
10186 `explicit' constructor is OK. Otherwise, an
10187 `explicit' constructor cannot be used. */
10188 ((is_parenthesized_init || !is_initialized)
10189 ? 0 : LOOKUP_ONLYCONVERTING));
10190
10191 /* Remember whether or not variables were initialized by
10192 constant-expressions. */
10193 if (decl && TREE_CODE (decl) == VAR_DECL
10194 && is_initialized && !is_non_constant_init)
10195 DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
10196
10197 return decl;
10198 }
注意到在为 template-id 及 VAR_DECL 构建了节点之后,正是为相关声明符及 decl-specifier 执行延迟访问检查的时机。看到访问控制检查失败不会停止解析器。