Replace line_map union with C++ class hierarchy

gcc/ChangeLog:
	* diagnostic.c (diagnostic_report_current_module): Strengthen
	local "new_map" from const line_map * to
	const line_map_ordinary *.
	* genmatch.c (error_cb): Likewise for local "map".
	(output_line_directive): Likewise for local "map".
	* input.c (expand_location_1): Likewise for local "map".
	Pass NULL rather than &map to
	linemap_unwind_to_first_non_reserved_loc, since the value is never
	read from there, and the value written back not read from here.
	(is_location_from_builtin_token): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	(dump_location_info): Strengthen locals "map" from
	line_map *, one to const line_map_ordinary *, the other
	to const line_map_macro *.
	* tree-diagnostic.c (loc_map_pair): Strengthen field "map" from
	const line_map * to const line_map_macro *.
	(maybe_unwind_expanded_macro_loc): Add a call to
	linemap_check_macro when writing to the "map" field of the
	loc_map_pair.
	Introduce local const line_map_ordinary * "ord_map", using it in
	place of "map" in the part of the function where we know we have
	an ordinary map.  Strengthen local "m" from const line_map * to
	const line_map_ordinary *.

gcc/ada/ChangeLog:
	* gcc-interface/trans.c (Sloc_to_locus1): Strenghthen local "map"
	from line_map * to line_map_ordinary *.

gcc/c-family/ChangeLog:
	* c-common.h (fe_file_change): Strengthen param from
	const line_map * to const line_map_ordinary *.
	(pp_file_change): Likewise.
	* c-lex.c (fe_file_change): Likewise.
	(cb_define): Use linemap_check_ordinary when invoking
	SOURCE_LINE.
	(cb_undef): Likewise.
	* c-opts.c (c_finish_options): Use linemap_check_ordinary when
	invoking cb_file_change.
	(c_finish_options): Likewise.
	(push_command_line_include): Likewise.
	(cb_file_change): Strengthen param "new_map" from
	const line_map * to const line_map_ordinary *.
	* c-ppoutput.c (cb_define): Likewise for local "map".
	(pp_file_change): Likewise for param "map" and local "from".

gcc/fortran/ChangeLog:
	* cpp.c (maybe_print_line): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	(cb_file_change): Likewise for param "map" and local "from".
	(cb_line_change): Likewise for local "map".

