Tiny patch for va_list definition on x86-64 target

Here attached you find a patch that add and intermediate typedef between
struct __va_list_tag and __builtin_va_list on x86-64.

This patch is fundamental in our project to recompile with gcc a pretty
printed output of clang AST.

The fact is that until __builtin_va_list is an array of struct
__va_list_tag, it decays to struct __va_list_tag * that is a type that
it's impossibile to match with gcc internal type.

With this patch, instead, va_list decays to __va_list_tag_t* that is
easily mappable to gcc internal type for va_list.

To make it match it's only needed to do the following:

/*
typedef struct __va_list_tag {
  unsigned int gp_offset;
  unsigned int fp_offset;
  void *overflow_arg_area;
  void *reg_save_area;
} __va_list_tag_t;
typedef __va_list_tag_t __builtin_va_list[1];
*/
extern __builtin_va_list __va_list_object;
typedef typeof(__va_list_object[0]) __va_list_tag_t;

i.e., we remove the two declarations added by clang and we substitute
them with other two that permit the pretty printed clang AST to be
compiled without other modifications.

For all the other uses of va_list the proposed patch is harmless (the
type of __builtin_va_list remains the same).

va_list.patch (488 Bytes)

Here attached you find a patch that add and intermediate typedef between
struct __va_list_tag and __builtin_va_list on x86-64.

This patch is fundamental in our project to recompile with gcc a pretty
printed output of clang AST.

Hmm... if the user never writes "struct __va_list_tag" explicitly, it
should never show up in the pretty-printed output. In what situations
is this an issue?

With this patch, instead, va_list decays to __va_list_tag_t* that is
easily mappable to gcc internal type for va_list.

Why __va_list_tag_t instead of __va_list_tag (which is what gcc uses)?

Otherwise, the patch looks fine.

-Eli

- implicit casts:

va_list ap;
va_start(ap, fmt);
int i = va_arg(ap, fmt);

becomes:

va_list ap;
__builtin_va_start((struct __va_list_tag*)(ap), fmt);
int i = __builtin_va_arg((struct __va_list_tag*)(ap), int);

- function types:

int (*fun)(const char *fmt, va_list args);

becomes:

int (*fun)(const char *, struct __va_list_tag*);

Neither of these examples prints in the indicated way using clang-cc
-ast-print, but I guess you're using some customized code?

With this patch, instead, va_list decays to __va_list_tag_t* that is
easily mappable to gcc internal type for va_list.

Why __va_list_tag_t instead of __va_list_tag (which is what gcc uses)?

Just to have a different name for struct tag and typedef name, but
perhaps this does not give anything.

Here attached you can find a patch where it's used the same name.

Otherwise, the patch looks fine.

Perfect, thanks for the review.

Committed in r74752.

-Eli

Eli Friedman ha scritto: