diff mbox series

[05/11] make predefined_type_size() more generic

Message ID 20181209234320.65274-6-luc.vanoostenryck@gmail.com (mailing list archive)
State Superseded, archived
Headers show
Series predefined macros for intmax_t/intptr_t/... | expand

Commit Message

Luc Van Oostenryck Dec. 9, 2018, 11:43 p.m. UTC
This allows to have a single function to output the
size, the type, the maximal value, ...
---
 lib.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 36 insertions(+), 21 deletions(-)

Comments

Ramsay Jones Dec. 11, 2018, 10:55 p.m. UTC | #1
On 09/12/2018 23:43, Luc Van Oostenryck wrote:
> This allows to have a single function to output the
> size, the type, the maximal value, ...
> ---
>  lib.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
>  1 file changed, 36 insertions(+), 21 deletions(-)
> 
> diff --git a/lib.c b/lib.c
> index db33e58b2..1156f6f6c 100644
> --- a/lib.c
> +++ b/lib.c
> @@ -1144,6 +1144,15 @@ static char **handle_switch(char *arg, char **next)
>  	return next;
>  }
>  
> +#define	PTYPE_SIZEOF	(1U << 0)
> +#define	PTYPE_T		(1U << 1)
> +#define	PTYPE_SIZEOF_T	(PTYPE_SIZEOF|PTYPE_T)
> +#define	PTYPE_MAX	(1U << 2)
> +#define	PTYPE_MIN	(1U << 3)
> +#define	PTYPE_TYPE	(1U << 4)
> +#define	PTYPE_WIDTH	(1U << 4)

(1U << 4) used twice for _TYPE and _WIDTH.

