Skip to contentSkip to conversation

Handle __builtin_ms_va_list.

PATCH Applied Michael Stefaniuc 3 participants 11 messages Sep 30, 2009 – Feb 2, 2010 Sparse checker

lore
Share & tools
lore
#0 lore raw

For Win64 compiles Wine does
#ifndef __ms_va_list

 # if defined(__x86_64__) && defined (__GNUC__)
 #  define __ms_va_list __builtin_ms_va_list
 #  define __ms_va_start(list,arg) __builtin_ms_va_start(list,arg)
 #  define __ms_va_end(list) __builtin_ms_va_end(list)
 # else

Wouldn't be as bad if sparse cannot handle those but it trips over
WINBASEAPI DWORD WINAPI FormatMessageA(DWORD,LPCVOID,DWORD,DWORD,LPSTR,DWORD,__ms_va_list*); WINBASEAPI DWORD WINAPI FormatMessageW(DWORD,LPCVOID,DWORD,DWORD,LPWSTR,DWORD,__ms_va_list*); producing this errors for basically every file:
wine/include/winbase.h:1546:96: error: Expected ) in function declarator wine/include/winbase.h:1546:96: error: got *
wine/include/winbase.h:1547:97: error: Expected ) in function declarator wine/include/winbase.h:1547:97: error: got *

---
 lib.c   |    2 ++
 parse.c |    1 +
 2 files changed, 3 insertions(+), 0 deletions(-)
lib.c +2 -0
index 622b547..cf00c8b 100644
@@ -794,11 +794,13 @@ void create_builtin_stream(void)
 
 	add_pre_buffer("#define __builtin_stdarg_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
 	add_pre_buffer("#define __builtin_va_start(a,b) ((a) = (__builtin_va_list)(&(b)))\n");
+	add_pre_buffer("#define __builtin_ms_va_start(a,b) ((a) = (__builtin_ms_va_list)(&(b)))\n");
 	add_pre_buffer("#define __builtin_va_arg(arg,type)  ({ type __va_arg_ret = *(type *)(arg); arg += sizeof(type); __va_arg_ret; })\n");
 	add_pre_buffer("#define __builtin_va_alist (*(void *)0)\n");
 	add_pre_buffer("#define __builtin_va_arg_incr(x) ((x) + 1)\n");
 	add_pre_buffer("#define __builtin_va_copy(dest, src) ({ dest = src; (void)0; })\n");
 	add_pre_buffer("#define __builtin_va_end(arg)\n");
+	add_pre_buffer("#define __builtin_ms_va_end(arg)\n");
 
 	/* FIXME! We need to do these as special magic macros at expansion time! */
 	add_pre_buffer("#define __BASE_FILE__ \"base_file.c\"\n");
parse.c +1 -0
index c3f9b6a..6ab2ac4 100644
@@ -391,6 +391,7 @@ static struct init_keyword {
 
 	/* Predeclared types */
 	{ "__builtin_va_list", NS_TYPEDEF, .type = &ptr_ctype, .op = &spec_op },
+	{ "__builtin_ms_va_list", NS_TYPEDEF, .type = &ptr_ctype, .op = &spec_op },
 	{ "__int128_t",	NS_TYPEDEF, .type = &lllong_ctype, .op = &spec_op },
 	{ "__uint128_t",NS_TYPEDEF, .type = &ulllong_ctype, .op = &spec_op },
 
Signature · 1 line
1.6.5.rc2
maintainer Applied
#1 lore raw
Quoted 8 lines · Michael Stefaniuc

For Win64 compiles Wine does
 #ifndef __ms_va_list

 # if defined(__x86_64__) && defined (__GNUC__)
 #  define __ms_va_list __builtin_ms_va_list
 #  define __ms_va_start(list,arg) __builtin_ms_va_start(list,arg)
 #  define __ms_va_end(list) __builtin_ms_va_end(list)
 # else
Quoted 8 lines

Wouldn't be as bad if sparse cannot handle those but it trips over
WINBASEAPI DWORD WINAPI FormatMessageA(DWORD,LPCVOID,DWORD,DWORD,LPSTR,DWORD,__ms_va_list*); WINBASEAPI DWORD WINAPI FormatMessageW(DWORD,LPCVOID,DWORD,DWORD,LPWSTR,DWORD,__ms_va_list*); producing this errors for basically every file:
wine/include/winbase.h:1546:96: error: Expected ) in function declarator wine/include/winbase.h:1546:96: error: got *
wine/include/winbase.h:1547:97: error: Expected ) in function declarator wine/include/winbase.h:1547:97: error: got *

