Studying note of GCC-3.4.6 source (120)
来源:互联网 发布:白金数据结局神乐和龙 编辑:程序博客网 时间:2024/06/05 09:37
5.12.4.1.2.1. Processnon-type parameter
After parsing this non-type template parameter, no doubt, next itneeds process this parameter to finish the revelant sub-tree and insert it inthe intermediate tree.
2161 tree
2162 process_template_parm(tree list, tree next) in pt.c
2163 {
2164 tree parm;
2165 tree decl = 0;
2166 tree defval;
2167 int is_type, idx;
2168
2169 parm = next;
2170 my_friendly_assert (TREE_CODE (parm) ==TREE_LIST, 259);
2171 defval = TREE_PURPOSE (parm);
2172 parm = TREE_VALUE (parm);
2173 is_type = TREE_PURPOSE (parm) ==class_type_node;
2174
2175 if (list)
2176 {
2177 tree p = TREE_VALUE (tree_last (list));
2178
2179 if (TREE_CODE (p) == TYPE_DECL || TREE_CODE(p) == TEMPLATE_DECL)
2180 idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p));
2181 else
2182 idx = TEMPLATE_PARM_IDX (DECL_INITIAL(p));
2183 ++idx;
2184 }
2185 else
2186 idx = 0;
2187
2188 if (!is_type)
2189 {
2190 my_friendly_assert (TREE_CODE (TREE_PURPOSE(parm)) == TREE_LIST, 260);
2191 /* is aconst-param */
2192 parm = grokdeclarator (TREE_VALUE (parm),TREE_PURPOSE (parm),
2193 PARM, 0, NULL);
2194 SET_DECL_TEMPLATE_PARM_P (parm);
2195
2196 /* [temp.param]
2197
2198 The top-level cv-qualifierson the template-parameter are
2199 ignored when determining itstype. */
2200 TREE_TYPE (parm) = TYPE_MAIN_VARIANT(TREE_TYPE (parm));
2201
2202 /* A templateparameter is not modifiable. */
2203 TREE_READONLY (parm) = TREE_CONSTANT (parm)= 1;
2204 if (invalid_nontype_parm_type_p (TREE_TYPE(parm), 1))
2205 TREE_TYPE (parm) = void_type_node;
2206 decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
2207 TREE_CONSTANT (decl) = TREE_READONLY (decl)= 1;
2208 DECL_INITIAL (parm) = DECL_INITIAL (decl)
2209 = build_template_parm_index (idx,processing_template_decl,
2210 processing_template_decl,
2211 decl,TREE_TYPE (parm));
2212 }
2213 else
2214 {
…
2241 }
2242 DECL_ARTIFICIAL (decl) = 1;
2243 SET_DECL_TEMPLATE_PARM_P (decl);
2244 pushdecl (decl);
2245 parm = build_tree_list (defval, parm);
2246 returnchainon (list, parm);
2247 }
For our example: “size_t chunkSize = 4096”, the relevant sub-tree is refered by argument next of process_template_parm,then at line 2172 above, parm points to the part of “size_t chunSize”. Soat invocation of grokdeclarator, argument declarator points to tree nodes of“chunkSize”, then argument declspecs points to tree nodes “size_t”.
6462 tree
6463 grokdeclarator(tree declarator, in decl.c
6464 tree declspecs,
6465 enumdecl_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 intexplicit_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 enumtree_code innermost_code = ERROR_MARK;
6487 int bitfield = 0;
6488 #if 0
6489 /* See the codebelow that used this. */
6490 tree decl_attr = NULL_TREE;
6491 #endif
6492
6493 /* Keep track ofwhat sort of function is being processed
6494 so that we can warn aboutdefault return values, or explicit
6495 return values which do notmatch 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 adeclarator for the name being declared
6519 and get it as a string, for anerror 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 caseIDENTIFIER_NODE:
6630 if (TREE_CODE (decl) ==IDENTIFIER_NODE)
6631 dname = decl;
6632
6633 next = 0;
6634
6635 if (C_IS_RESERVED_WORD (dname))
6636 {
6637 error ("declarator-id missing;using reserved word `%D'",
6638 dname);
6639 name = IDENTIFIER_POINTER (dname);
6640 }
6641 else if (!IDENTIFIER_TYPENAME_P(dname))
6642 name = IDENTIFIER_POINTER (dname);
6643 else
6644 {
6645 my_friendly_assert (flags ==NO_SPECIAL, 154);
6646 flags = TYPENAME_FLAG;
6647 ctor_return_type = TREE_TYPE(dname);
6648 sfk = sfk_conversion;
6649 if (is_typename_at_global_scope(dname))
6650 name = IDENTIFIER_POINTER(dname);
6651 else
6652 name = "<invalidoperator>";
6653 }
6654 break;
…
6784 }
6785 }
6786 }
6787
6788 /*A function definition's declarator must have the form of
6789 a function declarator. */
6790
6791 if (funcdef_flag && innermost_code !=CALL_EXPR)
6792 return 0;
…
6828 /* Look through thedecl specs and record which ones appear.
6829 Some typespecs are defined asbuilt-in typenames.
6830 Others, the ones that aremodifiers of other types,
6831 are represented by bits inSPECBITS: set the bits for
6832 the modifiers that appear. Storageclass keywords are also in SPECBITS.
6833
6834 If there is a typedef name ora type, store the type in TYPE.
6835 This includes builtin typedefssuch as `int'.
6836
6837 Set EXPLICIT_INT if the typeis `int' or `char' and did not
6838 come from a user typedef.
6839
6840 Set LONGLONG if `long' ismentioned twice.
6841
6842 For C++, constructors anddestructors 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 parseerrors 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 entiredeclaration is itself tagged as deprecated then
6858 suppress reports ofdeprecated 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 {
6867 if (id == ridpointers[(int) RID_INT]
6868 || id == ridpointers[(int) RID_CHAR]
6869 || id == ridpointers[(int) RID_BOOL]
6870 || id == ridpointers[(int) RID_WCHAR])
6871 {
…
6888 }
6889 /* C++ aggregate types. */
6890 if(IDENTIFIER_HAS_TYPE_VALUE (id))
6890 {
…
6896 }
…
6947 if (type)
6948 error ("two or more data types indeclaration of `%s'", name);
6949 else if (TREE_CODE (id) ==IDENTIFIER_NODE)
6950 {
6951 tree t = lookup_name (id, 1);
6952 if (!t || TREE_CODE (t) != TYPE_DECL)
6953 error ("`%s' fails to be atypedef or built in type",
6954 IDENTIFIER_POINTER (id));
6955 else
6956 {
6957 type = TREE_TYPE (t);
6958 typedef_decl = t;
6959 }
6960 }
…
6965 found: ;
6966 }
6967
6968 #if 0
6969 /* See the codebelow that used this. */
6970 if (typedef_decl)
6971 decl_attr = DECL_ATTRIBUTES (typedef_decl);
6972 #endif
6973 typedef_type = type;
For declarator of IDENTIFIER_NODE only literal name is retrieved,and this name is used in error message to give out a clear description. Thenfor declspecs,it is a tree_list of only node of IDENTIFIER_NODE, which is refered by idabove. Then lookup_nameat line 6951 looks up this unqualified-name, and the corresponding TYPE_DECLnode would be returned. Notice that for the case, the parser can recognize thatit is a typedef. So variable type at line 6957 points to long_unsigned_type_node (assumingsize_t is typedef as unsigned long), and typedef_decl points to the TYPE_DECL.
grokdeclarator (continue)
8163 {
8164 tree decl;
8165
8166 if (decl_context == PARM)
8167 {
8168 decl = cp_build_parm_decl(declarator, type);
8169
8170 bad_specifiers(decl, "parameter", virtualp, quals != NULL_TREE,
8171 inlinep, friendp, raises !=NULL_TREE);
8172 }
…
8750 returndecl;
8751 }
8752 }
Same astype-parameter, node of TEMPLATE_PARM_INDEX needs be created to stand for thisparameter. Note that template parameter chunkSize can only be constant. A nodeof CONST_DECL is created automatically by parser to indicate the fact. From thenodes built here, it can easily tell out that, it is a constant declaration ofparameter declaration of template declaration.
(Clickhere for open)
Figure 107:non-type template parameter built
Then the namemust be pushed within current binding scope and let later name-lookup procedurefind out the correct declaration more efficiently. Routine pushdecl runs the same codeas previous template template parameter, and the parameter list after thispoint looks like below.
(Clickhere for open)
Figure 108:non-type template parameter pushed
See that bindings field of IDENTIFIER_NODE of “size_t”points to the CONST_DECL now, which indicates the local binding value.Name-lookup procedure will return this binding as result of searching withinthe scope.
Then thefollowing parameter is parsed and processed exactly the same. To keep conciseas possible, we just skip the procedure, and the intermediate tree layout canbe drawn accordingly and easily. When finishing parsing the template parameters,end_template_parm_listpacks the paramters according to following figure (note that the part ofparameter of “size_t maxSmallObjectSize” is not present in figure).
(Clickhere for open)
Figure 109: result of end_template_parm_list
- Studying note of GCC-3.4.6 source (120)
- Studying note of GCC-3.4.6 source (6)
- Studying note of GCC-3.4.6 source (1)
- Studying note of GCC-3.4.6 source (2)
- Studying note of GCC-3.4.6 source (3)
- Studying note of GCC-3.4.6 source (4)
- Studying note of GCC-3.4.6 source (5)
- Studying note of GCC-3.4.6 source (7)
- Studying note of GCC-3.4.6 source (8)
- Studying note of GCC-3.4.6 source (9)
- Studying note of GCC-3.4.6 source (10)
- Studying note of GCC-3.4.6 source (10 cont1)
- Studying note of GCC-3.4.6 source (10 cont2)
- Studying note of GCC-3.4.6 source (10 cont3)
- Studying note of GCC-3.4.6 source (10 cont4)
- Studying note of GCC-3.4.6 source (11)
- Studying note of GCC-3.4.6 source (12)
- Studying note of GCC-3.4.6 source (13)
- 寻找信心
- [劈]道德上支持腾讯!情感上支持奇虎!行动上全部抵制!
- 小酌独饮对月吟
- 摸索
- GCC-3.4.6源代码学习笔记(120)
- Studying note of GCC-3.4.6 source (120)
- 窗口刷新时的问题
- GCC-3.4.6源代码学习笔记(121)
- 喜欢羽球
- Studying note of GCC-3.4.6 source (121)
- 最后一个人可以挽救360和QQ的——马云
- VirtualBox安装Fedora后的相关设置1——全屏显示
- visibility 属性
- Ext JavaScript 运行机制