Also add some test cases in tests/tests2/39_typedef.c.
Unified · Split
| @@ -3134,6 +3134,17 @@ ST_FUNC int is_btype_size(int bt) · 3133 unmodified lines | |||
| 3134 | return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG; | 3134 | return bt == VT_SHORT || bt == VT_LONG || bt == VT_LLONG; |
| 3135 | } | 3135 | } |
| 3136 | 3136 | ||
| 3137 | /* Add type qualifiers to a type. If the type is an array then the qualifiers | ||
| 3138 | are added to the element type, copied because it could be a typedef. */ | ||
| 3139 | static void parse_btype_qualify(CType *type, int qualifiers) | ||
| 3140 | { | ||
| 3141 | while (type->t & VT_ARRAY) { | ||
| 3142 | type->ref = sym_push(SYM_FIELD, &type->ref->type, 0, type->ref->c); | ||
| 3143 | type = &type->ref->type; | ||
| 3144 | } | ||
| 3145 | type->t |= qualifiers; | ||
| 3146 | } | ||
| 3147 | |||
| 3137 | /* return 0 if no type declaration. otherwise, return the basic type | 3148 | /* return 0 if no type declaration. otherwise, return the basic type |
| 3138 | and skip it. | 3149 | and skip it. |
| 3139 | */ | 3150 | */ |
| @@ -3232,13 +3243,17 @@ static int parse_btype(CType *type, AttributeDef *ad) · 92 unmodified lines | |||
| 3232 | case TOK_CONST1: | 3243 | case TOK_CONST1: |
| 3233 | case TOK_CONST2: | 3244 | case TOK_CONST2: |
| 3234 | case TOK_CONST3: | 3245 | case TOK_CONST3: |
| 3235 | t |= VT_CONSTANT; | 3246 | type->t = t; |
| 3247 | parse_btype_qualify(type, VT_CONSTANT); | ||
| 3248 | t = type->t; | ||
| 3236 | next(); | 3249 | next(); |
| 3237 | break; | 3250 | break; |
| 3238 | case TOK_VOLATILE1: | 3251 | case TOK_VOLATILE1: |
| 3239 | case TOK_VOLATILE2: | 3252 | case TOK_VOLATILE2: |
| 3240 | case TOK_VOLATILE3: | 3253 | case TOK_VOLATILE3: |
| 3241 | t |= VT_VOLATILE; | 3254 | type->t = t; |
| 3255 | parse_btype_qualify(type, VT_VOLATILE); | ||
| 3256 | t = type->t; | ||
| 3242 | next(); | 3257 | next(); |
| 3243 | break; | 3258 | break; |
| 3244 | case TOK_SIGNED1: | 3259 | case TOK_SIGNED1: |
| @@ -3309,18 +3324,14 @@ static int parse_btype(CType *type, AttributeDef *ad) · 64 unmodified lines | |||
| 3309 | s = sym_find(tok); | 3324 | s = sym_find(tok); |
| 3310 | if (!s || !(s->type.t & VT_TYPEDEF)) | 3325 | if (!s || !(s->type.t & VT_TYPEDEF)) |
| 3311 | goto the_end; | 3326 | goto the_end; |
| 3312 | t |= (s->type.t & ~VT_TYPEDEF); | 3327 | |
| 3313 | if ((t & VT_ARRAY) && | 3328 | type->t = ((s->type.t & ~VT_TYPEDEF) | |
| 3314 | t & (VT_CONSTANT | VT_VOLATILE) & ~s->type.ref->type.t) { | 3329 | (t & ~(VT_CONSTANT | VT_VOLATILE))); |
| 3315 | /* This is a case like "typedef int T[1]; const T x;" | 3330 | type->ref = s->type.ref; |
| 3316 | in which which we must make a copy of the typedef | 3331 | if (t & (VT_CONSTANT | VT_VOLATILE)) |
| 3317 | type so that we can add the type qualifiers to it. */ | 3332 | parse_btype_qualify(type, t & (VT_CONSTANT | VT_VOLATILE)); |
| 3318 | type->ref = sym_push(SYM_FIELD, &s->type.ref->type, | 3333 | t = type->t; |
| 3319 | 0, s->type.ref->c); | 3334 | |
| 3320 | type->ref->type.t |= t & (VT_CONSTANT | VT_VOLATILE); | ||
| 3321 | } | ||
| 3322 | else | ||
| 3323 | type->ref = s->type.ref; | ||
| 3324 | if (s->r) { | 3335 | if (s->r) { |
| 3325 | /* get attributes from typedef */ | 3336 | /* get attributes from typedef */ |
| 3326 | if (0 == ad->a.aligned) | 3337 | if (0 == ad->a.aligned) |
| @@ -28,4 +28,20 @@ int main() · 27 unmodified lines | |||
| 28 | return 0; | 28 | return 0; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | /* "If the specification of an array type includes any type qualifiers, | ||
| 32 | the element type is so-qualified, not the array type." */ | ||
| 33 | |||
| 34 | typedef int A[3]; | ||
| 35 | extern A const ca; | ||
| 36 | extern const A ca; | ||
| 37 | extern const int ca[3]; | ||
| 38 | |||
| 39 | typedef A B[1][2]; | ||
| 40 | extern B const cb; | ||
| 41 | extern const B cb; | ||
| 42 | extern const int cb[1][2][3]; | ||
| 43 | |||
| 44 | extern B b; | ||
| 45 | extern int b[1][2][3]; | ||
| 46 | |||
| 31 | /* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ | 47 | /* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ |