GCC-3.4.6源代码学习笔记 (100)

5.12.3.2.1.1.3.4.2.            为方法构建节点

显然,现在 declarator 是一个 tree_list 节点,并且 declares_class_or_enum 保存为 0 (如果它为非 0 ,表示在 decl-specifier 中看到了 elaborate-type-specifier class-specifier enum-specifier )。

 

cp_parser_member_declaration (continue)

 

12672          /* If something went wrong parsing the declarator, make sure

12673            that we at least consume some tokens.  */

12674          if (declarator == error_mark_node)

12675         {

12676             /* Skip to the end of the statement.  */

12677            cp_parser_skip_to_end_of_statement (parser);

12678             /* If the next token is not a semicolon, that is

12679              probably because we just skipped over the body of

12680              a function. So, we consume a semicolon if

12681              present, but do not issue an error message if it

12682              is not present.  */

12683            if (cp_lexer_next_token_is (parser->lexer,

12684                                  CPP_SEMICOLON))

12685             cp_lexer_consume_token (parser->lexer);

12686           return ;

12687         }

12688

12689          if (declares_class_or_enum & 2)

12690           cp_parser_check_for_definition_in_return_type

12691                      (declarator, TREE_VALUE (decl_specifiers));

12692

12693          /* Look for an asm-specification.  */

12694          asm_specification = cp_parser_asm_specification_opt (parser);

12695           /* Look for attributes that apply to the declaration.  */

12696         attributes = cp_parser_attributes_opt (parser);

12697         /* Remember which attributes are prefix attributes and

12698           which are not.  */

12699           first_attribute = attributes;

12700          /* Combine the attributes.  */

12701         attributes = chainon (prefix_attributes, attributes);

12702

12703         /* If it's an `=', then we have a constant-initializer or a

12704            pure-specifier. It is not correct to parse the

12705            initializer before registering the member declaration

12706            since the member declaration should be in scope while

12707            its initializer is processed. However, the rest of the

12708             front end does not yet provide an interface that allows

12709            us to handle this correctly.  */

12710          if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))

12711         {

                …

12730         }

12731          /* Otherwise, there is no initializer.  */

12732          else

12733           initializer = NULL_TREE;

12734

12735          /* See if we are probably looking at a function

12736            definition. We are certainly not looking at at a

12737            member-declarator. Calling `grokfield' has

12738            side-effects, so we must not do it unless we are sure

12739            that we are looking at a member-declarator.  */

12740          if (cp_parser_token_starts_function_definition_p

12741                   ( cp_lexer_peek_token (parser->lexer)))

12742         {

12743           /* The grammar does not allow a pure-specifier to be

12744             used when a member function is defined. (It is

12745             possible that this fact is an oversight in the

12746             standard, since a pure function may be defined

12747             outside of the class-specifier.  */

12748           if (initializer)

12749             error ("pure-specifier on function-definition");

12750           decl = cp_parser_save_member_function_body (parser,

12751                                                   decl_specifiers,

12752                                                  declarator,

12753                                                  attributes);

12754            /* If the member was not a friend, declare it here.  */

12755            if (!friend_p)

12756             finish_member_declaration (decl);

12757           /* Peek at the next token.  */

12758           token = cp_lexer_peek_token (parser->lexer);

12759           /* If the next token is a semicolon, consume it.  */

12760           if (token->type == CPP_SEMICOLON)

12761             cp_lexer_consume_token (parser->lexer);

12762           return ;

12763         }

              …

12775        }

            …

12811     }

12812   }

12813

12814   cp_parser_require (parser, CPP_SEMICOLON, "`;'");

12815 }

 

来到此处 需要检查是否仅是函数声明而不是定义。 看到在下面的 15191 行,检查是否有 function-try-block 部分。一个 function-try-block 把一个 handler-seq ctor-initializer (构造函数初始化列表,如果它出现)及函数体关联起来。在执行 ctor-initializer 中的初始化表达式或函数体期间抛出的异常,把控制转给在 function-try-block 中的句柄。就像在执行一个 try-block 期间抛出的异常把控制转给其句柄那样。例如:

int f(int);

class C {

int i;

double d;

public :

C(int, double);

};

 

C::C(int ii, double id)

try

: i(f(ii)), d(id) {

// constructor function body

}

catch (...) {

// handles exceptions thrown from the ctor-initializer

// and from the constructor function body

}

进一步的 GNU C++ 扩展了函数定义的语法允许在定义体外指定函数返回值的名字。当一个函数的返回类型是一个类时,你可以使用这个特性避免额外的构造函数的调用。例如,考虑函数 m ,表达“ X v = m (); ”,其返回值具有类型 class X

X m () {

  X b;

  b.a = 23;

  return b;

}

虽然 m 看上去没有参数,实际上它有一个隐含的参数:返回值的地址。在调用中,足够包含 v 的空间的地址被传给这个隐含参数。然后 b 被构建并且其 a 域被设置为值 23 。最后,一个拷贝构造函数(具有形式“ X(X&) ”的构造函数)被应用到 b ,把这个(隐含的)返回值地址作为目标,因此 v 现在被绑定到这个返回值。

但这样很浪费。局部变量 b 被声明做仅保存立刻就被拷贝出去物件。而一个具有结合了“省略( elision )”算法的过程间( interprocedural )数据流分析的编译器,将毫无疑问,可以消除这些情况。更为可行的方式是允许你协助编译器通过显式地操纵返回值,从而完全避免局部变量及拷贝构造函数,来产生高效的代码。

使用 GNU C++ 扩展的函数定义语法,你可以一开始通过命名 r 作为你的返回值,避免临时分配及拷贝,而直接向其赋值。

X m () return r;

{

  r.a = 23;

}

r 的声明是一个标准、正确的声明,其效果( effect )在 m 的定义体 得到执行。

这种类型的函数并不施加额外的约束,特别地,你可以执行返回语句,或者通过到达函数末尾隐含地返回(“越过边缘, falling off the edge ”)。例如:

X m () return r (23);

{

  return ;

}

(甚至“ X m () return r (23); { } ”)是明确的,因为在每个情况下返回值 r 都得到初始化。下面的代码可能不太好读,不过同样可以以期望的方式工作:

X m () return r;

{

  X b;

  return b;

}

r 标记的返回值的位置一开始就得到了初始化,不过语句“ return b; ”改写了这个值。编译器通过摧毁 r (调用析构函数如果有的话,或不做任何事如果没有),然后用 b 重新初始化 r

这个扩展主要是提供给使用重载操作符的人,他们通常不仅需要控制参数,而且还要控制函数的返回值。对于那些拷贝构造函数会招致性能影响的类(尤其是通常情况下,都会有一个快速的默认构造函数),这将是一个很大的节约。这个扩展的坏处是你不能控制返回值的默认构造函数的调用:它永远在一开始被调用。

这个特性已经过时,并将在 g++ v4 中移除,因为上面提及的情形都可以通过小心设计而避免。

 

15183 static bool

15184 cp_parser_token_starts_function_definition_p (cp_token* token)                  in parser.c

15185 {

15186   return (/* An ordinary function-body begins with an `{'.  */

15187         token->type == CPP_OPEN_BRACE

15188         /* A ctor-initializer begins with a `:'.  */

15189         || token->type == CPP_COLON

15190         /* A function-try-block begins with `try'.  */

15191         || token->keyword == RID_TRY

15192         /* The named return value extension begins with `return'.  */

15193         || token->keyword == RID_RETURN);

15194 }

 

在看到这是一个函数定义后,在 12750 行进入下面的函数。特别的现在对于构造函数 decl_specifiers NULL

 

14635 static tree

14636 cp_parser_save_member_function_body (cp_parser* parser,                        in parser.c

14637                                   tree decl_specifiers,

14638                                    tree declarator,

14639                                   tree attributes)

