Index: gcc/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

	* Makefile.in (CPPLIB_H): Put files in order of inclusion.
	(CPP_ID_DATA_H): New.
	(gtype-desc.o): Update dependencies.
	(GTFILES): Use CPP_ID_DATA_H.

Index: gcc/testsuite/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

	* gcc.dg/pch/macro-4.c: New.
	* gcc.dg/pch/macro-4.hs: New.

Index: libcpp/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

	* traditional.c (push_replacement_text): Set macro->traditional.
	(save_replacement_text): Likewise.
	* pch.c (cpp_write_pch_state): Don't write list of defined macros.
	(struct save_macro_item): Delete.
	(struct save_macro_data): Use a character array not the previous
	structured format.
	(save_macros): Save macro as text not as internal structures.
	(cpp_prepare_state): Update for changes to save_macro_data.
	(cpp_read_state): Don't read macros defined in PCH.  Restore
	-D macros as text.
	* macro.c (create_iso_definition): Honour alloc_subobject.
	Clear traditional flag.
	(_cpp_create_definition): Honour alloc_subobject.
	* lex.c (cpp_token_val_index): New.
	* internal.h: Include cpp-id-data.h.
	(uchar): Move definition to cpp-id-data.h.
	(U): Likewise.
	(cpp_macro): Likewise.
	* directives.c (struct answer): Move to cpp-id-data.h.
	(do_assert): Honour alloc_subobject.

Index: libcpp/include/ChangeLog
2004-06-09  Geoffrey Keating  <geoffk@apple.com>

	* symtab.h (struct ht): Add field 'alloc_subobject'.
	* cpplib.h (struct cpp_string): Add GTY marker.
	(enum cpp_token_fld_kind): New.
	(struct cpp_token): Add GTY markers.
	(cpp_token_val_index): Prototype.
	(CPP_HASHNODE_VALUE_IDX): New.
	(struct cpp_hashnode): Don't skip fields of 'value' when marking.
	* cpp-id-data.h: New file.

From-SVN: r82851
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index cf701b5..dab3157 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -156,7 +156,7 @@
 	     CLK_GNUCXX, CLK_CXX98, CLK_ASM};
 
 /* Payload of a NUMBER, STRING, CHAR or COMMENT token.  */
-struct cpp_string
+struct cpp_string GTY(())
 {
   unsigned int len;
   const unsigned char *text;
@@ -171,23 +171,48 @@
 #define NO_EXPAND	(1 << 5) /* Do not macro-expand this token.  */
 #define BOL		(1 << 6) /* Token at beginning of line.  */
 
+/* Specify which field, if any, of the cpp_token union is used.  */
+
+enum cpp_token_fld_kind {
+  CPP_TOKEN_FLD_NODE,
+  CPP_TOKEN_FLD_SOURCE,
+  CPP_TOKEN_FLD_STR,
+  CPP_TOKEN_FLD_ARG_NO,
+  CPP_TOKEN_FLD_NONE
+};
+
 /* A preprocessing token.  This has been carefully packed and should
    occupy 16 bytes on 32-bit hosts and 24 bytes on 64-bit hosts.  */
-struct cpp_token
+struct cpp_token GTY(())
 {
   source_location src_loc;	/* Location of first char of token.  */
   ENUM_BITFIELD(cpp_ttype) type : CHAR_BIT;  /* token type */
   unsigned char flags;		/* flags - see above */
 
-  union
+  union cpp_token_u
   {
-    cpp_hashnode *node;		/* An identifier.  */
-    const cpp_token *source;	/* Inherit padding from this token.  */
-    struct cpp_string str;	/* A string, or number.  */
-    unsigned int arg_no;	/* Argument no. for a CPP_MACRO_ARG.  */
-  } val;
+    /* An identifier.  */
+    cpp_hashnode *
+      GTY ((nested_ptr (union tree_node,
+		"%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
+			"%h ? HT_IDENT_TO_GCC_IDENT (HT_NODE (%h)) : NULL"),
+	    tag ("CPP_TOKEN_FLD_NODE")))
+	 node;
+	 
+    /* Inherit padding from this token.  */
+    cpp_token * GTY ((tag ("CPP_TOKEN_FLD_SOURCE"))) source;
+
+    /* A string, or number.  */
+    struct cpp_string GTY ((tag ("CPP_TOKEN_FLD_STR"))) str;
+
+    /* Argument no. for a CPP_MACRO_ARG.  */
+    unsigned int GTY ((tag ("CPP_TOKEN_FLD_ARG_NO"))) arg_no;
+  } GTY ((desc ("cpp_token_val_index (&%1)"))) val;
 };
 
+/* Say which field is in use.  */
+extern enum cpp_token_fld_kind cpp_token_val_index (cpp_token *tok);
+
 /* A type wide enough to hold any multibyte source character.
    cpplib's character constant interpreter requires an unsigned type.
    Also, a typedef for the signed equivalent.
@@ -498,6 +523,23 @@
 #define NODE_LEN(NODE)		HT_LEN (&(NODE)->ident)
 #define NODE_NAME(NODE)		HT_STR (&(NODE)->ident)
 
+/* Specify which field, if any, of the union is used.  */
+
+enum {
+  NTV_MACRO,
+  NTV_ANSWER,
+  NTV_BUILTIN,
+  NTV_ARGUMENT,
+  NTV_NONE
+};
+
+#define CPP_HASHNODE_VALUE_IDX(HNODE)				\
+  ((HNODE.flags & NODE_MACRO_ARG) ? NTV_ARGUMENT		\
+   : HNODE.type == NT_MACRO ? ((HNODE.flags & NODE_BUILTIN) 	\
+			       ? NTV_BUILTIN : NTV_MACRO)	\
+   : HNODE.type == NT_ASSERTION ? NTV_ANSWER			\
+   : NTV_NONE)
+
 /* The common part of an identifier node shared amongst all 3 C front
    ends.  Also used to store CPP identifiers, which are a superset of
    identifiers in the grammatical sense.  */
@@ -515,14 +557,14 @@
   union _cpp_hashnode_value
   {
     /* If a macro.  */
-    cpp_macro * GTY((skip)) macro;
+    cpp_macro * GTY((tag ("NTV_MACRO"))) macro;
     /* Answers to an assertion.  */
-    struct answer * GTY ((skip)) answers;
+    struct answer * GTY ((tag ("NTV_ANSWER"))) answers;
     /* Code for a builtin macro.  */
-    enum builtin_type GTY ((tag ("1"))) builtin;
+    enum builtin_type GTY ((tag ("NTV_BUILTIN"))) builtin;
     /* Macro argument index.  */
-    unsigned short GTY ((tag ("0"))) arg_index;
-  } GTY ((desc ("0"))) value;
+    unsigned short GTY ((tag ("NTV_ARGUMENT"))) arg_index;
+  } GTY ((desc ("CPP_HASHNODE_VALUE_IDX (%1)"))) value;
 };
 
 /* Call this first to get a handle to pass to other functions.