libcpp/ChangeLog:
	* directives.c (do_line): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	(do_linemarker): Likewise.
	(_cpp_do_file_change): Assert that we're not dealing with
	a macro map.  Introduce local "ord_map" via a call to
	linemap_check_ordinary, guarded within the check for
	non-NULL.  Use it for typesafety.
	* files.c (cpp_make_system_header): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	* include/cpplib.h (struct cpp_callbacks): Likewise for second
	parameter of "file_change" callback.
	* include/line-map.h (struct line_map): Convert from a struct
	containing a union to a base class.
	(struct line_map_ordinary): Convert to a subclass of line_map.
	(struct line_map_macro): Likewise.
	(linemap_check_ordinary): Strengthen return type from line_map *
	to line_map_ordinary *, and add a const-variant.
	(linemap_check_macro): New pair of functions.
	(ORDINARY_MAP_STARTING_LINE_NUMBER): Strengthen param from
	const line_map * to const line_map_ordinary *, eliminating call
	to linemap_check_ordinary.  Likewise for the non-const variant.
	(ORDINARY_MAP_INCLUDER_FILE_INDEX): Likewise.
	(ORDINARY_MAP_IN_SYSTEM_HEADER_P): Likewise.
	(ORDINARY_MAP_NUMBER_OF_COLUMN_BITS): Likewise.
	(ORDINARY_MAP_FILE_NAME): Likewise.
	(MACRO_MAP_MACRO): Strengthen param from const line_map * to
	const line_map_macro *.  Likewise for the non-const variant.
	(MACRO_MAP_NUM_MACRO_TOKENS): Likewise.
	(MACRO_MAP_LOCATIONS): Likewise.
	(MACRO_MAP_EXPANSION_POINT_LOCATION): Likewise.
	(struct maps_info): Replace with...
	(struct maps_info_ordinary):...this and...
	(struct maps_info_macro): ...this.
	(struct line_maps): Convert fields "info_ordinary" and
	"info_macro" to the above new structs.
	(LINEMAPS_MAP_INFO): Delete both functions.
	(LINEMAPS_MAPS): Likewise.
	(LINEMAPS_ALLOCATED): Rewrite both variants to avoid using
	LINEMAPS_MAP_INFO.
	(LINEMAPS_USED): Likewise.
	(LINEMAPS_CACHE): Likewise.
	(LINEMAPS_MAP_AT): Likewise.
	(LINEMAPS_ORDINARY_MAPS): Strengthen return type from line_map *
	to line_map_ordinary *.
	(LINEMAPS_ORDINARY_MAP_AT): Likewise.
	(LINEMAPS_LAST_ORDINARY_MAP): Likewise.
	(LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP): Likewise.
	(LINEMAPS_MACRO_MAPS): Strengthen return type from line_map * to
	line_map_macro *.
	(LINEMAPS_MACRO_MAP_AT): Likewise.
	(LINEMAPS_LAST_MACRO_MAP): Likewise.
	(LINEMAPS_LAST_ALLOCATED_MACRO_MAP): Likewise.
	(linemap_map_get_macro_name): Strengthen param from
	const line_map * to const line_map_macro *.
	(SOURCE_LINE): Strengthen first param from const line_map * to
	const line_map_ordinary *, removing call to
	linemap_check_ordinary.
	(SOURCE_COLUMN): Likewise.
	(LAST_SOURCE_LINE_LOCATION): Likewise.
	(LAST_SOURCE_LINE): Strengthen first param from const line_map *
	to const line_map_ordinary *.
	(LAST_SOURCE_COLUMN): Likewise.
	(INCLUDED_FROM): Strengthen return type from line_map * to
	line_map_ordinary *., and second param from const line_map *
	to const line_map_ordinary *, removing call to
	linemap_check_ordinary.
	(MAIN_FILE_P): Strengthen param from const line_map * to
	const line_map_ordinary *, removing call to
	linemap_check_ordinary.
	(linemap_position_for_line_and_column): Strengthen param from
	const line_map * to const line_map_ordinary *.
	(LINEMAP_FILE): Strengthen param from const line_map * to
	const line_map_ordinary *, removing call to
	linemap_check_ordinary.
	(LINEMAP_LINE): Likewise.
	(LINEMAP_SYSP): Likewise.
	(linemap_resolve_location): Strengthen final param from
	const line_map ** to const line_map_ordinary **.
	* internal.h (CPP_INCREMENT_LINE): Likewise for local "map".
	(linemap_enter_macro): Strengthen return type from
	const line_map * to const line_map_macro *.
	(linemap_add_macro_token): Likewise for first param.
	* line-map.c (linemap_check_files_exited): Strengthen local "map"
	from const line_map * to const line_map_ordinary *.
	(new_linemap): Introduce local "map_size" and use it when
	calculating how large the buffer should be.  Rewrite based
	on change of info_macro and info_ordinary into distinct types.
	(linemap_add): Strengthen locals "map" and "from" from line_map *
	to line_map_ordinary *.
	(linemap_enter_macro): Strengthen return type from
	const line_map * to const line_map_macro *, and local "map" from
	line_map * to line_map_macro *.
	(linemap_add_macro_token): Strengthen param "map" from
	const line_map * to const line_map_macro *.
	(linemap_line_start): Strengthen local "map" from line_map * to
	line_map_ordinary *.
	(linemap_position_for_column): Likewise.
	(linemap_position_for_line_and_column): Strengthen first param
	from const line_map * to const line_map_ordinary *.
	(linemap_position_for_loc_and_offset): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	(linemap_ordinary_map_lookup): Likewise for return type and locals
	"cached" and "result".
	(linemap_macro_map_lookup): Strengthen return type and locals
	"cached" and "result" from const line_map * to
	const line_map_macro *.
	(linemap_macro_map_loc_to_exp_point): Likewise for param "map".
	(linemap_macro_map_loc_to_def_point): Likewise.
	(linemap_macro_map_loc_unwind_toward_spelling): Likewise.
	(linemap_get_expansion_line): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	(linemap_get_expansion_filename): Likewise.
	(linemap_map_get_macro_name): Strengthen param from
	const line_map * to const line_map_macro *.
	(linemap_location_in_system_header_p): Add call to
	linemap_check_ordinary in region guarded by
	!linemap_macro_expansion_map_p.  Introduce local "macro_map" via
	linemap_check_macro in other region, using it in place of "map"
	for typesafety.
	(first_map_in_common_1): Add calls to linemap_check_macro.
	(trace_include): Strengthen param "map" from const line_map * to
	const line_map_ordinary *.
	(linemap_macro_loc_to_spelling_point): Strengthen final param from
	const line_map ** to const line_map_ordinary **.  Replace a
	C-style cast with a const_cast, and add calls to
	linemap_check_macro and linemap_check_ordinary.
	(linemap_macro_loc_to_def_point): Likewise.
	(linemap_macro_loc_to_exp_point): Likewise.
	(linemap_resolve_location): Strengthen final param from
	const line_map ** to const line_map_ordinary **.
	(linemap_unwind_toward_expansion): Introduce local "macro_map" via
	a checked cast and use it in place of *map.
	(linemap_unwind_to_first_non_reserved_loc): Strengthen local
	"map1" from const line_map * to const line_map_ordinary *.
	(linemap_expand_location): Introduce local "ord_map" via a checked
	cast and use it in place of map.
	(linemap_dump): Make local "map" const.  Strengthen local
	"includer_map" from line_map * to const line_map_ordinary *.
	Introduce locals "ord_map" and "macro_map" via checked casts and
	use them in place of "map" for typesafety.
	(linemap_dump_location): Strengthen local "map" from
	const line_map * to const line_map_ordinary *.
	(linemap_get_file_highest_location): Update for elimination of
	union.
	(linemap_get_statistics): Strengthen local "cur_map" from
	line_map * to const line_map_macro *.  Update uses of sizeof to
	use the appropriate line_map subclasses.
	* macro.c (_cpp_warn_if_unused_macro): Add call to
	linemap_check_ordinary.
	(builtin_macro): Strengthen local "map" from const line_map * to
	const line_map_macro *.
	(enter_macro_context): Likewise.
	(replace_args): Likewise.
	(tokens_buff_put_token_to): Likewise for param "map".
	(tokens_buff_add_token): Likewise.

