emit: Handle typedefs that are a pointer to typedefs

Before:

  $ pfunct --compile /home/acme/git/build/v5.1-rc4+/kernel/sched/autogroup.o > a.c
  $ gcc -g -c a.c
  a.c:1656:9: error: unknown type name ‘__signalfn_t’
   typedef __signalfn_t * __sighandler_t;
           ^~~~~~~~~~~~
  a.c:1658:9: error: unknown type name ‘__restorefn_t’
   typedef __restorefn_t * __sigrestore_t;
           ^~~~~~~~~~~~~
  $

After:

  $ pfunct --compile /home/acme/git/build/v5.1-rc4+/kernel/sched/autogroup.o > a.c
  $ gcc -g -c a.c
  $ egrep  '__(restore|signal)fn_t' -A10 a.c
  typedef void (__signalfn_t)(int);
  typedef __signalfn_t * __sighandler_t;

  typedef void (__restorefn_t)(void);
  typedef __restorefn_t * __sigrestore_t;

  struct sigaction {
	  __sighandler_t             sa_handler;           /*     0     8 */
	  long unsigned int          sa_flags;             /*     8     8 */
	  __sigrestore_t             sa_restorer;          /*    16     8 */
	  sigset_t                   sa_mask;              /*    24     8 */

	  /* size: 32, cachelines: 1, members: 4 */
	  /* last cacheline: 32 bytes */
  };
  $

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2019-04-16 13:49:29 -03:00
parent 87af9839bf
commit 05921c47f5
1 changed files with 6 additions and 1 deletions

View File

@ -138,7 +138,12 @@ static int typedef__emit_definitions(struct tag *tdef, struct cu *cu,
case DW_TAG_pointer_type:
ptr_type = cu__type(cu, type->type);
/* void ** can make ptr_type be NULL */
if (ptr_type == NULL || ptr_type->tag != DW_TAG_subroutine_type)
if (ptr_type == NULL)
break;
if (ptr_type->tag == DW_TAG_typedef) {
typedef__emit_definitions(ptr_type, cu, emissions, fp);
break;
} else if (ptr_type->tag != DW_TAG_subroutine_type)
break;
type = ptr_type;
is_pointer = 1;