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

5.12.5.2.2.2.1.3.6.            完成派生类的 RECORD_TYPE 验证成员

接着验证模板具现体的非方法成员的有效性。

 

check_bases_and_members (continue)

 

4169     /* Check all the data member declarations.  */

4170     check_field_decls (t, &access_decls,

4171                    &cant_have_default_ctor,

4172                    &cant_have_const_ctor,

4173                    &no_const_asn_ref);

 

注意下面的 2996 行,数据成员的上下文( context )应该被更新为具现体的 RECORD_TYPE 节点。但对于 TYPE_DECL TEMPLATE_DECL ,正如我们在前面章节所见的,在替换过程中,其上下文已经被相应地替换了。不要动它们。

 

2917   static void

2918   check_field_decls (tree t, tree *access_decls,                                             in class.c

2919                   int *cant_have_default_ctor_p,

2920                   int *cant_have_const_ctor_p,

2921                   int *no_const_asn_ref_p)

2922   {

2923     tree *field;

2924     tree *next;

2925     int has_pointers;

2926     int any_default_members;

2927  

2928     /* Assume there are no access declarations.  */

2929     *access_decls = NULL_TREE;

2930     /* Assume this class has no pointer members.  */

2931     has_pointers = 0;

2932     /* Assume none of the members of this class have default

2933       initializations.  */

2934     any_default_members = 0;

2935  

2936     for (field = &TYPE_FIELDS (t); *field; field = next)

2937     {

2938       tree x = *field;

2939       tree type = TREE_TYPE (x);

2940  

2941       next = &TREE_CHAIN (x);

2942  

2943       if (TREE_CODE (x) == FIELD_DECL)

2944       {

2945         if (TYPE_PACKED (t))

2946         {

2947           if (!pod_type_p (TREE_TYPE (x)) && !TYPE_PACKED (TREE_TYPE (x)))

2948             cp_warning_at

2949                 ("ignoring packed attribute on unpacked non-POD field `%#D'",

2950                  x);

2951           else

2952              DECL_PACKED (x) = 1;

2953         }

2954  

2955         if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x)))

2956           /* We don't treat zero-width bitfields as making a class

2957             non-empty.  */

2958           ;

2959         else

2960         {

2961           tree element_type;

2962  

2963           /* The class is non-empty.  */

2964           CLASSTYPE_EMPTY_P (t) = 0;

2965           /* The class is not even nearly empty.  */

2966           CLASSTYPE_NEARLY_EMPTY_P (t) = 0;

2967           /* If one of the data members contains an empty class,

2968             so does T.  */

2969           element_type = strip_array_types (type);

2970           if (CLASS_TYPE_P (element_type)

2971              && CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type))

2972              CLASSTYPE_CONTAINS_EMPTY_CLASS_P (t) = 1;

2973         }

2974       }

2975  

2976       if (TREE_CODE (x) == USING_DECL)

2977       {

2978         /* Prune the access declaration from the list of fields.  */

2979         *field = TREE_CHAIN (x);

2980  

2981         /* Save the access declarations for our caller.  */

2982         *access_decls = tree_cons (NULL_TREE, x, *access_decls);

2983  

2984          /* Since we've reset *FIELD there's no reason to skip to the

2985           next field.  */

2986         next = field;

2987          continue ;

2988       }

2989  

2990       if (TREE_CODE (x) == TYPE_DECL

2991          || TREE_CODE (x) == TEMPLATE_DECL)

2992         continue ;

2993  

2994       /* If we've gotten this far, it's a data member, possibly static,

2995         or an enumerator.  */

2996       DECL_CONTEXT (x) = t;

2997  

2998       /* When this goes into scope, it will be a non-local reference.  */

2999       DECL_NONLOCAL (x) = 1;

3000  

3001       if (TREE_CODE (t) == UNION_TYPE)

3002       {

3003         /* [class.union]

3004  

3005           If a union contains a static data member, or a member of

3006           reference type, the program is ill-formed. */

3007         if (TREE_CODE (x) == VAR_DECL)

3008         {

3009           cp_error_at ("`%D' may not be static because it is a member of a union", x);

3010           continue ;

3011         }

3012         if (TREE_CODE (type) == REFERENCE_TYPE)

3013         {

3014           cp_error_at ("`%D' may not have reference type `%T' because it is a member of a union",

3015                      x, type);

3016           continue ;

3017         }

3018       }

3019  

3020        /* ``A local class cannot have static data members.'' ARM 9.4 */

3021       if (current_function_decl && TREE_STATIC (x))

