  /**
   * Tags and typedefs
   */

  #define ILLEGAL 0


  /*
   * Declare a structure type, with 'tag1' in the
   * tag namespace
   */
  struct tag1;


  #if ILLEGAL
  /*
   * Cannot use the tag again with a union type,
   * because 'tag1' is already in the tag namespace
   * as a structure tag
   */
  union tag1;

  #endif


  /*
   * Redeclare the same structure type as before
   * and complete the definition of the type
   */
  struct tag1 {
      int i;
      double d;
    };


  /*
   * Declare a structure type, a tag, and an object.
   * (Note that 'obj1' is a pointer, not a 'struct tag2')
   */
  struct tag2 * obj1;


  #if ILLEGAL
  /*
   * Cannot redeclare the tag, for the same reason
   * as before
   */
  union tag2 * obj2;

  #endif


  /* Redeclare the tag2 structure type and complete it */
  struct tag2 {
      int j;
      double e;
    };


  /*
   * Declare a union type, its tag, complete the type,
   * declare an object of that type
   */
  union tag3 {
      short k;
      float f;
    } obj3;


  /*
   * The tag namespace and the ordinary namespace
   * are different, so there's no conflict, below.
   * There is an 'id4' union type tag, and an 'id4'
   * object
   */
  union id4 {
      long l;
      float g;
    } id4;


  #if ILLEGAL
  /*
   * But 'int' isn't a tag, so it's in the ordinary
   * namespace and this is a conflict
   */
  int int;

  #endif


  /* Declare a new structure type, with a tag */
  struct tag5;


  /*
   * Redeclare that structure type and define an
   * alias for that type
   */
  typedef struct tag5 alias5;


  /* These two objects have the same pointer type */
  struct tag5 * obj5a;
  alias5 * obj5b;


  /* Another structure type, completed */
  struct tag6 {
      int m;
      double h;
    };


  /* Another typedef */
  typedef struct tag6 alias6;


  /* These objects have the same type */
  struct tag6 obj6a;
  alias6 obj6b;


  /* Declare a structure type and a type-name alias */
  typedef struct tag7 alias7;


  /* These two have the same pointer type */
  struct tag7 * obj7a;
  alias7 * obj7b;


  /* Complete the structure type */
  struct tag7 {
      int n;
      double d;
    };


  /* Now we can declare objects of that complete type */
  struct tag7 obj8a;
  alias7 obj8b;


  /*
   * Type-name aliases are not in the tag namespace, so
   * there is no conflict, below
   */
  struct type9;
  typedef struct type9 type9;


  /* Complete the type */
  struct type9 {
      int o;
      double e;
    };


  /* These have the same type */
  struct type9 obj9a;
  type9 obj9b;


  /*
   * Declare a structure type with its tag, complete it,
   * establish a type-name alias
   */
  typedef struct type10 {
      int p;
      float f;
    } type10;


  /* These have the same type */
  struct type10 obj10a;
  type10 obj10b;


  /*
   * Declare a tagless structure type and an object
   * of that type
   */
  struct {
      int q;
      float g;
    } obj11;


  /*
   * Declare a tagless structure type and establish a
   * type-name alias for that type
   */
  typedef struct {
      int r;
      short h;
    } type12;


  int main(void) { return 0; }