14640 {

14641   cp_token_cache *cache;

14642   tree fn;

14643

14644   /* Create the function-declaration.  */

14645   fn = start_method (decl_specifiers, declarator, attributes);

14646   /* If something went badly wrong, bail out now.  */

14647   if (fn == error_mark_node)

14648   {

14649     /* If there's a function-body, skip it.  */

14650     if (cp_parser_token_starts_function_definition_p

14651                  (cp_lexer_peek_token (parser->lexer)))

14652       cp_parser_skip_to_end_of_block_or_statement (parser);

14653     return error_mark_node;

14654   }

 

为指定的方法创建及向中间树加入节点是一个复杂的工作。它由 start_method 启动。

 

11032 tree

11033 start_method (tree declspecs, tree declarator, tree attrlist)                                           in decl.c

11034 {

11035   tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,

11036                          &attrlist);

 

在这里的 grokdeclarator 参数 decl_context MEMFUNCDEF 。下面在函数中使用的枚举值用来在整个过程中保存声明符的特殊信息。

 

22      enum decl_context                                                                                           in decl.h

23      { NORMAL,                     /* Ordinary declaration */

24        FUNCDEF,                   /* Function definition */

25        PARM,                          /* Declaration of parm before function body */

26        CATCHPARM,               /* Declaration of catch parm */

27        FIELD,                /* Declaration inside struct or union */

28        BITFIELD,                    /* Likewise but with specified width */

29        TYPENAME,                /* Typename (inside cast or sizeof)  */

30        MEMFUNCDEF            /* Member function definition */

31      };

 

3003   typedef enum special_function_kind {                                                        in cp-tree.h

3004     sfk_none = 0,            /* Not a special function. This enumeral

3005                               must have value zero; see

3006                               special_function_p.  */

3007     sfk_constructor,         /* A constructor.  */

3008     sfk_copy_constructor,    /* A copy constructor.  */

3009     sfk_assignment_operator, /* An assignment operator.  */

3010     sfk_destructor,           /* A destructor.  */

3011     sfk_complete_destructor, /* A destructor for complete objects.  */

3012     sfk_base_destructor,     /* A destructor for base subobjects.  */

3013     sfk_deleting_destructor, /* A destructor for complete objects that

3014                            deletes the object after it has been

3015                            destroyed.  */

3016     sfk_conversion           /* A conversion operator.  */

3017   } special_function_kind;

 

3314   enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };

 

在这个函数的开始,一长串标记被初始化。在 6469 行, RID_BIT_TYPE unsigned long 的别名。而 6510 行的 RIDBIT_RESET_ALL 重置这个变量。

 

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         {

6530           case TREE_LIST:

6531             /* For attributes.  */

6532             next = &TREE_VALUE (decl);

6533             break ;

          …

6591            case CALL_EXPR:

6592             innermost_code = TREE_CODE (decl);

6593             if (decl_context == FIELD && ctype == NULL_TREE)

6594               ctype = current_class_type ;

6595             if (ctype

6596                && TREE_OPERAND (decl, 0)

6597                 && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL

6598                && constructor_name_p (DECL_NAME (TREE_OPERAND (decl, 0)),

6599                                     ctype)))

6600               TREE_OPERAND (decl, 0) = constructor_name (ctype);

6601             next = &TREE_OPERAND (decl, 0);

6602             decl = *next;

6603             if (ctype != NULL_TREE

6604                && decl != NULL_TREE && flags != DTOR_FLAG

6605                && constructor_name_p (decl, ctype))

6606             {

6607                sfk = sfk_constructor;

6608               ctor_return_type = ctype;

6609             }

6610             ctype = NULL_TREE;

6611             break ;

        …

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             {

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 = "<invalid operator>";

6653             }

6654             break ;

              …

6684         }

6685       }

6686     }

 

第一个 WHILE 循环探索这个声明符,并相应地设置控制标记。看到对于我们的例子语句,在第一次迭代中, TREE_CODE tree_list ,而在第二次迭代中, TREE_CODE CALL_EXPR 。对于构造函数, 6605 行的 constructor_name_p 返回 true ,而此时 ctype 指向当前类。注意 CALL_EXPR 节点的操作数 0 是相应的 IDENTIFIER_NODE 。在最后的迭代中,作为 IDENTIFIER_NODE 但不是操作符, 6642 行的代码得到执行,由 IDENTIFIER_POINTER 返回表示名字的字符串。

此刻,我们得到 ctype NULL ), sfk sfk_constructor ), name “Lock” ), ctor_return_type current_class_type ), funcdef_flag -1 ), decl_context FIELD ), innermost_code CALL_EXPR )。

 

grokdeclarator (continue)

 

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;

6793  

6794     if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG)

6795         && innermost_code != CALL_EXPR

6796         && ! (ctype && declspecs == NULL_TREE))

6797     {

6798       error ("declaration of `%D' as non-function", dname);

6799       return void_type_node;

6800     }

        …

6973     typedef_type = type;

6974  

6975     /* No type at all: default to `int', and set DEFAULTED_INT

6976       because it was not a user-defined typedef.  */