3022         cp_error_at ("field `%D' in local class cannot be static", x);

3023  

3024        /* Perform error checking that did not get done in

3025         grokdeclarator.  */

3026       if (TREE_CODE (type) == FUNCTION_TYPE)

3027       {

3028         cp_error_at ("field `%D' invalidly declared function type",

3029                     x);

3030         type = build_pointer_type (type);

3031         TREE_TYPE (x) = type;

3032       }

3033       else if (TREE_CODE (type) == METHOD_TYPE)

3034       {

3035         cp_error_at ("field `%D' invalidly declared method type", x);

3036         type = build_pointer_type (type);

3037         TREE_TYPE (x) = type;

3038       }

3039  

3040       if (type == error_mark_node)

3041         continue ;

3042         

3043       if (TREE_CODE (x) == CONST_DECL || TREE_CODE (x) == VAR_DECL)

3044         continue ;

3045  

3046        /* Now it can only be a FIELD_DECL.  */

3047  

3048       if (TREE_PRIVATE (x) || TREE_PROTECTED (x))

3049         CLASSTYPE_NON_AGGREGATE (t) = 1;

3050  

3051       /* If this is of reference type, check if it needs an init.

3052         Also do a little ANSI jig if necessary.  */

3053       if (TREE_CODE (type) == REFERENCE_TYPE)

3054       {

3055         CLASSTYPE_NON_POD_P (t) = 1;

3056         if (DECL_INITIAL (x) == NULL_TREE)

3057           SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);

3058  

3059         /* ARM $12.6.2: [A member initializer list] (or, for an

3060           aggregate, initialization by a brace-enclosed list) is the

3061           only way to initialize nonstatic const and reference

3062           members.  */

3063         *cant_have_default_ctor_p = 1;

3064         TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;

3065  

3066         if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)

3067            && extra_warnings )

3068           cp_warning_at ("non-static reference `%#D' in class without a constructor", x);

3069       }

3070  

3071       type = strip_array_types (type);

3072        

3073       if (TYPE_PTR_P (type))

3074         has_pointers = 1;

3075  

3076       if (CLASS_TYPE_P (type))

3077       {

3078         if (CLASSTYPE_REF_FIELDS_NEED_INIT (type))

3079           SET_CLASSTYPE_REF_FIELDS_NEED_INIT (t, 1);

3080         if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (type))

3081           SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);

3082       }

3083  

3084       if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))

3085         CLASSTYPE_HAS_MUTABLE (t) = 1;

3086  

3087       if (! pod_type_p (type))

3088         /* DR 148 now allows pointers to members (which are POD themselves),

3089           to be allowed in POD structs.  */

3090         CLASSTYPE_NON_POD_P (t) = 1;

3091  

3092       if (! zero_init_p (type))

3093         CLASSTYPE_NON_ZERO_INIT_P (t) = 1;

3094  

3095       /* If any field is const, the structure type is pseudo-const.  */

3096       if (CP_TYPE_CONST_P (type))

3097       {

3098         C_TYPE_FIELDS_READONLY (t) = 1;

3099         if (DECL_INITIAL (x) == NULL_TREE)

3100           SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t, 1);

3101  

3102         /* ARM $12.6.2: [A member initializer list] (or, for an

3103           aggregate, initialization by a brace-enclosed list) is the

3104            only way to initialize nonstatic const and reference

3105           members.  */

3106         *cant_have_default_ctor_p = 1;

3107         TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1;

3108  

3109         if (! TYPE_HAS_CONSTRUCTOR (t) && CLASSTYPE_NON_AGGREGATE (t)

3110            && extra_warnings )

3111           cp_warning_at ("non-static const member `%#D' in class without a constructor", x);

3112       }

3113       /* A field that is pseudo-const makes the structure likewise.  */

3114       else if (CLASS_TYPE_P (type))

3115       {

3116         C_TYPE_FIELDS_READONLY (t) |= C_TYPE_FIELDS_READONLY (type);

3117         SET_CLASSTYPE_READONLY_FIELDS_NEED_INIT (t,

3118              CLASSTYPE_READONLY_FIELDS_NEED_INIT (t)

3119              | CLASSTYPE_READONLY_FIELDS_NEED_INIT (type));

3120       }

3121  

3122       /* Core issue 80: A nonstatic data member is required to have a

3123         different name from the class iff the class has a

3124         user-defined constructor.  */

3125       if (constructor_name_p (DECL_NAME (x), t) && TYPE_HAS_CONSTRUCTOR (t))