> +#define	PTYPE_ALL	(PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH)
> +
>  static void predefined_sizeof(const char *name, const char *suffix, unsigned bits)
>  {
>  	char buf[32];
> @@ -1169,19 +1178,30 @@ static void predefined_max(const char *name, const char *suffix, unsigned bits)
>  	predefine(buf, 1, "%#llx%s", max, suffix);
>  }
>  
> -static void predefined_type_size(const char *name, const char *suffix, unsigned bits)
> -{
> -	predefined_max(name, suffix, bits);
> -	predefined_sizeof(name, "", bits);
> -	predefined_width(name, bits);
> -}
> -
>  static void predefined_type(const char *name, struct symbol *type)
>  {
>  	const char *typename = builtin_typename(type);
>  	add_pre_buffer("#weak_define __%s_TYPE__ %s\n", name, typename);
>  }
>  
> +static void predefined_ctype(const char *name, struct symbol *type, int flags)
> +{
> +	unsigned bits = type->bit_size;
> +
> +	if (flags & PTYPE_SIZEOF) {
> +		const char *suffix = (flags & PTYPE_T) ? "_T" : "";
> +		predefined_sizeof(name, suffix, bits);
> +	}
> +	if (flags & PTYPE_MAX) {
> +		const char *suffix = builtin_type_suffix(type);
> +		predefined_max(name, suffix, bits);

predefined_max() does not account for signed-ness of the type, so
that _all_ unsigned types have a _MAX value that is the same as
the signed variant. e.g. __UINT16_MAX__ is 0x7fff rather than 0xffff.

> +	}
> +	if (flags & PTYPE_TYPE)
> +		predefined_type(name, type);

The type names are not expressed the same as gcc (not a big deal), but
we could change the type names in the typenames[] table to match.
(show-parse.c, ln 222).

ATB,
Ramsay Jones


> +	if (flags & PTYPE_WIDTH)
> +		predefined_width(name, bits);
> +}
> +
>  static void predefined_macros(void)
>  {
>  	predefine("__CHECKER__", 0, "1");
> @@ -1223,26 +1243,23 @@ static void predefined_macros(void)
>  		break;
>  	}
>  
> -	predefined_sizeof("SHORT", "", bits_in_short);
> -	predefined_max("SHRT", "", bits_in_short);
> -	predefined_width("SHRT",   bits_in_short);
> -	predefined_max("SCHAR", "", bits_in_char);
> -	predefined_width("SCHAR",   bits_in_char);
> +	predefined_ctype("SHORT", &short_ctype, PTYPE_SIZEOF);
> +	predefined_ctype("SHRT",  &short_ctype, PTYPE_MAX|PTYPE_WIDTH);
> +	predefined_ctype("SCHAR",  &char_ctype, PTYPE_MAX|PTYPE_WIDTH);
>  	predefined_sizeof("WCHAR", "_T", bits_in_wchar);
>  	predefined_max("WCHAR", "", bits_in_wchar);
>  	predefined_width("WCHAR",   bits_in_wchar);
> +
>  	predefine("__CHAR_BIT__", 1, "%d", bits_in_char);
>  
> -	predefined_type_size("INT", "", bits_in_int);
> -	predefined_type_size("LONG", "L", bits_in_long);
> -	predefined_type_size("LONG_LONG", "LL", bits_in_longlong);
> +	predefined_ctype("INT",         &int_ctype, PTYPE_ALL);
> +	predefined_ctype("LONG",       &long_ctype, PTYPE_ALL);
> +	predefined_ctype("LONG_LONG", &llong_ctype, PTYPE_ALL);
>  
>  	predefined_sizeof("INT128", "", 128);
>  
> -	predefined_sizeof("SIZE", "_T", bits_in_pointer);
> -	predefined_width( "SIZE",   bits_in_pointer);
> -	predefined_sizeof("PTRDIFF", "_T", bits_in_pointer);
> -	predefined_width( "PTRDIFF",   bits_in_pointer);
> +	predefined_ctype("SIZE", size_t_ctype, PTYPE_ALL|PTYPE_T|PTYPE_TYPE);
> +	predefined_ctype("PTRDIFF", &ptr_ctype, PTYPE_ALL|PTYPE_T);
>  	predefined_sizeof("POINTER", "", bits_in_pointer);
>  
>  	predefined_sizeof("FLOAT", "", bits_in_float);
> @@ -1275,8 +1292,6 @@ static void create_builtin_stream(void)
>  	// Temporary hack
>  	add_pre_buffer("#define _Pragma(x)\n");
>  
> -	predefined_type("SIZE", size_t_ctype);
> -
>  	/* add the multiarch include directories, if any */
>  	if (multiarch_dir && *multiarch_dir) {
>  		add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);
>
Luc Van Oostenryck Dec. 12, 2018, 4:33 p.m. UTC | #2
On Tue, Dec 11, 2018 at 10:55:33PM +0000, Ramsay Jones wrote:
> 
> 
> On 09/12/2018 23:43, Luc Van Oostenryck wrote:
> > This allows to have a single function to output the
> > size, the type, the maximal value, ...
> > ---
> >  lib.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
> >  1 file changed, 36 insertions(+), 21 deletions(-)
> > 
> > diff --git a/lib.c b/lib.c
> > index db33e58b2..1156f6f6c 100644
> > --- a/lib.c
> > +++ b/lib.c
> > @@ -1144,6 +1144,15 @@ static char **handle_switch(char *arg, char **next)
> >  	return next;
> >  }
> >  
> > +#define	PTYPE_SIZEOF	(1U << 0)
> > +#define	PTYPE_T		(1U << 1)
> > +#define	PTYPE_SIZEOF_T	(PTYPE_SIZEOF|PTYPE_T)
> > +#define	PTYPE_MAX	(1U << 2)
> > +#define	PTYPE_MIN	(1U << 3)
> > +#define	PTYPE_TYPE	(1U << 4)
> > +#define	PTYPE_WIDTH	(1U << 4)
> 
> (1U << 4) used twice for _TYPE and _WIDTH.

Uh, indeed. Thanks for noticing this.
 
> > +	if (flags & PTYPE_MAX) {
> > +		const char *suffix = builtin_type_suffix(type);
> > +		predefined_max(name, suffix, bits);
> 
> predefined_max() does not account for signed-ness of the type, so
> that _all_ unsigned types have a _MAX value that is the same as
> the signed variant. e.g. __UINT16_MAX__ is 0x7fff rather than 0xffff.

Indeed, when I started this series all the types were signed.
This is fixed now. Thanks!
 
> > +	}
> > +	if (flags & PTYPE_TYPE)
> > +		predefined_type(name, type);
> 
> The type names are not expressed the same as gcc (not a big deal), but
> we could change the type names in the typenames[] table to match.
> (show-parse.c, ln 222).