Applied.

Thanks

Chris
--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#2 lore raw

Getting info from used typedef

Hello,

I try to get information about a typedef, which was used in a declaration.

For example:

typedef signed short INT;
INT var1;

When i iterate over the symbol_list which is returend by sparse(), I can get the information,
that "var1" was declared using a typedef, this information is held in "symbol->ctype.modifiers".
Can you tell me how I can examine the name of the typedef - "INT", which was used in the declaration?
I'm only able to get the name of the basic datatype, which is "signed short" in this case.

This behaviour has changed in 0.4.2, in former versions the name of a used typedef was stored in the used datatypes ident
(altough the behaviour was erroneous there).

Thanks in advance,
regards,
Thomas

maintainer
#3 lore raw

Re: Getting info from used typedef

Quoted 7 lines · Thomas Schmid

typedef signed short INT;
INT var1;

When i iterate over the symbol_list which is returend by sparse(), I can get the information,
that "var1" was declared using a typedef, this information is held in "symbol->ctype.modifiers".

So far so good.

Quoted 2 lines

Can you tell me how I can examine the name of the typedef - "INT", which was used in the declaration?

I take a look at the current code base, there is no good way to get the typedef from the symbol node. When sparse parse the "INT" token. It will try to lookup it as type define. If it is, sparse directly apply the underlying
ctype, which is "signed short", to var1.

The code does that is in declaration_specifiers() if you are curious. Sparse only use the base type of the user type, as if the declaration is "signed short var1". This make the later process much easier. It is none trivial change to preserve the type define name.

May I ask more back ground information what do you want to do with the type define name? I am trying to find out if there is other easier way to achieve your goal.

Chris

#4 lore raw

Antwort: Re: Getting info from used typedef

[email protected] schrieb am 01.12.2009 00:41:18:

Quoted 4 lines

The code does that is in declaration_specifiers() if you are curious. Sparse only use the base type of the user type, as if the declaration is "signed short var1". This make the later process much easier. It is none trivial change to preserve the type define name.

I see.

Quoted 2 lines

May I ask more back ground information what do you want to do with the type define name? I am trying to find out if there is other

easier

Quoted 1 line

way to achieve your goal.

Of course: I wrote a tool, which converts C-declarations into another format (IEC61131).
These generated declarations are used as a interface to communicate to programs of different languages.
This IEC-format uses datatypes, which are not known in ANSI C, such as the following:

typedef signed long    DINT;
typedef unsigned long  UDINT;
typedef signed long    TIME;
typedef unsigned long  DATE_AND_TIME;

typedef unsigned short UINT;
typedef unsigned short WSTRING;

As you can see, the use of the basetype "unsigned long" for example is not clear.
If I now declare a variable of type TIME and another one of type DINT, I am not able to determine which type was used in the declaration.

I hope this is understandable,

regards,
Thomas

maintainer
#5 lore raw

Re: Re: Getting info from used typedef

Quoted 7 lines · Thomas Schmid

Of course: I wrote a tool, which converts C-declarations into another format (IEC61131).
These generated declarations are used as a interface to communicate to programs of different languages.
This IEC-format uses datatypes, which are not known in ANSI C, such as the following:

Quoted 7 lines

typedef signed long    DINT;
typedef unsigned long  UDINT;
typedef signed long    TIME;
typedef unsigned long  DATE_AND_TIME;
typedef unsigned short UINT;
typedef unsigned short WSTRING;

So you only use sparse as a C source code processing tool. You don't care about the back end part of the sparse right?

In that case, you can try this one line patch. It should preserve the typedef symbol as the base type. I will not commit that to main line though.

Will that work for you?

Chris

From 6f1a577af7d9fa23c9070f278bdab02dbf8fb068 Mon Sep 17 00:00:00 2001
From: Christopher Li <[email protected]>
Date: Tue, 1 Dec 2009 10:38:02 -0800
Subject: [PATCH] hacking preserve typedef name.

---
 parse.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