6977  

6978     if (type == NULL_TREE

6979        && (RIDBIT_SETP (RID_SIGNED, specbits)

6980            || RIDBIT_SETP (RID_UNSIGNED, specbits)

6981            || RIDBIT_SETP (RID_LONG, specbits)

6982            || RIDBIT_SETP (RID_SHORT, specbits)))

6983     {

6984       /* These imply 'int'.  */

6985       type = integer_type_node;

6986       defaulted_int = 1;

6987     }

6988  

6989     if (sfk != sfk_none)

6990       type = check_special_function_return_type (sfk, type,

6991                                           ctor_return_type);

6992     else if (type == NULL_TREE)

6993     {

         …

7017     }

7018    

7019     ctype = NULL_TREE;

 

如果 sfk sfk_none ,它表示该声明符不是由 special_function_kind 所指出的特殊函数之一。在这些特殊函数里,构造函数,析构函数及转换操作符都不允许指定返回类型。下面除了转换操作符, type 被设置为 void

 

6361   static tree

6362   check_special_function_return_type (special_function_kind sfk,                          in decl.c

6363                                  tree type,

6364                                  tree optype)

6365   {

6366     switch (sfk)

6367     {

6368       case sfk_constructor:

6369         if (type)

6370           error ("return type specification for constructor invalid");

6371  

6372         type = void_type_node;

6373         break ;

6374  

6375       case sfk_destructor:

6376         if (type)

6377           error ("return type specification for destructor invalid");

6378         type = void_type_node;

6379         break ;

6380  

6381       case sfk_conversion:

6382         if (type && !same_type_p (type, optype))

6383           error ("operator `%T' declared to return `%T'", optype, type);

6384         else if (type)

6385            pedwarn ("return type specified for `operator %T'",  optype);

6386         type = optype;

6387         break ;

6388  

6389       default :

6390         abort ();

6391         break ;

6392     }

6393  

6394     return type;

6395   }

 

显然,下面的 type_quals 保存了 cv-qualifier (限定词)的信息。注意到对于转换操作符,不可用指定限定词。那么,前端需要从非限定类型来产生限定类型(记住仅限定词不同的类型被串接在一起, TYPE_MAIN_VARIANT 总是返回非限定类型,而 TYPE_NEXT_VARIANT 依次返回限定类型。

 

grokdeclarator (continue)

 

7161     type_quals = TYPE_UNQUALIFIED;

7162     if (RIDBIT_SETP (RID_CONST, specbits))

7163       type_quals |= TYPE_QUAL_CONST;

7164     if (RIDBIT_SETP (RID_VOLATILE, specbits))

7165       type_quals |= TYPE_QUAL_VOLATILE;

7166     if (RIDBIT_SETP (RID_RESTRICT, specbits))

7167       type_quals |= TYPE_QUAL_RESTRICT;

7168     if (sfk == sfk_conversion && type_quals != TYPE_UNQUALIFIED)

7169       error ("qualifiers are not allowed on declaration of `operator %T'",

7170             ctor_return_type);

 

现在,在上面的准备及检查后,有 type void_type_node ), scope NULL ), quals NULL ),及 type_quals TYPE_UNQUALIFIED )。

 

grokdeclarator (continue)

 

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     {

7346       /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]),

7347         an INDIRECT_REF (for *...),

7348         a CALL_EXPR (for ...(...)),

7349          an identifier (for the name being declared)

7350          or a null pointer (for the place in an absolute declarator

7351          where the name was omitted).

7352          For the last two cases, we have just exited the loop.

7353  

7354         For C++ it could also be

7355          a SCOPE_REF (for class :: ...). In this case, we have converted

7356          sensible names to types, and those are the values we use to

7357          qualify the member name.

7358          an ADDR_EXPR (for &...),

7359          a BIT_NOT_EXPR (for destructors)

7360  

7361          At this point, TYPE is the type of elements of an array,

7362          or for a function to return, or for a pointer to point to.

7363          After this sequence of ifs, TYPE is the type of the

7364          array or function or pointer, and DECLARATOR has had its

7365          outermost layer removed.  */

7366  

7367       if (type == error_mark_node)