Yes, I know. In fact it's more or less on purpose as 'unsigned long'
talks to me much more than 'long unsigned int'.
I suppose you only care about a one-to-one textual correspondance
when testing/comparing with what GCC outputs?

Best regards
-- Luc
Ramsay Jones Dec. 12, 2018, 4:56 p.m. UTC | #3
On 12/12/2018 16:33, Luc Van Oostenryck wrote:
> On Tue, Dec 11, 2018 at 10:55:33PM +0000, Ramsay Jones wrote:
>>
>>
>> On 09/12/2018 23:43, Luc Van Oostenryck wrote:
>>> This allows to have a single function to output the
>>> size, the type, the maximal value, ...
>>> ---
>>>  lib.c | 57 ++++++++++++++++++++++++++++++++++++---------------------
>>>  1 file changed, 36 insertions(+), 21 deletions(-)
>>>
>>> diff --git a/lib.c b/lib.c
>>> index db33e58b2..1156f6f6c 100644
>>> --- a/lib.c
>>> +++ b/lib.c
>>> @@ -1144,6 +1144,15 @@ static char **handle_switch(char *arg, char **next)
>>>  	return next;
>>>  }
>>>  
>>> +#define	PTYPE_SIZEOF	(1U << 0)
>>> +#define	PTYPE_T		(1U << 1)
>>> +#define	PTYPE_SIZEOF_T	(PTYPE_SIZEOF|PTYPE_T)
>>> +#define	PTYPE_MAX	(1U << 2)
>>> +#define	PTYPE_MIN	(1U << 3)
>>> +#define	PTYPE_TYPE	(1U << 4)
>>> +#define	PTYPE_WIDTH	(1U << 4)
>>
>> (1U << 4) used twice for _TYPE and _WIDTH.
> 
> Uh, indeed. Thanks for noticing this.
>  
>>> +	if (flags & PTYPE_MAX) {
>>> +		const char *suffix = builtin_type_suffix(type);
>>> +		predefined_max(name, suffix, bits);
>>
>> predefined_max() does not account for signed-ness of the type, so
>> that _all_ unsigned types have a _MAX value that is the same as
>> the signed variant. e.g. __UINT16_MAX__ is 0x7fff rather than 0xffff.
> 
> Indeed, when I started this series all the types were signed.
> This is fixed now. Thanks!
>  
>>> +	}
>>> +	if (flags & PTYPE_TYPE)
>>> +		predefined_type(name, type);
>>
>> The type names are not expressed the same as gcc (not a big deal), but
>> we could change the type names in the typenames[] table to match.
>> (show-parse.c, ln 222).
> 
> Yes, I know. In fact it's more or less on purpose as 'unsigned long'
> talks to me much more than 'long unsigned int'.

Heh, yes I agree with you here! (and the C standard refers to it
this was as well) :-D

> I suppose you only care about a one-to-one textual correspondance
> when testing/comparing with what GCC outputs?

Yeah, as I said, its not a big deal - I can 'translate' in my
head while looking at the meld output!

Ah, I see you have just posted another series - I will get back
to you.

ATB,
Ramsay Jones
diff mbox series

Patch

diff --git a/lib.c b/lib.c
index db33e58b2..1156f6f6c 100644
--- a/lib.c
+++ b/lib.c
@@ -1144,6 +1144,15 @@  static char **handle_switch(char *arg, char **next)
 	return next;
 }
 
+#define	PTYPE_SIZEOF	(1U << 0)
+#define	PTYPE_T		(1U << 1)
+#define	PTYPE_SIZEOF_T	(PTYPE_SIZEOF|PTYPE_T)
+#define	PTYPE_MAX	(1U << 2)
+#define	PTYPE_MIN	(1U << 3)
+#define	PTYPE_TYPE	(1U << 4)
+#define	PTYPE_WIDTH	(1U << 4)
+#define	PTYPE_ALL	(PTYPE_MAX|PTYPE_SIZEOF|PTYPE_WIDTH)
+
 static void predefined_sizeof(const char *name, const char *suffix, unsigned bits)
 {
 	char buf[32];
@@ -1169,19 +1178,30 @@  static void predefined_max(const char *name, const char *suffix, unsigned bits)
 	predefine(buf, 1, "%#llx%s", max, suffix);
 }
 