parse.c +1 -1
index 66b8112..249135b 100644
@@ -1429,7 +1429,7 @@ static struct token *declaration_specifiers(struct token *token, struct decl_sta
 			if (seen & Set_Any)
 				break;
 			seen |= Set_S | Set_T;
-			ctx->ctype.base_type = s->ctype.base_type;
+			ctx->ctype.base_type = s;
 			apply_ctype(token->pos, &s->ctype, &ctx->ctype);
 			token = token->next;
 			continue;
Signature · 1 line
1.6.0.6
#6 lore raw

Re: Re: Re: Getting info from used typedef

[email protected] schrieb am 01.12.2009 19:49:18:

Quoted 2 lines

So you only use sparse as a C source code processing tool. You don't care about the back end part of the sparse right?

Yes, that's right.

Quoted 1 line

In that case, you can try this one line patch. It should preserve the

typedef

Quoted 3 lines

symbol as the base type. I will not commit that to main line though.

Will that work for you?

Thank you, but I'm sorry, that patch doesn't work for me.
The output is the same as before, the base_type of the symbol doesn't have an ident.

I'm surprised that the base_type had an ident in former versions of sparse

(which didn't also work correctly - I tried to figure out something in the past, see
http://marc.info/?l=linux-sparse&m=118171213001092&w=2
), but now this has changed.

In former versions of sparse, this code gave output, even tough it was incorrect:
("sym" is a "struct symbol*" of the symlist returned by sparse() )

        struct symbol *type;
        type = sym->ctype.base_type;
 
        if (type->ident)
        {
                if (sym->ctype.modifiers & MOD_USERTYPE) 
                        fprintf(pFOut, "Typedef=\"%s\" ", 
type->ident->name);
        } 

I tried to compare the function "declaration_specifiers" from sparse 0.4.1 and 0.4.2.
The function changed a lot, but I don't understand the changes.

Is it really not necessary for compilers (or frontends) to hold the information about declarations with typedefs?

Regards,
Thomas

maintainer
#7 lore raw

Re: Re: Re: Getting info from used typedef

Quoted 2 lines · Thomas Schmid

Thank you, but I'm sorry, that patch doesn't work for me.

I took another look into it. I think if you are just working on the source code transform,
you should be able to skip the evaluation step which short cut the typedef.

Can you try again with the same patch, but in your program, using __sparse(filename)
instead of sparse(filename) to get the symbols? Using __sparse will skip the evaluation step. It should keep the typedef node unchanged.

Quoted 2 lines

Is it really not necessary for compilers (or frontends) to hold the information about declarations with typedefs?

The back end only care about the type, not the name of type. In fact, C type system need to evaluation the type to get ride of the alias so it will not complain type mismatch due to typedef.

Chris

#8 lore raw

Re: Re: Re: Re: Getting info from used typedef

[email protected] schrieb am 21.01.2010 01:38:09:

Quoted 3 lines

I took another look into it. I think if you are just working on the source code transform,
you should be able to skip the evaluation step which short cut the

typedef.

Quoted 4 lines

Can you try again with the same patch, but in your program, using __sparse(filename)
instead of sparse(filename) to get the symbols? Using __sparse will skip

the

Quoted 1 line

evaluation step. It should keep the typedef node unchanged.

Yes, that seems to help, thank you very much.
I think because of the missing evaluation step, it is now a little bit more tricky
to get out the elements of an struct or enum, but it will work. Do I lose anything else, skipping the evaluation step?

Is it possible to commit your change ( 0001-hacking-preserve-typedef-name.patch) in source?
- I didn't recognize any change in behaviour when using the function sparse().

Regards
Tom

maintainer
#9 lore raw

Re: Re: Re: Re: Getting info from used typedef

Quoted 6 lines · Thomas Schmid

Yes, that seems to help, thank you very much.
I think because of the missing evaluation step, it is now a little bit more tricky
to get out the elements of an struct or enum, but it will work. Do I lose anything else, skipping the evaluation step?

You don't have the type evaluation. I don't think your source code transform program
cares.

Quoted 5 lines

Is it possible to commit your change ( 0001-hacking-preserve-typedef-name.patch) in source?
- I didn't recognize any change in behaviour when using the function sparse().

How about make it an hidden options? It does not make sense for compiler to care about the typedef name. I will send out a review later.

Chris

#10 lore raw

Re: Re: Re: Re: Re: Getting info from used typedef

[email protected] schrieb am 29.01.2010 02:21:18:

Quoted 8 lines

Christopher Li <[email protected]>

Quoted 4 lines

Is it possible to commit your change ( 0001-hacking-preserve-typedef-name.patch) in source?
- I didn't recognize any change in behaviour when using the function sparse().

How about make it an hidden options? It does not make sense for compiler to care about the typedef name. I will send out a review later.

Sounds good to me.

Regards
Thomas