3126         cp_pedwarn_at ("field `%#D' with same name as class", x);

3127  

3128       /* We set DECL_C_BIT_FIELD in grokbitfield.

3129         If the type and width are valid, we'll also set DECL_BIT_FIELD.  */

3130       if (DECL_C_BIT_FIELD (x))

3131         check_bitfield_decl (x);

3132       else

3133         check_field_decl (x, t,

3134                        cant_have_const_ctor_p,

3135                        cant_have_default_ctor_p,

3136                        no_const_asn_ref_p,

3137                        &any_default_members);

3138     }

3139  

3140     /* Effective C++ rule 11.  */

3141     if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)

3142       && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t)))

3143     {

3144       warning ("`%#T' has pointer data members", t);

3145        

3146       if (! TYPE_HAS_INIT_REF (t))

3147       {

3148         warning ("  but does not override `%T(const %T&)'", t, t);

3149         if (! TYPE_HAS_ASSIGN_REF (t))

3150           warning ("  or `operator=(const %T&)'", t);

3151       }

3152       else if (! TYPE_HAS_ASSIGN_REF (t))

3153          warning ("  but does not override `operator=(const %T&)'", t);

3154     }

3155  

3156  

3157     /* Check anonymous struct/anonymous union fields.  */

3158     finish_struct_anon (t);

3159

3160     /* We've built up the list of access declarations in reverse order.

3161       Fix that now.  */

3162     *access_decls = nreverse (*access_decls);

3163   }

 

注意到在类的定义中, VAR_DECL 是为静态数据成员所构建的。在联合类型中,不允许出现静态成员及引用类型。进一步的, GCC 提供了一个特性:一个类可以被定义在一个函数体内,这称之为局部类( local class );而作为一个限制,其中不能使用静态成员。

3049 行, CLASSTYPE_NON_AGGREGATE 不为 0 表示这个类型的一个对象不能使用一个初始化列表来初始化。对于这样的域,如果它是一个引用( 3053 行),或者它是一个常量;这个域只能通过构造函数来初始化。如果违反了这个规则,编译器将给出警告。

进而如果类含有指针成员,如果它没有拷贝构造函数及赋值操作符,通过编译器产生的拷贝构造函数,这个域将得到错误的值。也需要为这个情形给出警告。

C C++ 允许整形或枚举的位域( bit-field )声明,相关信息参考 位域声明节点的处理 一节。对于这样的域,需要 check_bitfield_decl 来验证域的大小与其取值是否适合。

 

2732   static void

2733   check_bitfield_decl (tree field)                                                                  in class.c

2734   {

2735     tree type = TREE_TYPE (field);

2736     tree w = NULL_TREE;

2737  

2738     /* Detect invalid bit-field type.  */

2739     if (DECL_INITIAL (field)

2740         && ! INTEGRAL_TYPE_P (TREE_TYPE (field)))

2741     {

2742       cp_error_at ("bit-field `%#D' with non-integral type", field);

2743       w = error_mark_node;

2744     }

2745  

2746     /* Detect and ignore out of range field width.  */

2747     if (DECL_INITIAL (field))

2748     {

2749       w = DECL_INITIAL (field);

2750  

2751       /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs.  */

2752       STRIP_NOPS (w);

2753  

2754       /* detect invalid field size.  */

2755       if (TREE_CODE (w) == CONST_DECL)

2756         w = DECL_INITIAL (w);

2757       else

2758         w = decl_constant_value (w);

2759  

2760       if (TREE_CODE (w) != INTEGER_CST)

2761       {

2762         cp_error_at ("bit-field `%D' width not an integer constant",

2763                    field);

2764         w = error_mark_node;

2765       }

2766       else if (tree_int_cst_sgn (w) < 0)

2767       {

2768         cp_error_at ("negative width in bit-field `%D'", field);

2769         w = error_mark_node;

2770       }

2771       else if (integer_zerop (w) && DECL_NAME (field) != 0)

2772       {

2773         cp_error_at ("zero width for bit-field `%D'", field);

2774         w = error_mark_node;

2775       }

2776       else if (compare_tree_int (w, TYPE_PRECISION (type)) > 0

2777             && TREE_CODE (type) != ENUMERAL_TYPE

2778             && TREE_CODE (type) != BOOLEAN_TYPE)

2779         cp_warning_at ("width of `%D' exceeds its type", field);

2780       else if (TREE_CODE (type) == ENUMERAL_TYPE

2781             && (0 > compare_tree_int (w,

2782                        min_precision (TYPE_MIN_VALUE (type),

2783                        TREE_UNSIGNED (type)))

2784                  ||  0 > compare_tree_int (w,

2785                        min_precision

2786                            (TYPE_MAX_VALUE (type),

2787                        TREE_UNSIGNED (type)))))

2788         cp_warning_at ("`%D' is too small to hold all values of `%#T'",

2789                      field, type);

2790     }

2791    

2792     /* Remove the bit-field width indicator so that the rest of the

2793       compiler does not treat that value as an initializer.  */

2794     DECL_INITIAL (field) = NULL_TREE;

2795  

2796     if (w != error_mark_node)

2797     {

2798       DECL_SIZE (field) = convert (bitsizetype, w);

2799       DECL_BIT_FIELD (field) = 1;

2800     }

2801     else

2802     {

2803       /* Non-bit-fields are aligned for their type.  */

2804       DECL_BIT_FIELD (field) = 0;

2805       CLEAR_DECL_C_BIT_FIELD (field);

2806     }

2807   }

 