From-SVN: r223365
diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
index 0152ec8..1b1a53c 100644
--- a/libcpp/include/cpplib.h
+++ b/libcpp/include/cpplib.h
@@ -549,7 +549,7 @@
      The line_map is for the new file.  It is NULL if there is no new file.
      (In C this happens when done with <built-in>+<command line> and also
      when done with a main file.)  This can be used for resource cleanup.  */
-  void (*file_change) (cpp_reader *, const struct line_map *);
+  void (*file_change) (cpp_reader *, const line_map_ordinary *);
 
   void (*dir_change) (cpp_reader *, const char *);
   void (*include) (cpp_reader *, source_location, const unsigned char *,
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 27aa094..5c04945 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -125,6 +125,39 @@
    for a given requested allocation.  */
 typedef size_t (*line_map_round_alloc_size_func) (size_t);
 
+/* A line_map encodes a sequence of locations.
+   There are two kinds of maps. Ordinary maps and macro expansion
+   maps, a.k.a macro maps.
+
+   A macro map encodes source locations of tokens that are part of a
+   macro replacement-list, at a macro expansion point. E.g, in:
+
+            #define PLUS(A,B) A + B
+
+   No macro map is going to be created there, because we are not at a
+   macro expansion point. We are at a macro /definition/ point. So the
+   locations of the tokens of the macro replacement-list (i.e, A + B)
+   will be locations in an ordinary map, not a macro map.
+
+   On the other hand, if we later do:
+
+        int a = PLUS (1,2);
+
+   The invocation of PLUS here is a macro expansion. So we are at a
+   macro expansion point. The preprocessor expands PLUS (1,2) and
+   replaces it with the tokens of its replacement-list: 1 + 2. A macro
+   map is going to be created to hold (or rather to map, haha ...) the
+   locations of the tokens 1, + and 2. The macro map also records the
+   location of the expansion point of PLUS. That location is mapped in
+   the map that is active right before the location of the invocation
+   of PLUS.  */
+struct GTY((tag ("0"), desc ("%h.reason == LC_ENTER_MACRO ? 2 : 1"))) line_map {
+  source_location start_location;
+
+  /* The reason for creation of this line map.  */
+  ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
+};
+
 /* An ordinary line map encodes physical source locations. Those
    physical source locations are called "spelling locations".
    
@@ -136,7 +169,7 @@
    means "entire file/line" or "unknown line/column" or "not applicable".)
 
    The highest possible source location is MAX_SOURCE_LOCATION.  */
-struct GTY(()) line_map_ordinary {
+struct GTY((tag ("1"))) line_map_ordinary : public line_map {
   const char *to_file;
   linenum_type to_line;
 
@@ -164,13 +197,9 @@
 /* A macro line map encodes location of tokens coming from a macro
    expansion.
    
-   Please note that this struct line_map_macro is a field of struct
-   line_map below, go read the comments of struct line_map below and
-   then come back here.
-   
    The offset from START_LOCATION is used to index into
    MACRO_LOCATIONS; this holds the original location of the token.  */
-struct GTY(()) line_map_macro {
+struct GTY((tag ("2"))) line_map_macro : public line_map {
   /* The cpp macro which expansion gave birth to this macro map.  */
   struct cpp_hashnode * GTY ((nested_ptr (union tree_node,
 				   "%h ? CPP_HASHNODE (GCC_IDENT_TO_HT_IDENT (%h)) : NULL",
@@ -243,44 +272,6 @@
   source_location expansion;
 };
 
-/* A line_map encodes a sequence of locations.
-   There are two kinds of maps. Ordinary maps and macro expansion
-   maps, a.k.a macro maps.
-
-   A macro map encodes source locations of tokens that are part of a
-   macro replacement-list, at a macro expansion point. E.g, in:
-
-            #define PLUS(A,B) A + B
-
-   No macro map is going to be created there, because we are not at a
-   macro expansion point. We are at a macro /definition/ point. So the
-   locations of the tokens of the macro replacement-list (i.e, A + B)
-   will be locations in an ordinary map, not a macro map.
-
-   On the other hand, if we later do:
-
-        int a = PLUS (1,2);
-
-   The invocation of PLUS here is a macro expansion. So we are at a
-   macro expansion point. The preprocessor expands PLUS (1,2) and
-   replaces it with the tokens of its replacement-list: 1 + 2. A macro
-   map is going to be created to hold (or rather to map, haha ...) the
-   locations of the tokens 1, + and 2. The macro map also records the
-   location of the expansion point of PLUS. That location is mapped in
-   the map that is active right before the location of the invocation
-   of PLUS.  */
-struct GTY(()) line_map {
-  source_location start_location;
-
-  /* The reason for creation of this line map.  */
-  ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
-
-  union map_u {
-    struct line_map_ordinary GTY((tag ("0"))) ordinary;
-    struct line_map_macro GTY((tag ("1"))) macro;
-  } GTY((desc ("%1.reason == LC_ENTER_MACRO"))) d;
-};
-
 #if defined ENABLE_CHECKING && (GCC_VERSION >= 2007)
 
 /* Assertion macro to be used in line-map code.  */
@@ -312,22 +303,44 @@
 linemap_macro_expansion_map_p (const struct line_map *);
 
 /* Assert that MAP encodes locations of tokens that are not part of
-   the replacement-list of a macro expansion.  */
-inline struct line_map *
+   the replacement-list of a macro expansion, downcasting from
+   line_map * to line_map_ordinary *.  */
+
+inline line_map_ordinary *
 linemap_check_ordinary (struct line_map *map)
 {
   linemap_assert (!linemap_macro_expansion_map_p (map));
-  return map;
+  return (line_map_ordinary *)map;
 }
 
 /* Assert that MAP encodes locations of tokens that are not part of
-   the replacement-list of a macro expansion.  */
+   the replacement-list of a macro expansion, downcasting from
+   const line_map * to const line_map_ordinary *.  */
 
-inline const struct line_map *
+inline const line_map_ordinary *
 linemap_check_ordinary (const struct line_map *map)
 {
   linemap_assert (!linemap_macro_expansion_map_p (map));
-  return map;
+  return (const line_map_ordinary *)map;
+}
+
+/* Assert that MAP is a macro expansion and downcast to the appropriate
+   subclass.  */
+
+inline line_map_macro *linemap_check_macro (line_map *map)
+{
+  linemap_assert (linemap_macro_expansion_map_p (map));
+  return (line_map_macro *)map;
+}
+
+/* Assert that MAP is a macro expansion and downcast to the appropriate
+   subclass.  */
+
+inline const line_map_macro *
+linemap_check_macro (const line_map *map)
+{
+  linemap_assert (linemap_macro_expansion_map_p (map));
+  return (const line_map_macro *)map;
 }
 
 /* Read the start location of MAP, as an rvalue.  */
@@ -350,18 +363,18 @@
 /* Get the starting line number of ordinary map MAP.  */
 
 inline linenum_type
-ORDINARY_MAP_STARTING_LINE_NUMBER (const line_map *map)
+ORDINARY_MAP_STARTING_LINE_NUMBER (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.to_line;
+  return ord_map->to_line;
 }
 
 /* Access the starting line number of ordinary map MAP by
    reference (e.g. as an lvalue).  */
 
 inline linenum_type&
-ORDINARY_MAP_STARTING_LINE_NUMBER (line_map *map)
+ORDINARY_MAP_STARTING_LINE_NUMBER (line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.to_line;
+  return ord_map->to_line;
 }
 
 /* Get the index of the ordinary map at whose end
@@ -370,17 +383,17 @@
    File(s) at the bottom of the include stack have this set.  */
 
 inline int
-ORDINARY_MAP_INCLUDER_FILE_INDEX (const line_map *map)
+ORDINARY_MAP_INCLUDER_FILE_INDEX (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.included_from;
+  return ord_map->included_from;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline int&
-ORDINARY_MAP_INCLUDER_FILE_INDEX (line_map *map)
+ORDINARY_MAP_INCLUDER_FILE_INDEX (line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.included_from;
+  return ord_map->included_from;
 }
 
 /* Return a positive value if map encodes locations from a system
@@ -389,129 +402,147 @@
    that therefore needs to be extern "C" protected in C++.  */
 
 inline unsigned char
-ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map *map)
+ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.sysp;
+  return ord_map->sysp;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline unsigned char &
-ORDINARY_MAP_IN_SYSTEM_HEADER_P (line_map *map)
+ORDINARY_MAP_IN_SYSTEM_HEADER_P (line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.sysp;
+  return ord_map->sysp;
 }
 
 /* Get the number of the low-order source_location bits used for a
    column number within ordinary map MAP.  */
 
 inline unsigned char
-ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (const line_map *map)
+ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.column_bits;
+  return ord_map->column_bits;
 }
 
 /* Set the number of the low-order source_location bits used for a
    column number within ordinary map MAP.  */
 
 inline void
-SET_ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (line_map *map, int col_bits)
+SET_ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (line_map_ordinary *ord_map,
+					int col_bits)
 {
-  linemap_check_ordinary (map)->d.ordinary.column_bits = col_bits;
+  ord_map->column_bits = col_bits;
 }
 
 /* Get the filename of ordinary map MAP.  */
 
 inline const char *
-ORDINARY_MAP_FILE_NAME (const line_map *map)
+ORDINARY_MAP_FILE_NAME (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.to_file;
+  return ord_map->to_file;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline const char * &
-ORDINARY_MAP_FILE_NAME (line_map *map)
+ORDINARY_MAP_FILE_NAME (line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.to_file;
+  return ord_map->to_file;
 }
 
 /* Get the cpp macro whose expansion gave birth to macro map MAP.  */
 
 inline cpp_hashnode *
-MACRO_MAP_MACRO (const line_map *map)
+MACRO_MAP_MACRO (const line_map_macro *macro_map)
 {
-  return map->d.macro.macro;
+  return macro_map->macro;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline cpp_hashnode * &
-MACRO_MAP_MACRO (line_map *map)
+MACRO_MAP_MACRO (line_map_macro *macro_map)
 {
-  return map->d.macro.macro;
+  return macro_map->macro;
 }
 
 /* Get the number of tokens inside the replacement-list of the macro
    that led to macro map MAP.  */
 
 inline unsigned int
-MACRO_MAP_NUM_MACRO_TOKENS (const line_map *map)
+MACRO_MAP_NUM_MACRO_TOKENS (const line_map_macro *macro_map)
 {
-  return map->d.macro.n_tokens;
+  return macro_map->n_tokens;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline unsigned int &
-MACRO_MAP_NUM_MACRO_TOKENS (line_map *map)
+MACRO_MAP_NUM_MACRO_TOKENS (line_map_macro *macro_map)
 {
-  return map->d.macro.n_tokens;
+  return macro_map->n_tokens;
 }
 
 /* Get the array of pairs of locations within macro map MAP.
    See the declaration of line_map_macro for more information.  */
 
 inline source_location *
-MACRO_MAP_LOCATIONS (const line_map *map)
+MACRO_MAP_LOCATIONS (const line_map_macro *macro_map)
 {
-  return map->d.macro.macro_locations;
+  return macro_map->macro_locations;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline source_location * &
-MACRO_MAP_LOCATIONS (line_map *map)
+MACRO_MAP_LOCATIONS (line_map_macro *macro_map)
 {
-  return map->d.macro.macro_locations;
+  return macro_map->macro_locations;
 }
 
 /* Get the location of the expansion point of the macro map MAP.  */
 
 inline source_location
-MACRO_MAP_EXPANSION_POINT_LOCATION (const line_map *map)
+MACRO_MAP_EXPANSION_POINT_LOCATION (const line_map_macro *macro_map)
 {
-  return map->d.macro.expansion;
+  return macro_map->expansion;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
 
 inline source_location &
-MACRO_MAP_EXPANSION_POINT_LOCATION (line_map *map)
+MACRO_MAP_EXPANSION_POINT_LOCATION (line_map_macro *macro_map)
 {
-  return map->d.macro.expansion;
+  return macro_map->expansion;
 }
 
 /* The abstraction of a set of location maps. There can be several
    types of location maps. This abstraction contains the attributes
-   that are independent from the type of the map.  */
-struct GTY(()) maps_info {
-  /* This array contains the different line maps.
-     A line map is created for the following events:
-       - when a new preprocessing unit start. 
-       - when a preprocessing unit ends.
-       - when a macro expansion occurs.  */
-  struct line_map * GTY ((length ("%h.used"))) maps;
+   that are independent from the type of the map.
+
+   Essentially this is just a vector of T_linemap_subclass,
+   which can only ever grow in size.  */
+
+struct GTY(()) maps_info_ordinary {
+  /* This array contains the "ordinary" line maps, for all
+     events other than macro expansion
+     (e.g. when a new preprocessing unit starts or ends).  */
+  line_map_ordinary * GTY ((length ("%h.used"))) maps;
+
+  /* The total number of allocated maps.  */
+  unsigned int allocated;
+
+  /* The number of elements used in maps. This number is smaller
+     or equal to ALLOCATED.  */
+  unsigned int used;
+
+  unsigned int cache;
+};
+
+struct GTY(()) maps_info_macro {
+  /* This array contains the macro line maps.
+     A macro line map is created whenever a macro expansion occurs.  */
+  line_map_macro * GTY ((length ("%h.used"))) maps;
 
   /* The total number of allocated maps.  */
   unsigned int allocated;
@@ -551,9 +582,9 @@
 /* A set of chronological line_map structures.  */
 struct GTY(()) line_maps {
   
-  struct maps_info info_ordinary;
+  maps_info_ordinary info_ordinary;
 
-  struct maps_info info_macro;
+  maps_info_macro info_macro;
 
   /* Depth of the include stack, including the current file.  */
   unsigned int depth;
@@ -589,50 +620,15 @@
   bool seen_line_directive;
 };
 
-/* Returns the pointer to the memory region where information about
-   maps are stored in the line table SET. MACRO_MAP_P is a flag
-   telling if we want macro or ordinary maps.  */
-inline struct maps_info *
-LINEMAPS_MAP_INFO (line_maps *set, bool macro_map_p)
-{
-  return (macro_map_p
-	  ? &(set->info_macro)
-	  : &(set->info_ordinary));
-}
-
-/* As above, but preserving constness.  */
-
-inline const struct maps_info *
-LINEMAPS_MAP_INFO (const line_maps *set, bool macro_map_p)
-{
-  return (macro_map_p
-	  ? &(set->info_macro)
-	  : &(set->info_ordinary));
-}
-
-/* Returns the pointer to the memory region where maps are stored in
-   the line table SET. MAP_KIND shall be TRUE if we are interested in
-   macro maps false otherwise.  */
-inline line_map *
-LINEMAPS_MAPS (const line_maps *set, bool map_kind)
-{
-  return LINEMAPS_MAP_INFO (set, map_kind)->maps;
-}
-
-/* As above, but by reference (e.g. as an lvalue).  */
-
-inline line_map * &
-LINEMAPS_MAPS (line_maps *set, bool map_kind)
-{
-  return LINEMAPS_MAP_INFO (set, map_kind)->maps;
-}
-
 /* Returns the number of allocated maps so far. MAP_KIND shall be TRUE
    if we are interested in macro maps, FALSE otherwise.  */
 inline unsigned int
 LINEMAPS_ALLOCATED (const line_maps *set, bool map_kind)
 {
-  return LINEMAPS_MAP_INFO (set, map_kind)->allocated;
+  if (map_kind)
+    return set->info_macro.allocated;
+  else
+    return set->info_ordinary.allocated;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
@@ -640,7 +636,10 @@
 inline unsigned int &
 LINEMAPS_ALLOCATED (line_maps *set, bool map_kind)
 {
-  return LINEMAPS_MAP_INFO (set, map_kind)->allocated;
+  if (map_kind)
+    return set->info_macro.allocated;
+  else
+    return set->info_ordinary.allocated;
 }
 
 /* Returns the number of used maps so far. MAP_KIND shall be TRUE if
@@ -648,7 +647,10 @@
 inline unsigned int
 LINEMAPS_USED (const line_maps *set, bool map_kind)
 {
-  return LINEMAPS_MAP_INFO (set, map_kind)->used;
+  if (map_kind)
+    return set->info_macro.used;
+  else
+    return set->info_ordinary.used;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
@@ -656,7 +658,10 @@
 inline unsigned int &
 LINEMAPS_USED (line_maps *set, bool map_kind)
 {
-  return LINEMAPS_MAP_INFO (set, map_kind)->used;
+  if (map_kind)
+    return set->info_macro.used;
+  else
+    return set->info_ordinary.used;
 }
 
 /* Returns the index of the last map that was looked up with
@@ -665,7 +670,10 @@
 inline unsigned int
 LINEMAPS_CACHE (const line_maps *set, bool map_kind)
 {
-  return LINEMAPS_MAP_INFO (set, map_kind)->cache;
+  if (map_kind)
+    return set->info_macro.cache;
+  else
+    return set->info_ordinary.cache;
 }
 
 /* As above, but by reference (e.g. as an lvalue).  */
@@ -673,14 +681,20 @@
 inline unsigned int &
 LINEMAPS_CACHE (line_maps *set, bool map_kind)
 {
-  return LINEMAPS_MAP_INFO (set, map_kind)->cache;
+  if (map_kind)
+    return set->info_macro.cache;
+  else
+    return set->info_ordinary.cache;
 }
 
 /* Return the map at a given index.  */
 inline line_map *
 LINEMAPS_MAP_AT (const line_maps *set, bool map_kind, int index)
 {
-  return &(LINEMAPS_MAPS (set, map_kind)[index]);
+  if (map_kind)
+    return &set->info_macro.maps[index];
+  else
+    return &set->info_ordinary.maps[index];
 }
 
 /* Returns the last map used in the line table SET. MAP_KIND
@@ -705,17 +719,19 @@
 
 /* Returns a pointer to the memory region where ordinary maps are
    allocated in the line table SET.  */
-inline line_map *
+inline line_map_ordinary *
 LINEMAPS_ORDINARY_MAPS (const line_maps *set)
 {
-  return LINEMAPS_MAPS (set, false);
+  return set->info_ordinary.maps;
 }
 
 /* Returns the INDEXth ordinary map.  */
-inline line_map *
+inline line_map_ordinary *
 LINEMAPS_ORDINARY_MAP_AT (const line_maps *set, int index)
 {
-  return LINEMAPS_MAP_AT (set, false, index);
+  linemap_assert (index >= 0);
+  linemap_assert ((unsigned int)index < set->info_ordinary.used);
+  return &set->info_ordinary.maps[index];
 }
 
 /* Return the number of ordinary maps allocated in the line table
@@ -751,33 +767,35 @@
 
 /* Returns a pointer to the last ordinary map used in the line table
    SET.  */
-inline line_map *
+inline line_map_ordinary *
 LINEMAPS_LAST_ORDINARY_MAP (const line_maps *set)
 {
-  return LINEMAPS_LAST_MAP (set, false);
+  return (line_map_ordinary *)LINEMAPS_LAST_MAP (set, false);
 }
 
 /* Returns a pointer to the last ordinary map allocated the line table
    SET.  */
-inline line_map *
+inline line_map_ordinary *
 LINEMAPS_LAST_ALLOCATED_ORDINARY_MAP (const line_maps *set)
 {
-  return LINEMAPS_LAST_ALLOCATED_MAP (set, false);
+  return (line_map_ordinary *)LINEMAPS_LAST_ALLOCATED_MAP (set, false);
 }
 
 /* Returns a pointer to the beginning of the region where macro maps
    are allcoated.  */
-inline line_map *
+inline line_map_macro *
 LINEMAPS_MACRO_MAPS (const line_maps *set)
 {
-  return LINEMAPS_MAPS (set, true);
+  return set->info_macro.maps;
 }
 
 /* Returns the INDEXth macro map.  */
-inline line_map *
+inline line_map_macro *
 LINEMAPS_MACRO_MAP_AT (const line_maps *set, int index)
 {
-  return LINEMAPS_MAP_AT (set, true, index);
+  linemap_assert (index >= 0);
+  linemap_assert ((unsigned int)index < set->info_macro.used);
+  return &set->info_macro.maps[index];
 }
 
 /* Returns the number of macro maps that were allocated in the line
@@ -812,10 +830,10 @@
 }
 
 /* Returns the last macro map used in the line table SET.  */
-inline line_map *
+inline line_map_macro *
 LINEMAPS_LAST_MACRO_MAP (const line_maps *set)
 {
-  return LINEMAPS_LAST_MAP (set, true);
+  return (line_map_macro *)LINEMAPS_LAST_MAP (set, true);
 }
 
 /* Returns the lowest location [of a token resulting from macro
@@ -829,10 +847,10 @@
 }
 
 /* Returns the last macro map allocated in the line table SET.  */
-inline line_map *
+inline line_map_macro *
 LINEMAPS_LAST_ALLOCATED_MACRO_MAP (const line_maps *set)
 {
-  return LINEMAPS_LAST_ALLOCATED_MAP (set, true);
+  return (line_map_macro *)LINEMAPS_LAST_ALLOCATED_MAP (set, true);
 }
 
 extern void location_adhoc_data_fini (struct line_maps *);
@@ -913,7 +931,7 @@
 bool linemap_tracks_macro_expansion_locs_p (struct line_maps *);
 
 /* Return the name of the macro associated to MACRO_MAP.  */
-const char* linemap_map_get_macro_name (const struct line_map*);
+const char* linemap_map_get_macro_name (const line_map_macro *);
 
 /* Return a positive value if LOCATION is the locus of a token that is
    located in a system header, O otherwise. It returns 1 if LOCATION
@@ -940,37 +958,36 @@
 
 /* Converts a map and a source_location to source line.  */
 inline linenum_type
-SOURCE_LINE (const struct line_map *map, source_location loc)
+SOURCE_LINE (const line_map_ordinary *ord_map, source_location loc)
 {
-  return ((loc - linemap_check_ordinary (map)->start_location)
-	  >> map->d.ordinary.column_bits) + map->d.ordinary.to_line;
+  return ((loc - ord_map->start_location)
+	  >> ord_map->column_bits) + ord_map->to_line;
 }
 
 /* Convert a map and source_location to source column number.  */
 inline linenum_type
-SOURCE_COLUMN (const struct line_map *map, source_location loc)
+SOURCE_COLUMN (const line_map_ordinary *ord_map, source_location loc)
 {
-  return ((loc - linemap_check_ordinary (map)->start_location)
-	  & ((1 << map->d.ordinary.column_bits) - 1));
+  return ((loc - ord_map->start_location)
+	  & ((1 << ord_map->column_bits) - 1));
 }
 
 /* Return the location of the last source line within an ordinary
    map.  */
 inline source_location
-LAST_SOURCE_LINE_LOCATION (const struct line_map *map)
+LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
 {
-  return (((linemap_check_ordinary (map)[1].start_location - 1
+  return (((map[1].start_location - 1
 	    - map->start_location)
-	   & ~((1 << map->d.ordinary.column_bits) - 1))
+	   & ~((1 << map->column_bits) - 1))
 	  + map->start_location);
 }
 
 /* Returns the last source line number within an ordinary map.  This
    is the (last) line of the #include, or other directive, that caused
    a map change.  */
-
 inline linenum_type
-LAST_SOURCE_LINE (const struct line_map *map)
+LAST_SOURCE_LINE (const line_map_ordinary *map)
 {
   return SOURCE_LINE (map, LAST_SOURCE_LINE_LOCATION (map));
 }
@@ -978,7 +995,7 @@
 /* Return the last column number within an ordinary map.  */
 
 inline linenum_type
-LAST_SOURCE_COLUMN (const struct line_map *map)
+LAST_SOURCE_COLUMN (const line_map_ordinary *map)
 {
   return SOURCE_COLUMN (map, LAST_SOURCE_LINE_LOCATION (map));
 }
@@ -986,21 +1003,20 @@
 /* Returns the map a given map was included from, or NULL if the map
    belongs to the main file, i.e, a file that wasn't included by
    another one.  */
-
-inline struct line_map *
-INCLUDED_FROM (struct line_maps *set, const struct line_map *map)
+inline line_map_ordinary *
+INCLUDED_FROM (struct line_maps *set, const line_map_ordinary *ord_map)
 {
-  return ((linemap_check_ordinary (map)->d.ordinary.included_from == -1)
+  return ((ord_map->included_from == -1)
 	  ? NULL
-	  : (&LINEMAPS_ORDINARY_MAPS (set)[(map)->d.ordinary.included_from]));
+	  : LINEMAPS_ORDINARY_MAP_AT (set, ord_map->included_from));
 }
 
 /* True if the map is at the bottom of the include stack.  */
 
 inline bool
-MAIN_FILE_P (const struct line_map *map)
+MAIN_FILE_P (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.included_from < 0;
+  return ord_map->included_from < 0;
 }
 
 /* Encode and return a source_location from a column number. The
@@ -1013,7 +1029,7 @@
 /* Encode and return a source location from a given line and
    column.  */
 source_location
-linemap_position_for_line_and_column (const struct line_map *,
+linemap_position_for_line_and_column (const line_map_ordinary *,
 				      linenum_type, unsigned int);
 
 /* Encode and return a source_location starting from location LOC and
@@ -1026,16 +1042,16 @@
 
 /* Return the file this map is for.  */
 inline const char *
-LINEMAP_FILE (const struct line_map *map)
+LINEMAP_FILE (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.to_file;
+  return ord_map->to_file;
 }
 
 /* Return the line number this map started encoding location from.  */
 inline linenum_type
-LINEMAP_LINE (const struct line_map *map)
+LINEMAP_LINE (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.to_line;
+  return ord_map->to_line;
 }
 
 /* Return a positive value if map encodes locations from a system
@@ -1043,9 +1059,9 @@
    system header and 2 if it encodes locations in a C system header
    that therefore needs to be extern "C" protected in C++.  */
 inline unsigned char
-LINEMAP_SYSP (const struct line_map *map)
+LINEMAP_SYSP (const line_map_ordinary *ord_map)
 {
-  return linemap_check_ordinary (map)->d.ordinary.sysp;
+  return ord_map->sysp;
 }
 
 /* Return a positive value if PRE denotes the location of a token that
@@ -1144,7 +1160,7 @@
 source_location linemap_resolve_location (struct line_maps *,
 					  source_location loc,
 					  enum location_resolution_kind lrk,
-					  const struct line_map **loc_map);
+					  const line_map_ordinary **loc_map);
 
 /* Suppose that LOC is the virtual location of a token coming from the
    expansion of a macro M.  This function then steps up to get the