History

'long' review

add some features for more complete 'long' support tcc.h: - use LONG_SIZE=4/8 instead of TCC_LONG_ARE_64_BIT tccgen.c: - add ptrdiff_type, update size_type - support shift and ?: operations - support long enum types - display 'long' from type_to_str - nwchar_t is unsigned short on windows - unrelated: use memcpy in init_putv for long doubles to avoid random bytes in the image (if tcc was compiled by gcc) for diff purposes. tccpp.c: - make parse_number return correct types - improve multi-character-constants 'XX' 'abcd' Changelog: - update

grischka committed 9 years ago

Commit 14430391 parent 870271e6 files · +164 −176Browse files

Unified · Split

6 files
  1. Changelog +4 −2
  2. libtcc.c +7 −7
  3. tcc.h +11 −12
  4. tccgen.c +83 −90
  5. tccpp.c +58 −64
  6. win32/build-tcc.bat +1 −1
Changelog+4−2
@@ -9,11 +9,10 @@ User interface: · 8 unmodified lines
9- -mno-sse on x86-64 disables use of SSE instructions9- -mno-sse on x86-64 disables use of SSE instructions
10- @listfile support (Vlad Vissoultchev)10- @listfile support (Vlad Vissoultchev)
11- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)11- tcc -ar/-impdef - formerly tiny_xxx tools integrated (grischka)
12- CPATH, C_INCLUDE_PATH and LD_LIBRARY_PATH environment variables support12- CPATH, C_INCLUDE_PATH and LIBRARY_PATH environment variables support
13 (Andrew Aladjev, Urs Janssen)13 (Andrew Aladjev, Urs Janssen)
14 14
15Platforms:15Platforms:
16- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
17- new AARCH64 (arm64) target (Edmund Grimley Evans)16- new AARCH64 (arm64) target (Edmund Grimley Evans)
18- vastly improved support for ARM hard float calling convention17- vastly improved support for ARM hard float calling convention
19 (Thomas Preud'homme, Daniel Glöckner)18 (Thomas Preud'homme, Daniel Glöckner)
@@ -22,6 +21,7 @@ Platforms: · 2 unmodified lines
22- ABI tests with native compiler using libtcc (James Lyon)21- ABI tests with native compiler using libtcc (James Lyon)
23- UNICODE startup code supports wmain and wWinMain (YX Hao)22- UNICODE startup code supports wmain and wWinMain (YX Hao)
24- shared libraries for x86_64 (Michael Matz)23- shared libraries for x86_64 (Michael Matz)
24- Bootstrap native Windows 32/64 compiler using Cygwin+gcc (Christian Jullien)
25 25
26Features:26Features:
27- VLA (variable length array) improved (James Lyon, Pip Cet)27- VLA (variable length array) improved (James Lyon, Pip Cet)
@@ -35,6 +35,8 @@ Features: · 7 unmodified lines
35- standard conforming (and GCC compatible) struct initialization35- standard conforming (and GCC compatible) struct initialization
36 (Michael Matz)36 (Michael Matz)
37- bit-field layout made compatible with GCC (Michael Matz)37- bit-field layout made compatible with GCC (Michael Matz)
38- UTF8 in string literals supported (Zdenek Pavlas)
39_ _Generic(...) supported (Matthias Gatto)
38 40
39Licensing:41Licensing:
40- TinyCC partly relicensed to MIT license (See RELICENSING file).42- TinyCC partly relicensed to MIT license (See RELICENSING file).
libtcc.c+7−7
@@ -836,21 +836,21 @@ LIBTCCAPI TCCState *tcc_new(void) · 835 unmodified lines
836# endif836# endif
837 837
838 /* TinyCC & gcc defines */838 /* TinyCC & gcc defines */
839#if defined(TCC_TARGET_PE) && PTR_SIZE == 8839#if PTR_SIZE == 4
840 /* 32bit systems. */
841 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
842 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
843 tcc_define_symbol(s, "__ILP32__", NULL);
844#elif LONG_SIZE == 4
840 /* 64bit Windows. */845 /* 64bit Windows. */
841 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");846 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long long");
842 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");847 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");
843 tcc_define_symbol(s, "__LLP64__", NULL);848 tcc_define_symbol(s, "__LLP64__", NULL);
844#elif PTR_SIZE == 8849#else
845 /* Other 64bit systems. */850 /* Other 64bit systems. */
846 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");851 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned long");
847 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");852 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long");
848 tcc_define_symbol(s, "__LP64__", NULL);853 tcc_define_symbol(s, "__LP64__", NULL);
849#else
850 /* Other 32bit systems. */
851 tcc_define_symbol(s, "__SIZE_TYPE__", "unsigned int");
852 tcc_define_symbol(s, "__PTRDIFF_TYPE__", "int");
853 tcc_define_symbol(s, "__ILP32__", NULL);
854#endif854#endif
855 855
856#if defined(TCC_MUSL)856#if defined(TCC_MUSL)
tcc.h+11−12
@@ -361,6 +361,12 @@ extern long double strtold (const char *__nptr, char **__endptr); · 360 unmodified lines
361/* target address type */361/* target address type */
362#define addr_t ElfW(Addr)362#define addr_t ElfW(Addr)
363 363
364#if PTR_SIZE == 8 && !defined TCC_TARGET_PE
365# define LONG_SIZE 8
366#else
367# define LONG_SIZE 4
368#endif
369
364/* -------------------------------------------- */370/* -------------------------------------------- */
365 371
366#define INCLUDE_STACK_SIZE 32372#define INCLUDE_STACK_SIZE 32
@@ -880,14 +886,14 @@ struct filespec { · 513 unmodified lines
880#define VT_CONSTANT 0x0100 /* const modifier */886#define VT_CONSTANT 0x0100 /* const modifier */
881#define VT_VOLATILE 0x0200 /* volatile modifier */887#define VT_VOLATILE 0x0200 /* volatile modifier */
882#define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */888#define VT_VLA 0x0400 /* VLA type (also has VT_PTR and VT_ARRAY) */
883#define VT_LONG 0x0800889#define VT_LONG 0x0800 /* long type (also has VT_INT rsp. VT_LLONG) */
884 890
885/* storage */891/* storage */
886#define VT_EXTERN 0x00001000 /* extern definition */892#define VT_EXTERN 0x00001000 /* extern definition */
887#define VT_STATIC 0x00002000 /* static variable */893#define VT_STATIC 0x00002000 /* static variable */
888#define VT_TYPEDEF 0x00004000 /* typedef definition */894#define VT_TYPEDEF 0x00004000 /* typedef definition */
889#define VT_INLINE 0x00008000 /* inline definition */895#define VT_INLINE 0x00008000 /* inline definition */
890/* currently unused: 0x0800, 0x000[1248]0000 */896/* currently unused: 0x000[1248]0000 */
891 897
892#define VT_STRUCT_SHIFT 20 /* shift for bitfield shift values (32 - 2*6) */898#define VT_STRUCT_SHIFT 20 /* shift for bitfield shift values (32 - 2*6) */
893#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)899#define VT_STRUCT_MASK (((1 << (6+6)) - 1) << VT_STRUCT_SHIFT | VT_BITFIELD)
@@ -906,7 +912,6 @@ struct filespec { · 12 unmodified lines
906#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)912#define VT_STORAGE (VT_EXTERN | VT_STATIC | VT_TYPEDEF | VT_INLINE)
907#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))913#define VT_TYPE (~(VT_STORAGE|VT_STRUCT_MASK))
908 914
909
910/* token values */915/* token values */
911 916
912/* warning: the following compare tokens depend on i386 asm code */917/* warning: the following compare tokens depend on i386 asm code */
@@ -947,6 +952,7 @@ struct filespec { · 34 unmodified lines
947#define TOK_PPNUM 0xbe /* preprocessor number */952#define TOK_PPNUM 0xbe /* preprocessor number */
948#define TOK_PPSTR 0xbf /* preprocessor string */953#define TOK_PPSTR 0xbf /* preprocessor string */
949#define TOK_LINENUM 0xc0 /* line number info */954#define TOK_LINENUM 0xc0 /* line number info */
955#define TOK_TWODOTS 0xa8 /* C++ token ? */
950/* <-- */956/* <-- */
951 957
952#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */958#define TOK_UMULL 0xc2 /* unsigned 32x32 -> 64 mul */
@@ -961,15 +967,8 @@ struct filespec { · 8 unmodified lines
961#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */967#define TOK_PLCHLDR 0xcb /* placeholder token as defined in C99 */
962#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */968#define TOK_NOSUBST 0xcc /* means following token has already been pp'd */
963#define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */969#define TOK_PPJOIN 0xcd /* A '##' in the right position to mean pasting */
964 970#define TOK_CLONG 0xce /* long constant */
965#define TOK_CLONG 0xce /* long constant */971#define TOK_CULONG 0xcf /* unsigned long constant */
966#define TOK_CULONG 0xcf /* unsigned long constant */
967
968
969#if defined TCC_TARGET_X86_64 && !defined TCC_TARGET_PE
970 #define TCC_LONG_ARE_64_BIT
971#endif
972
973 972
974#define TOK_SHL 0x01 /* shift left */973#define TOK_SHL 0x01 /* shift left */
975#define TOK_SAR 0x02 /* signed shift right */974#define TOK_SAR 0x02 /* signed shift right */
tccgen.c+83−90
@@ -61,7 +61,7 @@ ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc · 60 unmodified lines
61ST_DATA const char *funcname;61ST_DATA const char *funcname;
62ST_DATA int g_debug;62ST_DATA int g_debug;
63 63
64ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;64ST_DATA CType char_pointer_type, func_old_type, int_type, size_type, ptrdiff_type;
65 65
66ST_DATA struct switch_t {66ST_DATA struct switch_t {
67 struct case_t {67 struct case_t {
@@ -240,9 +240,14 @@ ST_FUNC int tccgen_compile(TCCState *s1) · 172 unmodified lines
240 char_pointer_type.t = VT_BYTE;240 char_pointer_type.t = VT_BYTE;
241 mk_pointer(&char_pointer_type);241 mk_pointer(&char_pointer_type);
242#if PTR_SIZE == 4242#if PTR_SIZE == 4
243 size_type.t = VT_INT;243 size_type.t = VT_INT | VT_UNSIGNED;
244 ptrdiff_type.t = VT_INT;
245#elif LONG_SIZE == 4
246 size_type.t = VT_LLONG | VT_UNSIGNED;
247 ptrdiff_type.t = VT_LLONG;
244#else248#else
245 size_type.t = VT_LLONG;249 size_type.t = VT_LONG | VT_LLONG | VT_UNSIGNED;
250 ptrdiff_type.t = VT_LONG | VT_LLONG;
246#endif251#endif
247 func_old_type.t = VT_FUNC;252 func_old_type.t = VT_FUNC;
248 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);253 func_old_type.ref = sym_push(SYM_FIELD, &int_type, 0, 0);
@@ -2127,12 +2132,7 @@ redo: · 1878 unmodified lines
2127 }2132 }
2128 vrott(3);2133 vrott(3);
2129 gen_opic(op);2134 gen_opic(op);
2130 /* set to integer type */2135 vtop->type.t = ptrdiff_type.t;
2131#if PTR_SIZE == 8
2132 vtop->type.t = VT_LLONG;
2133#else
2134 vtop->type.t = VT_INT;
2135#endif
2136 vswap();2136 vswap();
2137 gen_op(TOK_PDIV);2137 gen_op(TOK_PDIV);
2138 } else {2138 } else {
@@ -2218,14 +2218,15 @@ redo: · 79 unmodified lines
2218 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;2218 t = bt1 == VT_LLONG ? VT_LLONG : VT_INT;
2219 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))2219 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (t | VT_UNSIGNED))
2220 t |= VT_UNSIGNED;2220 t |= VT_UNSIGNED;
2221 t |= (VT_LONG & t1);
2221 goto std_op;2222 goto std_op;
2222 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {2223 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
2223 /* cast to biggest op */2224 /* cast to biggest op */
2224 t = VT_LLONG;2225 t = VT_LLONG | VT_LONG;
2225 /* check if we need to keep type as long or as long long */2226 if (bt1 == VT_LLONG)
2226 if ((t1 & VT_LONG && (t2 & (VT_BTYPE | VT_LONG)) != VT_LLONG) ||2227 t &= t1;
2227 (t2 & VT_LONG && (t1 & (VT_BTYPE | VT_LONG)) != VT_LLONG))2228 if (bt2 == VT_LLONG)
2228 t |= VT_LONG;2229 t &= t2;
2229 /* convert to unsigned if it does not fit in a long long */2230 /* convert to unsigned if it does not fit in a long long */
2230 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||2231 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
2231 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))2232 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
@@ -2233,12 +2234,8 @@ redo: · 1 unmodified line
2233 goto std_op;2234 goto std_op;
2234 } else {2235 } else {
2235 /* integer operations */2236 /* integer operations */
2236 t = VT_INT;2237 t = VT_INT | (VT_LONG & (t1 | t2));
2237 2238 /* convert to unsigned if it does not fit in an integer */
2238 if ((t1 & VT_LONG) || (t2 & VT_LONG))
2239 t |= VT_LONG;
2240
2241 /* convert to unsigned if it does not fit in an integer */
2242 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||2239 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
2243 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))2240 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
2244 t |= VT_UNSIGNED;2241 t |= VT_UNSIGNED;
@@ -2741,7 +2738,6 @@ static int compare_types(CType *type1, CType *type2, int unqualified) · 496 unmodified lines
2741 t1 &= ~VT_DEFSIGN;2738 t1 &= ~VT_DEFSIGN;
2742 t2 &= ~VT_DEFSIGN;2739 t2 &= ~VT_DEFSIGN;
2743 }2740 }
2744
2745 /* XXX: bitfields ? */2741 /* XXX: bitfields ? */
2746 if (t1 != t2)2742 if (t1 != t2)
2747 return 0;2743 return 0;
@@ -2790,14 +2786,7 @@ static void type_to_str(char *buf, int buf_size, · 42 unmodified lines
2790 t = type->t;2786 t = type->t;
2791 bt = t & VT_BTYPE;2787 bt = t & VT_BTYPE;
2792 buf[0] = '\0';2788 buf[0] = '\0';
2793 if (t & VT_CONSTANT)2789
2794 pstrcat(buf, buf_size, "const ");
2795 if (t & VT_VOLATILE)
2796 pstrcat(buf, buf_size, "volatile ");
2797 if ((t & (VT_DEFSIGN | VT_UNSIGNED)) == (VT_DEFSIGN | VT_UNSIGNED))
2798 pstrcat(buf, buf_size, "unsigned ");
2799 else if (t & VT_DEFSIGN)
2800 pstrcat(buf, buf_size, "signed ");
2801 if (t & VT_EXTERN)2790 if (t & VT_EXTERN)
2802 pstrcat(buf, buf_size, "extern ");2791 pstrcat(buf, buf_size, "extern ");
2803 if (t & VT_STATIC)2792 if (t & VT_STATIC)
@@ -2806,17 +2795,20 @@ static void type_to_str(char *buf, int buf_size, · 2 unmodified lines
2806 pstrcat(buf, buf_size, "typedef ");2795 pstrcat(buf, buf_size, "typedef ");
2807 if (t & VT_INLINE)2796 if (t & VT_INLINE)
2808 pstrcat(buf, buf_size, "inline ");2797 pstrcat(buf, buf_size, "inline ");
2798 if (t & VT_VOLATILE)
2799 pstrcat(buf, buf_size, "volatile ");
2800 if (t & VT_CONSTANT)
2801 pstrcat(buf, buf_size, "const ");
2802
2803 if (((t & VT_DEFSIGN) && bt == VT_BYTE)
2804 || ((t & VT_UNSIGNED)
2805 && (bt == VT_SHORT || bt == VT_INT || bt == VT_LLONG)
2806 && !IS_ENUM(t)
2807 ))
2808 pstrcat(buf, buf_size, (t & VT_UNSIGNED) ? "unsigned " : "signed ");
2809
2809 buf_size -= strlen(buf);2810 buf_size -= strlen(buf);
2810 buf += strlen(buf);2811 buf += strlen(buf);
2811 if (IS_ENUM(t)) {
2812 tstr = "enum ";
2813 goto tstruct;
2814 }
2815
2816 if (!bt && VT_LONG & t) {
2817 tstr = "long";
2818 goto add_tstr;
2819 }
2820 2812
2821 switch(bt) {2813 switch(bt) {
2822 case VT_VOID:2814 case VT_VOID:
@@ -2833,10 +2825,16 @@ static void type_to_str(char *buf, int buf_size, · 10 unmodified lines
2833 goto add_tstr;2825 goto add_tstr;
2834 case VT_INT:2826 case VT_INT:
2835 tstr = "int";2827 tstr = "int";
2836 goto add_tstr;2828 goto maybe_long;
2837 case VT_LLONG:2829 case VT_LLONG:
2838 tstr = "long long";2830 tstr = "long long";
2839 goto add_tstr;2831 maybe_long:
2832 if (t & VT_LONG)
2833 tstr = "long";
2834 if (!IS_ENUM(t))
2835 goto add_tstr;
2836 tstr = "enum ";
2837 goto tstruct;
2840 case VT_FLOAT:2838 case VT_FLOAT:
2841 tstr = "float";2839 tstr = "float";
2842 goto add_tstr;2840 goto add_tstr;
@@ -2902,7 +2900,7 @@ static void type_to_str(char *buf, int buf_size, · 59 unmodified lines
2902 casts if needed. */2900 casts if needed. */
2903static void gen_assign_cast(CType *dt)2901static void gen_assign_cast(CType *dt)
2904{2902{
2905 CType *st, *type1, *type2, tmp_type1, tmp_type2;2903 CType *st, *type1, *type2;
2906 char buf1[256], buf2[256];2904 char buf1[256], buf2[256];
2907 int dbt, sbt;2905 int dbt, sbt;
2908 2906
@@ -2958,7 +2956,7 @@ static void gen_assign_cast(CType *dt) · 49 unmodified lines
2958 in pointer target signedness. Do warn for different2956 in pointer target signedness. Do warn for different
2959 base types, though, in particular for unsigned enums2957 base types, though, in particular for unsigned enums
2960 and signed int targets. */2958 and signed int targets. */
2961 if ((type1->t & VT_BTYPE) != (type2->t & VT_BTYPE)2959 if ((type1->t & (VT_BTYPE|VT_LONG)) != (type2->t & (VT_BTYPE|VT_LONG))
2962 || IS_ENUM(type1->t) || IS_ENUM(type2->t)2960 || IS_ENUM(type1->t) || IS_ENUM(type2->t)
2963 )2961 )
2964 tcc_warning("assignment from incompatible pointer type");2962 tcc_warning("assignment from incompatible pointer type");
@@ -2982,11 +2980,7 @@ static void gen_assign_cast(CType *dt) · 17 unmodified lines
2982 break;2980 break;
2983 case VT_STRUCT:2981 case VT_STRUCT:
2984 case_VT_STRUCT:2982 case_VT_STRUCT:
2985 tmp_type1 = *dt;2983 if (!is_compatible_unqualified_types(dt, st)) {
2986 tmp_type2 = *st;
2987 tmp_type1.t &= ~(VT_CONSTANT | VT_VOLATILE);
2988 tmp_type2.t &= ~(VT_CONSTANT | VT_VOLATILE);
2989 if (!is_compatible_types(&tmp_type1, &tmp_type2)) {
2990 error:2984 error:
2991 type_to_str(buf1, sizeof(buf1), st, NULL);2985 type_to_str(buf1, sizeof(buf1), st, NULL);
2992 type_to_str(buf2, sizeof(buf2), dt, NULL);2986 type_to_str(buf2, sizeof(buf2), dt, NULL);
@@ -3775,10 +3769,10 @@ do_decl: · 782 unmodified lines
3775 t.t = VT_INT;3769 t.t = VT_INT;
3776 if (nl >= 0) {3770 if (nl >= 0) {
3777 if (pl != (unsigned)pl)3771 if (pl != (unsigned)pl)
3778 t.t = VT_LLONG;3772 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3779 t.t |= VT_UNSIGNED;3773 t.t |= VT_UNSIGNED;
3780 } else if (pl != (int)pl || nl != (int)nl)3774 } else if (pl != (int)pl || nl != (int)nl)
3781 t.t = VT_LLONG;3775 t.t = (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3782 s->type.t = type->t = t.t | VT_ENUM;3776 s->type.t = type->t = t.t | VT_ENUM;
3783 s->c = 0;3777 s->c = 0;
3784 /* set type for enum members */3778 /* set type for enum members */
@@ -3791,7 +3785,8 @@ do_decl: · 6 unmodified lines
3791 if (ll == (unsigned)ll)3785 if (ll == (unsigned)ll)
3792 continue;3786 continue;
3793 }3787 }
3794 ss->type.t = (ss->type.t & ~VT_BTYPE) | VT_LLONG;3788 ss->type.t = (ss->type.t & ~VT_BTYPE)
3789 | (LONG_SIZE==8 ? VT_LLONG|VT_LONG : VT_LLONG);
3795 }3790 }
3796 } else {3791 } else {
3797 c = 0;3792 c = 0;
@@ -3964,7 +3959,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 166 unmodified lines
3964 bt = u;3959 bt = u;
3965 }3960 }
3966 if (u != VT_INT)3961 if (u != VT_INT)
3967 t = (t & ~VT_BTYPE) | u;3962 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
3968 typespec_found = 1;3963 typespec_found = 1;
3969 break;3964 break;
3970 case TOK_VOID:3965 case TOK_VOID:
@@ -3978,11 +3973,9 @@ static int parse_btype(CType *type, AttributeDef *ad) · 7 unmodified lines
3978 goto basic_type;3973 goto basic_type;
3979 case TOK_LONG:3974 case TOK_LONG:
3980 if ((t & VT_BTYPE) == VT_DOUBLE) {3975 if ((t & VT_BTYPE) == VT_DOUBLE) {
3981#ifndef TCC_TARGET_PE3976 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
3982 t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LDOUBLE;3977 } else if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
3983#endif3978 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LLONG;
3984 } else if (t & VT_LONG) {
3985 t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LLONG;
3986 } else {3979 } else {
3987 u = VT_LONG;3980 u = VT_LONG;
3988 goto basic_type;3981 goto basic_type;
@@ -4003,12 +3996,8 @@ static int parse_btype(CType *type, AttributeDef *ad) · 14 unmodified lines
4003 u = VT_FLOAT;3996 u = VT_FLOAT;
4004 goto basic_type;3997 goto basic_type;
4005 case TOK_DOUBLE:3998 case TOK_DOUBLE:
4006 if (t & VT_LONG) {3999 if ((t & (VT_BTYPE|VT_LONG)) == VT_LONG) {
4007#ifdef TCC_TARGET_PE4000 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
4008 t = (t & ~(VT_LONG | VT_BTYPE)) | VT_DOUBLE;
4009#else
4010 t = (t & ~(VT_LONG | VT_BTYPE)) | VT_LDOUBLE;
4011#endif
4012 } else {4001 } else {
4013 u = VT_DOUBLE;4002 u = VT_DOUBLE;
4014 goto basic_type;4003 goto basic_type;
@@ -4098,7 +4087,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 83 unmodified lines
4098 parse_attribute(ad);4087 parse_attribute(ad);
4099 if (ad->attr_mode) {4088 if (ad->attr_mode) {
4100 u = ad->attr_mode -1;4089 u = ad->attr_mode -1;
4101 t = (t & ~VT_BTYPE) | u;4090 t = (t & ~(VT_BTYPE|VT_LONG)) | u;
4102 }4091 }
4103 break;4092 break;
4104 /* GNUC typeof */4093 /* GNUC typeof */
@@ -4118,7 +4107,7 @@ static int parse_btype(CType *type, AttributeDef *ad) · 13 unmodified lines
4118 s = sym_find(tok);4107 s = sym_find(tok);
4119 if (!s || !(s->type.t & VT_TYPEDEF))4108 if (!s || !(s->type.t & VT_TYPEDEF))
4120 goto the_end;4109 goto the_end;
4121 t &= ~VT_BTYPE;4110 t &= ~(VT_BTYPE|VT_LONG);
4122 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;4111 u = t & ~(VT_CONSTANT | VT_VOLATILE), t ^= u;
4123 type->t = (s->type.t & ~VT_TYPEDEF) | u;4112 type->t = (s->type.t & ~VT_TYPEDEF) | u;
4124 type->ref = s->type.ref;4113 type->ref = s->type.ref;
@@ -4139,13 +4128,13 @@ the_end: · 14 unmodified lines
4139 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)4128 if ((t & (VT_DEFSIGN|VT_BTYPE)) == VT_BYTE)
4140 t |= VT_UNSIGNED;4129 t |= VT_UNSIGNED;
4141 }4130 }
4142 4131 /* VT_LONG is used just as a modifier for VT_INT / VT_LLONG */
4143 /* long is never used as type */4132 bt = t & (VT_BTYPE|VT_LONG);
4144 if (t & VT_LONG)4133 if (bt == VT_LONG)
4145#if PTR_SIZE == 8 && !defined TCC_TARGET_PE4134 t |= LONG_SIZE == 8 ? VT_LLONG : VT_INT;
4146 t = (t & ~VT_BTYPE) | VT_LLONG;4135#ifdef TCC_TARGET_PE
4147#else4136 if (bt == VT_LDOUBLE)
4148 t = (t & ~VT_BTYPE) | VT_INT;4137 t = (t & ~(VT_BTYPE|VT_LONG)) | VT_DOUBLE;
4149#endif4138#endif
4150 type->t = t;4139 type->t = t;
4151 return type_found;4140 return type_found;
@@ -4544,9 +4533,13 @@ ST_FUNC void unary(void) · 392 unmodified lines
4544 case TOK_EXTENSION:4533 case TOK_EXTENSION:
4545 next();4534 next();
4546 goto tok_next;4535 goto tok_next;
4536 case TOK_LCHAR:
4537#ifdef TCC_TARGET_PE
4538 t = VT_SHORT|VT_UNSIGNED;
4539 goto push_tokc;
4540#endif
4547 case TOK_CINT:4541 case TOK_CINT:
4548 case TOK_CCHAR: 4542 case TOK_CCHAR:
4549 case TOK_LCHAR:
4550 t = VT_INT;4543 t = VT_INT;
4551 push_tokc:4544 push_tokc:
4552 type.t = t;4545 type.t = t;
@@ -4572,14 +4565,10 @@ ST_FUNC void unary(void) · 19 unmodified lines
4572 t = VT_LDOUBLE;4565 t = VT_LDOUBLE;
4573 goto push_tokc;4566 goto push_tokc;
4574 case TOK_CLONG:4567 case TOK_CLONG:
4568 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG;
4569 goto push_tokc;
4575 case TOK_CULONG:4570 case TOK_CULONG:
4576 #ifdef TCC_LONG_ARE_64_BIT4571 t = (LONG_SIZE == 8 ? VT_LLONG : VT_INT) | VT_LONG | VT_UNSIGNED;
4577 t = VT_LLONG | VT_LONG;
4578 #else
4579 t = VT_INT | VT_LONG;
4580 #endif
4581 if (tok == TOK_CULONG)
4582 t |= VT_UNSIGNED;
4583 goto push_tokc;4572 goto push_tokc;
4584 case TOK___FUNCTION__:4573 case TOK___FUNCTION__:
4585 if (!gnu_ext)4574 if (!gnu_ext)
@@ -5491,7 +5480,11 @@ static void expr_cond(void) · 905 unmodified lines
5491 }5480 }
5492 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {5481 } else if (bt1 == VT_LLONG || bt2 == VT_LLONG) {
5493 /* cast to biggest op */5482 /* cast to biggest op */
5494 type.t = VT_LLONG;5483 type.t = VT_LLONG | VT_LONG;
5484 if (bt1 == VT_LLONG)
5485 type.t &= t1;
5486 if (bt2 == VT_LLONG)
5487 type.t &= t2;
5495 /* convert to unsigned if it does not fit in a long long */5488 /* convert to unsigned if it does not fit in a long long */
5496 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||5489 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED) ||
5497 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))5490 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_LLONG | VT_UNSIGNED))
@@ -5518,7 +5511,7 @@ static void expr_cond(void) · 20 unmodified lines
5518 type.t = VT_VOID;5511 type.t = VT_VOID;
5519 } else {5512 } else {
5520 /* integer operations */5513 /* integer operations */
5521 type.t = VT_INT;5514 type.t = VT_INT | (VT_LONG & (t1 | t2));
5522 /* convert to unsigned if it does not fit in an integer */5515 /* convert to unsigned if it does not fit in an integer */
5523 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||5516 if ((t1 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED) ||
5524 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))5517 (t2 & (VT_BTYPE | VT_UNSIGNED | VT_BITFIELD)) == (VT_INT | VT_UNSIGNED))
@@ -6490,20 +6483,20 @@ static void init_putv(CType *type, Section *sec, unsigned long c) · 965 unmodified lines
6490 *(double *)ptr = vtop->c.d;6483 *(double *)ptr = vtop->c.d;
6491 break;6484 break;
6492 case VT_LDOUBLE:6485 case VT_LDOUBLE:
6493 if (sizeof(long double) == LDOUBLE_SIZE)
6494 *(long double *)ptr = vtop->c.ld;
6495 else if (sizeof(double) == LDOUBLE_SIZE)
6496 *(double *)ptr = (double)vtop->c.ld;
6497#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)6486#if (defined __i386__ || defined __x86_64__) && (defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64)
6498 else if (sizeof (long double) >= 10)6487 if (sizeof (long double) >= 10) /* zero pad ten-byte LD */
6499 memcpy(memset(ptr, 0, LDOUBLE_SIZE), &vtop->c.ld, 10);6488 memcpy(ptr, &vtop->c.ld, 10);
6500#ifdef __TINYC__6489#ifdef __TINYC__
6501 else if (sizeof (long double) == sizeof (double))6490 else if (sizeof (long double) == sizeof (double))
6502 __asm__("fldl %1\nfstpt %0\n" : "=m"6491 __asm__("fldl %1\nfstpt %0\n" : "=m" (ptr) : "m" (vtop->c.ld));
6503 (memset(ptr, 0, LDOUBLE_SIZE), ptr) : "m" (vtop->c.ld));
6504#endif6492#endif
6493 else
6505#endif6494#endif
6506 else6495 if (sizeof(long double) == LDOUBLE_SIZE)
6496 *(long double*)ptr = vtop->c.ld;
6497 else if (sizeof(double) == LDOUBLE_SIZE)
6498 *(double *)ptr = (double)vtop->c.ld;
6499 else
6507 tcc_error("can't cross compile long double constants");6500 tcc_error("can't cross compile long double constants");
6508 break;6501 break;
6509#if PTR_SIZE != 86502#if PTR_SIZE != 8
tccpp.c+58−64
@@ -89,7 +89,7 @@ static const unsigned char tok_two_chars[] = · 88 unmodified lines
89 '^','=', TOK_A_XOR,89 '^','=', TOK_A_XOR,
90 '|','=', TOK_A_OR,90 '|','=', TOK_A_OR,
91 '-','>', TOK_ARROW,91 '-','>', TOK_ARROW,
92 '.','.', 0xa8, // C++ token ?92 '.','.', TOK_TWODOTS,
93 '#','#', TOK_TWOSHARPS,93 '#','#', TOK_TWOSHARPS,
94 094 0
95};95};
@@ -1017,23 +1017,18 @@ static inline int tok_size(const int *p) · 921 unmodified lines
1017 case TOK_LCHAR:1017 case TOK_LCHAR:
1018 case TOK_CFLOAT:1018 case TOK_CFLOAT:
1019 case TOK_LINENUM:1019 case TOK_LINENUM:
1020#ifndef TCC_LONG_ARE_64_BIT
1021 case TOK_CLONG;
1022 case TOK_CULONG;
1023#endif
1024 return 1 + 1;1020 return 1 + 1;
1025 case TOK_STR:1021 case TOK_STR:
1026 case TOK_LSTR:1022 case TOK_LSTR:
1027 case TOK_PPNUM:1023 case TOK_PPNUM:
1028 case TOK_PPSTR:1024 case TOK_PPSTR:
1029 return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);1025 return 1 + ((sizeof(CString) + ((CString *)(p+1))->size + 3) >> 2);
1026 case TOK_CLONG:
1027 case TOK_CULONG:
1028 return 1 + LONG_SIZE / 4;
1030 case TOK_CDOUBLE:1029 case TOK_CDOUBLE:
1031 case TOK_CLLONG:1030 case TOK_CLLONG:
1032 case TOK_CULLONG:1031 case TOK_CULLONG:
1033#ifdef TCC_LONG_ARE_64_BIT
1034 case TOK_CLONG;
1035 case TOK_CULONG;
1036#endif
1037 return 1 + 2;1032 return 1 + 2;
1038 case TOK_CLDOUBLE:1033 case TOK_CLDOUBLE:
1039 return 1 + LDOUBLE_SIZE / 4;1034 return 1 + LDOUBLE_SIZE / 4;
@@ -1149,7 +1144,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 109 unmodified lines
1149 case TOK_LCHAR:1144 case TOK_LCHAR:
1150 case TOK_CFLOAT:1145 case TOK_CFLOAT:
1151 case TOK_LINENUM:1146 case TOK_LINENUM:
1152#ifndef TCC_LONG_ARE_64_BIT1147#if LONG_SIZE == 4
1153 case TOK_CLONG:1148 case TOK_CLONG:
1154 case TOK_CULONG:1149 case TOK_CULONG:
1155#endif1150#endif
@@ -1173,7 +1168,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv) · 17 unmodified lines
1173 case TOK_CDOUBLE:1168 case TOK_CDOUBLE:
1174 case TOK_CLLONG:1169 case TOK_CLLONG:
1175 case TOK_CULLONG:1170 case TOK_CULLONG:
1176#ifdef TCC_LONG_ARE_64_BIT1171#if LONG_SIZE == 8
1177 case TOK_CLONG:1172 case TOK_CLONG:
1178 case TOK_CULONG:1173 case TOK_CULONG:
1179#endif1174#endif
@@ -1227,17 +1222,20 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 47 unmodified lines
1227 1222
1228 tab = cv->tab;1223 tab = cv->tab;
1229 switch(*t = *p++) {1224 switch(*t = *p++) {
1225#if LONG_SIZE == 4
1226 case TOK_CLONG:
1227#endif
1230 case TOK_CINT:1228 case TOK_CINT:
1231 case TOK_CUINT:
1232 case TOK_CCHAR:1229 case TOK_CCHAR:
1233 case TOK_LCHAR:1230 case TOK_LCHAR:
1234 case TOK_LINENUM:1231 case TOK_LINENUM:
1235#ifndef TCC_LONG_ARE_64_BIT1232 cv->i = *p++;
1236 case TOK_CLONG:1233 break;
1234#if LONG_SIZE == 4
1237 case TOK_CULONG:1235 case TOK_CULONG:
1238#endif1236#endif
1239 tab[0] = *p++;1237 case TOK_CUINT:
1240 cv->i = (*t == TOK_CUINT) ? (unsigned)cv->i : (int)cv->i;1238 cv->i = (unsigned)*p++;
1241 break;1239 break;
1242 case TOK_CFLOAT:1240 case TOK_CFLOAT:
1243 tab[0] = *p++;1241 tab[0] = *p++;
@@ -1253,7 +1251,7 @@ static inline void TOK_GET(int *t, const int **pp, CValue *cv) · 9 unmodified lines
1253 case TOK_CDOUBLE:1251 case TOK_CDOUBLE:
1254 case TOK_CLLONG:1252 case TOK_CLLONG:
1255 case TOK_CULLONG:1253 case TOK_CULLONG:
1256#ifdef TCC_LONG_ARE_64_BIT1254#if LONG_SIZE == 8
1257 case TOK_CLONG:1255 case TOK_CLONG:
1258 case TOK_CULONG:1256 case TOK_CULONG:
1259#endif1257#endif
@@ -2206,23 +2204,24 @@ static void parse_string(const char *s, int len) · 946 unmodified lines
2206 tcc_free(p);2204 tcc_free(p);
2207 2205
2208 if (sep == '\'') {2206 if (sep == '\'') {
2209 int char_size;2207 int char_size, i, n, c;
2210 /* XXX: make it portable */2208 /* XXX: make it portable */
2211 if (!is_long)2209 if (!is_long)
2212 char_size = 1;2210 tok = TOK_CCHAR, char_size = 1;
2213 else2211 else
2214 char_size = sizeof(nwchar_t);2212 tok = TOK_LCHAR, char_size = sizeof(nwchar_t);
2215 if (tokcstr.size <= char_size)2213 n = tokcstr.size / char_size - 1;
2214 if (n < 1)
2216 tcc_error("empty character constant");2215 tcc_error("empty character constant");
2217 if (tokcstr.size > 2 * char_size)2216 if (n > 1)
2218 tcc_warning("multi-character character constant");2217 tcc_warning("multi-character character constant");
2219 if (!is_long) {2218 for (c = i = 0; i < n; ++i) {
2220 tokc.i = *(int8_t *)tokcstr.data;2219 if (is_long)
2221 tok = TOK_CCHAR;2220 c = ((nwchar_t *)tokcstr.data)[i];
2222 } else {2221 else
2223 tokc.i = *(nwchar_t *)tokcstr.data;2222 c = (c << 8) | ((char *)tokcstr.data)[i];
2224 tok = TOK_LCHAR;
2225 }2223 }
2224 tokc.i = c;
2226 } else {2225 } else {
2227 tokc.str.size = tokcstr.size;2226 tokc.str.size = tokcstr.size;
2228 tokc.str.data = tokcstr.data;2227 tokc.str.data = tokcstr.data;
@@ -2456,7 +2455,7 @@ static void parse_number(const char *p) · 227 unmodified lines
2456 }2455 }
2457 } else {2456 } else {
2458 unsigned long long n, n1;2457 unsigned long long n, n1;
2459 int lcount, ucount, must_64bit;2458 int lcount, ucount, ov = 0;
2460 const char *p1;2459 const char *p1;
2461 2460
2462 /* integer number */2461 /* integer number */
@@ -2483,14 +2482,13 @@ static void parse_number(const char *p) · 20 unmodified lines
2483 n1 = n;2482 n1 = n;
2484 n = n * b + t;2483 n = n * b + t;
2485 /* detect overflow */2484 /* detect overflow */
2486 /* XXX: this test is not reliable */2485 if (n1 >= 0x1000000000000000ULL && n / b != n1)
2487 if (n < n1)2486 ov = 1;
2488 tcc_error("integer constant overflow");
2489 }2487 }
2490 2488
2491 /* Determine the characteristics (unsigned and/or 64bit) the type of2489 /* Determine the characteristics (unsigned and/or 64bit) the type of
2492 the constant must have according to the constant suffix(es) */2490 the constant must have according to the constant suffix(es) */
2493 lcount = ucount = must_64bit = 0;2491 lcount = ucount = 0;
2494 p1 = p;2492 p1 = p;
2495 for(;;) {2493 for(;;) {
2496 t = toup(ch);2494 t = toup(ch);
@@ -2500,8 +2498,6 @@ static void parse_number(const char *p) · 3 unmodified lines
2500 if (lcount && *(p - 1) != ch)2498 if (lcount && *(p - 1) != ch)
2501 tcc_error("incorrect integer suffix: %s", p1);2499 tcc_error("incorrect integer suffix: %s", p1);
2502 lcount++;2500 lcount++;
2503 if (lcount == 2)
2504 must_64bit = 1;
2505 ch = *p++;2501 ch = *p++;
2506 } else if (t == 'U') {2502 } else if (t == 'U') {
2507 if (ucount >= 1)2503 if (ucount >= 1)
@@ -2513,38 +2509,36 @@ static void parse_number(const char *p) · 5 unmodified lines
2513 }2509 }
2514 }2510 }
2515 2511
2516 /* Whether 64 bits are needed to hold the constant's value */2512 /* Determine if it needs 64 bits and/or unsigned in order to fit */
2517 if (n & 0xffffffff00000000LL || must_64bit) {2513 if (ucount == 0 && b == 10) {
2518 tok = TOK_CLLONG;2514 if (lcount <= (LONG_SIZE == 4)) {
2519 n1 = n >> 32;2515 if (n >= 0x80000000U)
2520 } else if (lcount) {2516 lcount = (LONG_SIZE == 4) + 1;
2521#ifdef TCC_LONG_ARE_64_BIT2517 }
2522 n1 = n >> 32;2518 if (n >= 0x8000000000000000ULL)
2523#else2519 ov = 1, ucount = 1;
2524 n1 = n;2520 } else {
2525#endif2521 if (lcount <= (LONG_SIZE == 4)) {
2526 tok = TOK_CLONG;2522 if (n >= 0x100000000ULL)
2527 } else {2523 lcount = (LONG_SIZE == 4) + 1;
2528 tok = TOK_CINT;2524 else if (n >= 0x80000000U)
2529 n1 = n;2525 ucount = 1;
2526 }
2527 if (n >= 0x8000000000000000ULL)
2528 ucount = 1;
2530 }2529 }
2531 2530
2532 /* Whether type must be unsigned to hold the constant's value */2531 if (ov)
2533 if (ucount || ((n1 >> 31) && (b != 10))) {2532 tcc_warning("integer constant overflow");
2534 if (tok == TOK_CLLONG)
2535 tok = TOK_CULLONG;
2536 else if (tok == TOK_CLONG)
2537 tok = TOK_CULONG;
2538 else
2539 tok = TOK_CUINT;
2540 /* If decimal and no unsigned suffix, bump to 64 bits or throw error */
2541 } else if (n1 >> 31) {
2542 if (tok == TOK_CINT)
2543 tok = TOK_CLLONG;
2544 else
2545 tcc_error("integer constant overflow");
2546 }
2547 2533
2534 tok = TOK_CINT;
2535 if (lcount) {
2536 tok = TOK_CLONG;
2537 if (lcount == 2)
2538 tok = TOK_CLLONG;
2539 }
2540 if (ucount)
2541 ++tok; /* TOK_CU... */
2548 tokc.i = n;2542 tokc.i = n;
2549 }2543 }
2550 if (ch)2544 if (ch)
win32/build-tcc.bat+1−1
@@ -113,7 +113,7 @@ for %%f in (*tcc.exe *tcc.dll) do @del %%f · 112 unmodified lines
113:compiler113:compiler
114%CC% -o libtcc.dll -shared ..\libtcc.c %D% -DLIBTCC_AS_DLL114%CC% -o libtcc.dll -shared ..\libtcc.c %D% -DLIBTCC_AS_DLL
115@if errorlevel 1 goto :the_end115@if errorlevel 1 goto :the_end
116%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE=0116%CC% -o tcc.exe ..\tcc.c libtcc.dll %D% -DONE_SOURCE"=0"
117%CC% -o %PX%-tcc.exe ..\tcc.c %DX%117%CC% -o %PX%-tcc.exe ..\tcc.c %DX%
118 118
119@if (%TCC_FILES%)==(no) goto :files-done119@if (%TCC_FILES%)==(no) goto :files-done

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t