7368       {

7369         if (declarator == error_mark_node)

7370           return error_mark_node;

7371         else if (TREE_CODE (declarator) == SCOPE_REF)

7372           declarator = TREE_OPERAND (declarator, 1);

7373         else

7374           declarator = TREE_OPERAND (declarator, 0);

7375         continue ;

7376       }

7377       if (quals != NULL_TREE

7378         && (declarator == NULL_TREE

7379             || TREE_CODE (declarator) != SCOPE_REF))

7380       {

7381         if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE)

7382           ctype = TYPE_METHOD_BASETYPE (type);

7383         if (ctype != NULL_TREE)

7384         {

7385           tree dummy = build_decl (TYPE_DECL, NULL_TREE, type);

7386           grok_method_quals (ctype, dummy, quals);

7387           type = TREE_TYPE (dummy);

7388           quals = NULL_TREE;

7389         }

7390       }

7391  

7392       switch (TREE_CODE (declarator))

7393       {

7394         case TREE_LIST:

7395         {

7396           /* We encode a declarator with embedded attributes using

7397             a TREE_LIST.  */

7398           tree attrs = TREE_PURPOSE (declarator);

7399           tree inner_decl;

7400           int attr_flags;

7401  

7402           declarator = TREE_VALUE (declarator);

7403           inner_decl = declarator;

7404           while (inner_decl != NULL_TREE

7405                 && TREE_CODE (inner_decl) == TREE_LIST)

7406             inner_decl = TREE_VALUE (inner_decl);

7407           attr_flags = 0;

7408           if (inner_decl == NULL_TREE

7409              || TREE_CODE (inner_decl) == IDENTIFIER_NODE)

7410             attr_flags |= (int) ATTR_FLAG_DECL_NEXT;

7411           if (TREE_CODE (inner_decl) == CALL_EXPR)

7412             attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;

7413           if (TREE_CODE (inner_decl) == ARRAY_REF)

7414             attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;

7415           returned_attrs = decl_attributes (&type,

7416                                      chainon (returned_attrs, attrs),

7417                                     attr_flags);

7418         }

7419         break ;

 

在第一次执行上面的 WHILE 循环中, declarator TREE_PURPOSE 为属性链表,而 TREE_VALUE CALL_EXPR tree_list 。函数 decl_attributes 将安装在 type 节点中指定的属性;不过在这里属性链表为空。不管怎样,在 7402 行的 declarator 现在指向这个 CALL_EXPR 节点。

 

grokdeclarator (continue)

 

7432         case CALL_EXPR:

7433         {

7434           tree arg_types;

7435           int funcdecl_p;

7436           tree inner_parms = CALL_DECLARATOR_PARMS (declarator);

7437           tree inner_decl = TREE_OPERAND (declarator, 0);

7438  

7439           /* Declaring a function type.

7440             Make sure we have a valid type for the function to return.  */

7441  

7442           /* We now know that the TYPE_QUALS don't apply to the

7443              decl, but to its return type.  */

7444           type_quals = TYPE_UNQUALIFIED;

7445  

7446           /* Warn about some types functions can't return.  */

7447  

7448           if (TREE_CODE (type) == FUNCTION_TYPE)

7449           {

7450             error ("`%s' declared as function returning a function", name);

7451             type = integer_type_node;

7452           }

7453           if (TREE_CODE (type) == ARRAY_TYPE)

7454           {

7455             error ("`%s' declared as function returning an array", name);

7456             type = integer_type_node;

7457           }

7458  

7459           if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF)

7460             inner_decl = TREE_OPERAND (inner_decl, 1);

7461  

7462           if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR)

7463             inner_decl = dname;

7464  

7465           /* Pick up type qualifiers which should be applied to `this'.  */

7466           quals = CALL_DECLARATOR_QUALS (declarator);

7467  

7468           /* Pick up the exception specifications.  */

7469            raises = CALL_DECLARATOR_EXCEPTION_SPEC (declarator);

7470  

7471           /* Say it's a definition only for the CALL_EXPR

7472              closest to the identifier.  */

7473           funcdecl_p

7474              = inner_decl

7475                && (TREE_CODE (inner_decl) == IDENTIFIER_NODE

7476                     || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR

7477                     || TREE_CODE (inner_decl) == BIT_NOT_EXPR);

7478  

7479           if (ctype == NULL_TREE

7480              && decl_context == FIELD

7481              && funcdecl_p

7482              && (friendp == 0 || dname == current_class_name))

7483             ctype = current_class_type ;

 

对于这个 CALL_EXPR 节点,我们已经在学习函数 cp_parser_direct_declarator make_call_declarator 时看过其布局。这里宏 CALL_DECLARATOR_* 提取相关的子节点。此刻,有 ctype current_class_type ), funcdecl_p 1 ), decl_context FIELD ), quals NULL_TREE ), raises NULL_TREE ), inner_parms void_list_node ), explicitp 0 ), staticp 0 ), specbits 0 ), type void_type_node )及 virtualp 0 )。

 

grokdeclarator (continue)

 

7485           if (ctype && sfk == sfk_conversion)

7486             TYPE_HAS_CONVERSION (ctype) = 1;

7487           if (ctype && constructor_name_p (dname, ctype))

7488           {

7489             /* We are within a class's scope. If our declarator name

7490                is the same as the class name, and we are defining

7491                a function, then it is a constructor/destructor, and

7492                therefore returns a void type.  */

7493  

7494             if (flags == DTOR_FLAG)

7495             {

                  …

7514             }

7515             else             /* It's a constructor.  */

7516             {

7517               if (explicitp == 1)

7518                 explicitp = 2;

7519               /* ISO C++ 12.1. A constructor may not be

7520                  declared const or volatile. A constructor may

7521                  not be virtual. A constructor may not be

7522                  static.  */

7523               if (staticp == 2)

7524                 error ("constructor cannot be static member function");

7525               if (virtualp)

7526               {

7527                  pedwarn ("constructors cannot be declared virtual");

7528                 virtualp = 0;

7529               }

7530               if (quals)

7531               {

7532                 error ("constructors may not be `%s'",

7533                       IDENTIFIER_POINTER (TREE_VALUE (quals)));

7534                 quals = NULL_TREE;

7535               }

7536               {

7537                 RID_BIT_TYPE tmp_bits;

7538                 memcpy (&tmp_bits, &specbits, sizeof (RID_BIT_TYPE));

7539                 RIDBIT_RESET (RID_INLINE, tmp_bits);

7540                 RIDBIT_RESET (RID_STATIC, tmp_bits);

7541                 if (RIDBIT_ANY_SET (tmp_bits))

7542                   error ("return value type specifier for constructor ignored");

7543               }

7544               if (decl_context == FIELD)

7545               {

7546                 if (! member_function_or_else (ctype,

7547                                          current_class_type ,

7548                                          flags))

7549                   return void_type_node;

7550                 TYPE_HAS_CONSTRUCTOR (ctype) = 1;

7551                 if (sfk != sfk_constructor)

7552                   return NULL_TREE;

7553               }

7554             }

7555             if (decl_context == FIELD)

7556               staticp = 0;

7557            }

7558            else if (friendp)

7559            {

                …

7574           }

7575  

7576           /* Construct the function type and go to the next

7577              inner layer of declarator.  */

7578  

7579           declarator = TREE_OPERAND (declarator, 0);

7580  

7581           arg_types = grokparms (inner_parms, &parms);

7582  

7583           if (declarator && flags == DTOR_FLAG)

7584           {

7585             /* A destructor declared in the body of a class will

7586                be represented as a BIT_NOT_EXPR. But, we just

7587                want the underlying IDENTIFIER.  */

7588             if (TREE_CODE (declarator) == BIT_NOT_EXPR)

7589               declarator = TREE_OPERAND (declarator, 0);

7590  

7591             if (arg_types != void_list_node)

7592             {

7593               error ("destructors may not have parameters");

7594               arg_types = void_list_node;

7595               parms = NULL_TREE;

7596             }

7597           }

7598  

7599           /* ANSI says that `const int foo ();'

7600              does not make the function foo const.  */

7601           type = build_function_type (type, arg_types);

7602         }

7603         break ;

            …

7839       }

7840     }

 

上面的大部分代码用来确认被编译代码的正确性,其中在 7546 行, member_function_or_else 确认,对于构造函数或析构函数, ctype current_class_type 相同。 7601 行的 build_function_type 则创建了返回值及参数均为 void FUNCTION_TYPE 。因为在 7579 行, declarator 被更新为 INDENTIFIER_NODE ,因此将跳出这个 WHILE 循环。

 

grokdeclarator (continue)

 

7850     /* Now TYPE has the actual type.  */

7851  

