History

completed initializer handlign (compute size before storing initializers if unknown size - macro subst fix

bellard committed 24 years ago

Commit 0c6b2dc1 parent 34a14a01 file · +144 −56Browse files

Unified · Split

tcc.c+144−56
@@ -264,7 +264,7 @@ int expr_const(); · 263 unmodified lines
264void expr_eq();264void expr_eq();
265void expr();265void expr();
266void decl();266void decl();
267void decl_assign(int t, int c, int first);267void decl_initializer(int t, int c, int first, int size_only);
268int gv();268int gv();
269void move_reg();269void move_reg();
270void save_reg();270void save_reg();
@@ -1168,7 +1168,7 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args) · 897 unmodified lines
1168 tok_add(&str, &len, t);1168 tok_add(&str, &len, t);
1169 }1169 }
1170 } else if (t == TOK_NUM || t == TOK_CCHAR || t == TOK_STR) {1170 } else if (t == TOK_NUM || t == TOK_CCHAR || t == TOK_STR) {
1171 tok_add2(&str, &len, t, *macro_ptr++);1171 tok_add2(&str, &len, t, *macro_str++);
1172 } else {1172 } else {
1173 s = sym_find2(args, t);1173 s = sym_find2(args, t);
1174 if (s) {1174 if (s) {
@@ -2906,8 +2906,10 @@ void block(int *bsym, int *csym, int *case_sym, int *def_sym, int case_reg) · 1731 unmodified lines
2906}2906}
2907 2907
2908/* t is the array or struct type. c is the array or struct2908/* t is the array or struct type. c is the array or struct
2909 address. cur_index/cur_field is the pointer to the current value */2909 address. cur_index/cur_field is the pointer to the current
2910void decl_designator(int t, int c, int *cur_index, Sym **cur_field)2910 value. 'size_only' is true if only size info is needed (only used
2911 in arrays) */
2912void decl_designator(int t, int c, int *cur_index, Sym **cur_field, int size_only)
2911{2913{
2912 Sym *s, *f;2914 Sym *s, *f;
2913 int notfirst, index, align;2915 int notfirst, index, align;
@@ -2964,39 +2966,79 @@ void decl_designator(int t, int c, int *cur_index, Sym **cur_field) · 50 unmodified lines
2964 c += f->c;2966 c += f->c;
2965 }2967 }
2966 }2968 }
2967 decl_assign(t, c, 0);2969 decl_initializer(t, c, 0, size_only);
2970}
2971
2972/* store a value or an expression directly in global data or in local array */
2973
2974void init_putv(int t, int c, int v, int is_expr)
2975{
2976 if ((t & VT_VALMASK) == VT_CONST) {
2977 if (is_expr)
2978 v = expr_const();
2979 if (t & VT_BYTE)
2980 *(char *)c = v;
2981 else if (t & VT_SHORT)
2982 *(short *)c = v;
2983 else
2984 *(int *)c = v;
2985 } else {
2986 vt = t;
2987 vc = c;
2988 vpush();
2989 if (is_expr)
2990 expr_eq();
2991 else
2992 vset(VT_CONST, v);
2993 vstore();
2994 }
2968}2995}
2969 2996
2970/* 't' contains the type and storage info. c is the address of the2997/* 't' contains the type and storage info. c is the address of the
2971 object. 'first' is true if array '{' must be read (multi dimension2998 object. 'first' is true if array '{' must be read (multi dimension
2972 implicit array init handling). */2999 implicit array init handling). 'size_only' is true if size only
2973void decl_assign(int t, int c, int first)3000 evaluation is wanted (only for arrays). */
3001void decl_initializer(int t, int c, int first, int size_only)
2974{3002{
2975 int v, index, index_max, t1, n, no_oblock;3003 int index, array_length, t1, n, no_oblock, nb, parlevel, i;
2976 Sym *s, *f;3004 Sym *s, *f;
2977 TokenSym *ts;3005 TokenSym *ts;
2978 3006
2979 if (t & VT_ARRAY) {3007 if (t & VT_ARRAY) {
2980 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));3008 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT));
2981 n = s->c;3009 n = s->c;
2982 index_max = 0;3010 array_length = 0;
2983 if (tok == TOK_STR) {3011 if (tok == TOK_STR) {
2984 t1 = pointed_type(t);3012 t1 = pointed_type(t);
2985 if (!(t1 & VT_BYTE))3013 if (!(t1 & VT_BYTE))
2986 error("invalid type");3014 error("invalid type");
2987 if ((t & VT_VALMASK) == VT_CONST) {3015 /* XXX: move multiple string parsing in parser ? */
2988 while (tok == TOK_STR) {3016 while (tok == TOK_STR) {
2989 ts = (TokenSym *)tokc;3017 ts = (TokenSym *)tokc;
2990 memcpy((void *)c, ts->str, ts->len);3018 /* compute maximum number of chars wanted */
2991 c += ts->len;3019 nb = ts->len;
2992 index_max += ts->len;3020 if (n >= 0 && nb > (n - array_length))
2993 next();3021 nb = n - array_length;
3022 if (!size_only) {
3023 if (ts->len > nb)
3024 warning("initializer-string for array is too long");
3025 for(i=0;i<nb;i++) {
3026 init_putv(t1, c, ts->str[i], 0);
3027 c++;
3028 }
2994 }3029 }
2995 *(char *)c++ = 0;3030 array_length += nb;
2996 } else {3031 next();
2997 error("local string init not handled");3032 }
3033 /* only add trailing zero if enough storage (no
3034 warning in this case since it is standard) */
3035 if (n < 0 || array_length < n) {
3036 if (!size_only) {
3037 init_putv(t1, c, 0, 0);
3038 c++;
3039 }
3040 array_length++;
2998 }3041 }
2999 /* string init */
3000 } else {3042 } else {
3001 no_oblock = 0;3043 no_oblock = 0;
3002 if (!first && tok != '{')3044 if (!first && tok != '{')
@@ -3005,12 +3047,12 @@ void decl_assign(int t, int c, int first) · 2 unmodified lines
3005 skip('{');3047 skip('{');
3006 index = 0;3048 index = 0;
3007 while (tok != '}') {3049 while (tok != '}') {
3008 decl_designator(t, c, &index, NULL);3050 decl_designator(t, c, &index, NULL, size_only);
3009 if (n >= 0 && index >= n)3051 if (n >= 0 && index >= n)
3010 error("index too large");3052 error("index too large");
3011 if (index > index_max)
3012 index_max = index;
3013 index++;3053 index++;
3054 if (index > array_length)
3055 array_length = index;
3014 /* special test for multi dimensional arrays (may not3056 /* special test for multi dimensional arrays (may not
3015 be strictly correct if designators are used at the3057 be strictly correct if designators are used at the
3016 same time) */3058 same time) */
@@ -3025,45 +3067,43 @@ void decl_assign(int t, int c, int first) · 8 unmodified lines
3025 }3067 }
3026 /* patch type size if needed */3068 /* patch type size if needed */
3027 if (n < 0)3069 if (n < 0)
3028 s->c = index_max + 1;3070 s->c = array_length;
3029 } else if (t & VT_STRUCT) {3071 } else if (t & VT_STRUCT) {
3030 /* XXX: union needs only one init */3072 /* XXX: union needs only one init */
3031 skip('{');3073 skip('{');
3032 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);3074 s = sym_find(((unsigned)t >> VT_STRUCT_SHIFT) | SYM_STRUCT);
3033 f = s->next;3075 f = s->next;
3034 while (tok != '}') {3076 while (tok != '}') {
3035 decl_designator(t, c, NULL, &f);3077 decl_designator(t, c, NULL, &f, size_only);
3036 if (tok == '}')3078 if (tok == '}')
3037 break;3079 break;
3038 skip(',');3080 skip(',');
3039 f = f->next;3081 f = f->next;
3040 }3082 }
3041 skip('}');3083 skip('}');
3084 } else if (size_only) {
3085 /* just skip expression */
3086 parlevel = 0;
3087 while ((parlevel > 0 || (tok != '}' && tok != ',')) &&
3088 tok != -1) {
3089 if (tok == '(')
3090 parlevel++;
3091 else if (tok == ')')
3092 parlevel--;
3093 next();
3094 }
3042 } else {3095 } else {
3043 if ((t & VT_VALMASK) == VT_CONST) {3096 init_putv(t, c, 0, 1);
3044 v = expr_const();
3045 if (t & VT_BYTE)
3046 *(char *)c = v;
3047 else if (t & VT_SHORT)
3048 *(short *)c = v;
3049 else
3050 *(int *)c = v;
3051 } else {
3052 vt = t;
3053 vc = c;
3054 vpush();
3055 expr_eq();
3056 vstore();
3057 }
3058 }3097 }
3059}3098}
3060 3099
3061/* 'l' is VT_LOCAL or VT_CONST to define default storage type */3100/* 'l' is VT_LOCAL or VT_CONST to define default storage type */
3062void decl(l)3101void decl(l)
3063{3102{
3064 int *a, t, b, size, align, v, u, n, addr;3103 int *a, t, b, size, align, v, u, n, addr, tok1;
3065 Sym *sym;3104 Sym *sym;
3066 3105 int *init_str, init_len, level, *saved_macro_ptr;
3106
3067 while (b = ist()) {3107 while (b = ist()) {
3068 if ((b & (VT_ENUM | VT_STRUCT)) && tok == ';') {3108 if ((b & (VT_ENUM | VT_STRUCT)) && tok == ';') {
3069 /* we accept no variable after */3109 /* we accept no variable after */
@@ -3130,16 +3170,67 @@ void decl(l) · 60 unmodified lines
3130 u = VT_CONST;3170 u = VT_CONST;
3131 u |= t;3171 u |= t;
3132 size = type_size(t, &align);3172 size = type_size(t, &align);
3173 /* If unknown size, we must evaluate it before
3174 evaluating initializers because
3175 initializers can generate global data too
3176 (e.g. string pointers or ISOC99 compound
3177 literals). It also simplifies local
3178 initializers handling */
3179 init_len = 0;
3180 init_str = NULL;
3181 saved_macro_ptr = NULL; /* avoid warning */
3182 tok1 = 0;
3183 if (size < 0) {
3184 if (tok != '=')
3185 error("unknown size for '%s'", get_tok_str(v, 0));
3186 tok_add2(&init_str, &init_len, tok, tokc);
3187 next();
3188 /* get all init string */
3189 level = 0;
3190 while (level > 0 || (tok != ',' && tok != ';')) {
3191 if (tok < 0)
3192 error("unexpect end of file in initializer for '%s'",
3193 get_tok_str(v, 0));
3194 tok_add2(&init_str, &init_len, tok, tokc);
3195 if (tok == '{')
3196 level++;
3197 else if (tok == '}') {
3198 if (level == 0)
3199 break;
3200 level--;
3201 }
3202 next();
3203 }
3204 tok1 = tok;
3205 tok_add(&init_str, &init_len, -1);
3206 tok_add(&init_str, &init_len, 0);
3207
3208 /* compute size */
3209 saved_macro_ptr = macro_ptr;
3210 macro_ptr = init_str;
3211 next();
3212 skip('=');
3213 decl_initializer(u, 0, 1, 1);
3214 /* prepare second initializer parsing */
3215 macro_ptr = init_str;
3216 next();
3217
3218 /* if still unknown size, error */
3219 size = type_size(t, &align);
3220 if (size < 0)
3221 error("unknown size for '%s'", get_tok_str(v, 0));
3222 }
3133 if ((u & VT_VALMASK) == VT_LOCAL) {3223 if ((u & VT_VALMASK) == VT_LOCAL) {
3134 /* XXX: cannot use implicit size for local
3135 storage */
3136 if (size < 0)
3137 error("size must be known for locals");
3138 loc = (loc - size) & -align;3224 loc = (loc - size) & -align;
3139 addr = loc;3225 addr = loc;
3140 } else {3226 } else {
3141 glo = (glo + align - 1) & -align;3227 glo = (glo + align - 1) & -align;
3142 addr = glo;3228 addr = glo;
3229 /* very important to increment global
3230 pointer at this time because
3231 initializers themselves can create new
3232 initializers */
3233 glo += size;
3143 }3234 }
3144 if (tok == '=') {3235 if (tok == '=') {
3145 next();3236 next();
@@ -3149,20 +3240,17 @@ void decl(l) · 3 unmodified lines
3149 n = 1;3240 n = 1;
3150 next();3241 next();
3151 }3242 }
3152 decl_assign(u, addr, 1);3243 decl_initializer(u, addr, 1, 0);
3153 if (n)3244 if (n)
3154 skip('}');3245 skip('}');
3246 /* restore parse state if needed */
3247 if (init_str) {
3248 free(init_str);
3249 macro_ptr = saved_macro_ptr;
3250 tok = tok1;
3251 }
3155 }3252 }
3156 sym_push(v, u, addr);3253 sym_push(v, u, addr);
3157 /* if global, add size */
3158 if ((u & VT_VALMASK) == VT_CONST) {
3159 /* must recompute size if it was an array
3160 with implicit size */
3161 size = type_size(t, &align);
3162 if (size < 0)
3163 error("invalid size");
3164 glo += size;
3165 }
3166 }3254 }
3167 }3255 }
3168 if (tok != ',') {3256 if (tok != ',') {