-static void predefined_type_size(const char *name, const char *suffix, unsigned bits)
-{
-	predefined_max(name, suffix, bits);
-	predefined_sizeof(name, "", bits);
-	predefined_width(name, bits);
-}
-
 static void predefined_type(const char *name, struct symbol *type)
 {
 	const char *typename = builtin_typename(type);
 	add_pre_buffer("#weak_define __%s_TYPE__ %s\n", name, typename);
 }
 
+static void predefined_ctype(const char *name, struct symbol *type, int flags)
+{
+	unsigned bits = type->bit_size;
+
+	if (flags & PTYPE_SIZEOF) {
+		const char *suffix = (flags & PTYPE_T) ? "_T" : "";
+		predefined_sizeof(name, suffix, bits);
+	}
+	if (flags & PTYPE_MAX) {
+		const char *suffix = builtin_type_suffix(type);
+		predefined_max(name, suffix, bits);
+	}
+	if (flags & PTYPE_TYPE)
+		predefined_type(name, type);
+	if (flags & PTYPE_WIDTH)
+		predefined_width(name, bits);
+}
+
 static void predefined_macros(void)
 {
 	predefine("__CHECKER__", 0, "1");
@@ -1223,26 +1243,23 @@  static void predefined_macros(void)
 		break;
 	}
 
-	predefined_sizeof("SHORT", "", bits_in_short);
-	predefined_max("SHRT", "", bits_in_short);
-	predefined_width("SHRT",   bits_in_short);
-	predefined_max("SCHAR", "", bits_in_char);
-	predefined_width("SCHAR",   bits_in_char);
+	predefined_ctype("SHORT", &short_ctype, PTYPE_SIZEOF);
+	predefined_ctype("SHRT",  &short_ctype, PTYPE_MAX|PTYPE_WIDTH);
+	predefined_ctype("SCHAR",  &char_ctype, PTYPE_MAX|PTYPE_WIDTH);
 	predefined_sizeof("WCHAR", "_T", bits_in_wchar);
 	predefined_max("WCHAR", "", bits_in_wchar);
 	predefined_width("WCHAR",   bits_in_wchar);
+
 	predefine("__CHAR_BIT__", 1, "%d", bits_in_char);
 
-	predefined_type_size("INT", "", bits_in_int);
-	predefined_type_size("LONG", "L", bits_in_long);
-	predefined_type_size("LONG_LONG", "LL", bits_in_longlong);
+	predefined_ctype("INT",         &int_ctype, PTYPE_ALL);
+	predefined_ctype("LONG",       &long_ctype, PTYPE_ALL);
+	predefined_ctype("LONG_LONG", &llong_ctype, PTYPE_ALL);
 
 	predefined_sizeof("INT128", "", 128);
 
-	predefined_sizeof("SIZE", "_T", bits_in_pointer);
-	predefined_width( "SIZE",   bits_in_pointer);
-	predefined_sizeof("PTRDIFF", "_T", bits_in_pointer);
-	predefined_width( "PTRDIFF",   bits_in_pointer);
+	predefined_ctype("SIZE", size_t_ctype, PTYPE_ALL|PTYPE_T|PTYPE_TYPE);
+	predefined_ctype("PTRDIFF", &ptr_ctype, PTYPE_ALL|PTYPE_T);
 	predefined_sizeof("POINTER", "", bits_in_pointer);
 
 	predefined_sizeof("FLOAT", "", bits_in_float);
@@ -1275,8 +1292,6 @@  static void create_builtin_stream(void)
 	// Temporary hack
 	add_pre_buffer("#define _Pragma(x)\n");
 
-	predefined_type("SIZE", size_t_ctype);
-
 	/* add the multiarch include directories, if any */
 	if (multiarch_dir && *multiarch_dir) {
 		add_pre_buffer("#add_system \"/usr/include/%s\"\n", multiarch_dir);