7852     /* Did array size calculations overflow?  */

7853  

7854     if (TREE_CODE (type) == ARRAY_TYPE

7855        && COMPLETE_TYPE_P (type)

7856        && TREE_OVERFLOW (TYPE_SIZE (type)))

7857     {

7858       error ("size of array `%s' is too large", name);

7859       /* If we proceed with the array type as it is, we'll eventually

7860         crash in tree_low_cst().  */

7861       type = error_mark_node;

7862     }

7863  

7864     if ((decl_context == FIELD || decl_context == PARM)

7865        && !processing_template_decl

7866        && variably_modified_type_p (type))

7867     {

7868       if (decl_context == FIELD)

7869         error ("data member may not have variably modified type `%T'", type);

7870       else

7871         error ("parameter may not have variably modified type `%T'", type);

7872       type = error_mark_node;

7873     }

7874  

7875     if (explicitp == 1 || (explicitp && friendp))

7876     {

7877       /* [dcl.fct.spec] The explicit specifier shall only be used in

7878         declarations of constructors within a class definition.  */

7879       error ("only declarations of constructors can be `explicit'");

7880       explicitp = 0;

7881     }

7882  

7883     if (RIDBIT_SETP (RID_MUTABLE, specbits))

7884     {

          …

7911     }

7912  

7913     if (declarator == NULL_TREE

7914        || TREE_CODE (declarator) == IDENTIFIER_NODE

7915        || (TREE_CODE (declarator) == TEMPLATE_ID_EXPR

7916          && (TREE_CODE (type) == FUNCTION_TYPE

7917              || TREE_CODE (type) == METHOD_TYPE)))

7918       /* OK */ ;

7919     else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR)

7920     {

7921       error ("template-id `%D' used as a declarator", declarator);

7922       declarator = dname;

7923     }

7924     else

7925       /* Unexpected declarator format.  */

7926       abort ();

7927  

7928     /* If this is declaring a typedef name, return a TYPE_DECL.  */

7929  

7930     if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME)

7931     {

          …

8013     }

8014  

8015     /* Detect the case of an array type of unspecified size

8016       which came, as such, direct from a typedef name.

8017        We must copy the type, so that the array's domain can be

8018       individually set by the object's initializer.  */

8019  

8020     if (type && typedef_type

8021        && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)

8022        && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))

8023       type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);

8024  

8025     /* Detect where we're using a typedef of function type to declare a

8026       function. PARMS will not be set, so we must create it now.  */

8027    

8028     if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)

8029     {

          …

8042     }

8043  

8044     /* If this is a type name (such as, in a cast or sizeof),

8045       compute the type and return it now.  */

8046  

8047     if (decl_context == TYPENAME)

8048     {

          …

8115     }

8116     else if (declarator == NULL_TREE && decl_context != PARM

8117           && decl_context != CATCHPARM

8118           && TREE_CODE (type) != UNION_TYPE

8119           && ! bitfield)

8120     {

8121       error ("abstract declarator `%T' used as declaration", type);

8122       return error_mark_node;

8123     }

8124  

8125     /* Only functions may be declared using an operator-function-id.  */

8126     if (declarator

8127         && TREE_CODE (declarator) == IDENTIFIER_NODE

8128         && IDENTIFIER_OPNAME_P (declarator)

8129         && TREE_CODE (type) != FUNCTION_TYPE

8130         && TREE_CODE (type) != METHOD_TYPE)

8131     {

8132       error ("declaration of `%D' as non-function", declarator);

8133       return error_mark_node;

8134     }

8135  

8136     /* We don't check parameter types here because we can emit a better

8137       error message later.  */

8138     if (decl_context != PARM)

8139       type = check_var_type (declarator, type);

8140  

8141     /* Now create the decl, which may be a VAR_DECL, a PARM_DECL

8142       or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */

8143  

8144     if (decl_context == PARM || decl_context == CATCHPARM)

8145     {

          …

8161     }

 

如果遗漏了一小点不一致处,它的影响可能会被扩大到整个系统,因为这些节点可能被中间树中其他的多个节点引用。这里执行严格的检查,看一下应用的条件也是挺有趣的。上面在 7866 行,如果 type 具有可变大小, variably_modified_type_p 返回 true 。而 8139 行的 check_var_type 确认 type 不是声明为“ void ”。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值