而对于普通的域,需要进入类类型的域。看到类型的某些特征由其包含的域确定。需要一个一个域地来收集这些信息。

 

2813   static void

2814   check_field_decl (tree field,                                                                      in class.c

2815                  tree t,

2816                  int* cant_have_const_ctor,

2817                  int* cant_have_default_ctor,

2818                  int* no_const_asn_ref,

2819                  int* any_default_members)

2820   {

2821     tree type = strip_array_types (TREE_TYPE (field));

2822  

2823     /* An anonymous union cannot contain any fields which would change

2824       the settings of CANT_HAVE_CONST_CTOR and friends.  */

2825     if (ANON_UNION_TYPE_P (type))

2826       ;

2827     /* And, we don't set TYPE_HAS_CONST_INIT_REF, etc., for anonymous

2828       structs. So, we recurse through their fields here.  */

2829     else if (ANON_AGGR_TYPE_P (type))

2830     {

2831       tree fields;

2832  

2833       for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields))

2834         if (TREE_CODE (fields) == FIELD_DECL && !DECL_C_BIT_FIELD (field))

2835           check_field_decl (fields, t, cant_have_const_ctor,

2836                          cant_have_default_ctor, no_const_asn_ref,

2837                           any_default_members);

2838     }

2839     /* Check members with class type for constructors, destructors,

2840       etc.  */

2841     else if (CLASS_TYPE_P (type))

2842     {

2843       /* Never let anything with uninheritable virtuals

2844         make it through without complaint.  */

2845       abstract_virtuals_error (field, type);

2846                    

2847       if (TREE_CODE (t) == UNION_TYPE)

2848       {

2849         if (TYPE_NEEDS_CONSTRUCTING (type))

2850            cp_error_at ("member `%#D' with constructor not allowed in union",

2851                      field);

2852         if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))

2853           cp_error_at ("member `%#D' with destructor not allowed in union",

2854                       field);

2855         if (TYPE_HAS_COMPLEX_ASSIGN_REF (type))

2856           cp_error_at ("member `%#D' with copy assignment operator not allowed in union",

2857                      field);

2858       }

2859       else

2860       {

2861         TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type);

2862         TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)

2863            |= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type);

2864         TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type);

2865         TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type);

2866       }

2867  

2868       if (!TYPE_HAS_CONST_INIT_REF (type))

2869         *cant_have_const_ctor = 1;

2870  

2871       if (!TYPE_HAS_CONST_ASSIGN_REF (type))

2872         *no_const_asn_ref = 1;

2873  

2874       if (TYPE_HAS_CONSTRUCTOR (type)

2875           && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))

2876         *cant_have_default_ctor = 1;

2877     }

2878     if (DECL_INITIAL (field) != NULL_TREE)

2879     {

2880       /* `build_class_init_list' does not recognize

2881          non-FIELD_DECLs.  */

2882       if (TREE_CODE (t) == UNION_TYPE && any_default_members != 0)

2883         error ("multiple fields in union `%T' initialized", t);

2884       *any_default_members = 1;

2885     }

2886   }

 

对于匿名的 union/struct 域, check_field_decl 中的检查是不够的——该函数仅验证通常的域是否有效,但是对于匿名的 union/struct 某些域是不允许的。在 2845 行, abstract_virtuals_error 检查类是否含有纯虚函数(注意到虚基类被跳过了,下面可以看到为什么这样),其中下面的 CLASSTYPE_PURE_VIRTUALS 保存了未被重载的纯虚函数构成的链表。

 

125    int

126    abstract_virtuals_error (tree decl, tree type)                                               typeck2.c

127    {

128      tree u;

129      tree tu;

130   

131      if (!CLASS_TYPE_P (type) || !CLASSTYPE_PURE_VIRTUALS (type))

132        return 0;

133   

134      if (!TYPE_SIZE (type))

135        /* TYPE is being defined, and during that time

136          CLASSTYPE_PURE_VIRTUALS holds the inline friends.  */

137        return 0;

138   

139      if (dependent_type_p (type))

140        /* For a dependent type, we do not yet know which functions are pure

141          virtuals.  */

142        return 0;

143   

144      u = CLASSTYPE_PURE_VIRTUALS (type);

145      if (decl)

146      {

147        if (TREE_CODE (decl) == RESULT_DECL)

148          return 0;

149   

150        if (TREE_CODE (decl) == VAR_DECL)

151          error ("cannot declare variable `%D' to be of type `%T'",

152                decl, type);

153        else if (TREE_CODE (decl) == PARM_DECL)

154          error ("cannot declare parameter `%D' to be of type `%T'",

155                decl, type);

156        else if (TREE_CODE (decl) == FIELD_DECL)

157          error ("cannot declare field `%D' to be of type `%T'",

158                 decl, type);

159        else if (TREE_CODE (decl) == FUNCTION_DECL

160              && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)

161          error ("invalid return type for member function `%#D'", decl);

162        else if (TREE_CODE (decl) == FUNCTION_DECL)

163          error ("invalid return type for function `%#D'", decl);

164      }

165      else

166        error ("cannot allocate an object of type `%T'", type);

167   

168      /* Only go through this once.  */

169      if (TREE_PURPOSE (u) == NULL_TREE)

170      {

171        TREE_PURPOSE (u) = error_mark_node;

172   

173        error ("  because the following virtual functions are abstract:");

174        for (tu = u; tu; tu = TREE_CHAIN (tu))

175          cp_error_at ("/t%#D", TREE_VALUE (tu));

176      }

177      else

178        error ("  since type `%T' has abstract virtual functions", type);

179   

180      return 1;

181    }

 

进一步的检查在 check_field_decls 3158 行的 finish_struct_anon 中进行。

 

2522   static void

2523   finish_struct_anon (tree t)                                                                         in class.c

2524   {

2525     tree field;

2526  

2527     for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))

2528     {

2529       if (TREE_STATIC (field))

2530         continue ;

2531       if (TREE_CODE (field) != FIELD_DECL)

2532         continue ;

2533  

2534       if (DECL_NAME (field) == NULL_TREE

2535          && ANON_AGGR_TYPE_P (TREE_TYPE (field)))

2536       {

2537         tree elt = TYPE_FIELDS (TREE_TYPE (field));

2538         for (; elt; elt = TREE_CHAIN (elt))

2539         {

2540           /* We're generally only interested in entities the user

2541             declared, but we also find nested classes by noticing

2542             the TYPE_DECL that we create implicitly. You're

2543             allowed to put one anonymous union inside another,

2544             though, so we explicitly tolerate that. We use

2545             TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that

2546             we also allow unnamed types used for defining fields.  */

2547           if (DECL_ARTIFICIAL (elt)

2548              && (!DECL_IMPLICIT_TYPEDEF_P (elt)

2549                   || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))

2550             continue ;

2551  

2552           if (TREE_CODE (elt) != FIELD_DECL)

2553           {

2554             cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members",

2555                           elt);

2556             continue ;

2557           }

2558  

2559              if (TREE_PRIVATE (elt))

2560               cp_pedwarn_at ("private member `%#D' in anonymous union",

2561                             elt);

2562            else if (TREE_PROTECTED (elt))

2563              cp_pedwarn_at ("protected member `%#D' in anonymous union",

2564                            elt);

2565  

2566           TREE_PRIVATE (elt) = TREE_PRIVATE (field);

2567           TREE_PROTECTED (elt) = TREE_PROTECTED (field);

2568         }

2569       }

2570     }

2571   }

 

在代码中, DECL_ARTIFICIAL 为非 0 值,如果该实体是由编译器产生的而不是由用户声明的。而 DECL_IMPLICIT_TYPEDEF_P 被设置,例如在 RECORD_TYPE 对应的 TYPE_DECL 中,来表示这是该类型的隐含声明的 typedef (记得该 TYPE_DECL 有标签 DECL_ARTIFICIAL )。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值