]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Prune unneeded macro locations
authorNathan Sidwell <nathan@acm.org>
Wed, 22 Jun 2022 12:54:30 +0000 (05:54 -0700)
committerNathan Sidwell <nathan@acm.org>
Thu, 23 Jun 2022 12:16:24 +0000 (05:16 -0700)
This implements garbage collection on locations within macro
expansions, when streaming out a CMI.  When doing the reachability
walks, we now note which macro locations we need and then only write
those locations.  The complication here is that every macro expansion
location has an independently calculated offset.  This complicates
writing, but reading remains the same -- the macro locations of a CMI
continue to form a contiguous block.

For std headers this reduced the number of macro maps by 40% and the
number of locations by 16%.  For a GMF including iostream, it reduced
it by 80% and 60% respectively.

Ordinary locations are still transformed en-mass.  They are somewhat
more complicated to apply a similar optimization to.

gcc/cp/
* module.cc (struct macro_info): New.
(struct macro_traits): New.
(macro_remap, macro_table): New globals.
(depset::hash::find_dependencies): Note namespace location.
(module_for_macro_loc): Adjust.
(module_state::note_location): New.
(module_state::Write_location): Note location when not
streaming. Adjust macro location streaming.
(module_state::read_location): Adjust macro location
streaming.
(module_state::write_init_maps): New.
(module_state::write_prepare_maps): Reimplement macro map
preparation.
(module_state::write_macro_maps): Reimplement.
(module_state::read_macro_maps): Likewise.
(module_state::write_begin): Adjust.
gcc/testsuite/
* g++.dg/modules/loc-prune-1.C: New.
* g++.dg/modules/loc-prune-2.C: New.
* g++.dg/modules/loc-prune-3.C: New.
* g++.dg/modules/pr98718_a.C: Adjust.
* g++.dg/modules/pr98718_b.C: Adjust.

gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/loc-prune-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/loc-prune-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/loc-prune-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/pr98718_a.C
gcc/testsuite/g++.dg/modules/pr98718_b.C

index d735d7e8b30374490c6f219f1dbd3ee16e371f83..7ee779d06b93598565256b7ec27f02efcafdc922 100644 (file)
@@ -3238,6 +3238,65 @@ public:
 };
 
 static loc_spans spans;
+
+/* Information about macro locations we stream out.  */
+struct macro_info
+{
+  const line_map_macro *src;    // original expansion
+  unsigned remap;        // serialization
+
+  static int compare (const void *a_, const void *b_)
+  {
+    auto *a = static_cast<const macro_info *> (a_);
+    auto *b = static_cast<const macro_info *> (b_);
+
+    gcc_checking_assert (MAP_START_LOCATION (a->src)
+                        != MAP_START_LOCATION (b->src));
+    if (MAP_START_LOCATION (a->src) < MAP_START_LOCATION (b->src))
+      return -1;
+    else
+      return +1;
+  }
+};
+struct macro_traits
+{
+  typedef macro_info value_type;
+  typedef const line_map_macro *compare_type;
+
+  static const bool empty_zero_p = false;
+
+  static hashval_t hash (compare_type p)
+  {
+    return pointer_hash<const line_map_macro>::hash (p);
+  }
+  static hashval_t hash (const value_type &v)
+  {
+    return hash (v.src);
+  }
+  static bool equal (const value_type &v, const compare_type p)
+  {
+    return v.src == p;
+  }
+
+  static void mark_empty (value_type &v)
+  {
+    v.src = nullptr;
+  }
+  static bool is_empty (value_type &v)
+  {
+    return !v.src;
+  }
+
+  static bool is_deleted (value_type &) { return false; }
+  static void mark_deleted (value_type &) { gcc_unreachable (); }
+  
+  static void remove (value_type &) {}
+};
+/* Table keyed by line_map_macro, used for noting.  */
+static  hash_table<macro_traits> *macro_table;
+/* Sorted vector, used for writing.  */
+static vec<macro_info> *macro_remap;
+
 /* Indirection to allow bsearching imports by ordinary location.  */
 static vec<module_state *> *ool;
 
@@ -3398,7 +3457,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state {
   /* Location ranges for this module.  adhoc-locs are decomposed, so
      don't have a range.  */
   loc_range_t GTY((skip)) ordinary_locs;
-  loc_range_t GTY((skip)) macro_locs;
+  loc_range_t GTY((skip)) macro_locs; // [lwm,num)
 
   /* LOC is first set too the importing location.  When initially
      loaded it refers to a module loc whose parent is the importing
@@ -3591,6 +3650,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state {
   bool read_entities (unsigned count, unsigned lwm, unsigned hwm);
 
  private:
+  void write_init_maps ();
   location_map_info write_prepare_maps (module_state_config *);
   bool read_prepare_maps (const module_state_config *);
 
@@ -3599,7 +3659,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state {
   bool read_ordinary_maps ();
   void write_macro_maps (elf_out *to, location_map_info &,
                         module_state_config *, unsigned *crc_ptr);
-  bool read_macro_maps ();
+  bool read_macro_maps (unsigned);
 
  private:
   void write_define (bytes_out &, const cpp_macro *, bool located = true);
@@ -3616,6 +3676,7 @@ class GTY((chain_next ("%h.parent"), for_user)) module_state {
   static cpp_macro *deferred_macro (cpp_reader *, location_t, cpp_hashnode *);
 
  public:
+  static void note_location (location_t);
   static void write_location (bytes_out &, location_t);
   location_t read_location (bytes_in &) const;
 
@@ -13106,7 +13167,10 @@ depset::hash::find_dependencies (module_state *module)
              else if (TREE_VISITED (decl))
                /* A global tree.  */;
              else if (item->get_entity_kind () == EK_NAMESPACE)
-               add_namespace_context (current, CP_DECL_CONTEXT (decl));
+               {
+                 module->note_location (DECL_SOURCE_LOCATION (decl));
+                 add_namespace_context (current, CP_DECL_CONTEXT (decl));
+               }
              else
                {
                  walker.mark_declaration (decl, current->has_defn ());
@@ -15518,15 +15582,15 @@ module_for_macro_loc (location_t loc)
     {
       unsigned half = len / 2;
       module_state *probe = (*modules)[pos + half];
-      if (loc >= probe->macro_locs.second)
-       len = half;
-      else if (loc >= probe->macro_locs.first)
-       return probe;
-      else
+      if (loc < probe->macro_locs.first)
        {
          pos += half + 1;
          len = len - (half + 1);
        }
+      else if (loc >= (probe->macro_locs.first + probe->macro_locs.second))
+       len = half;
+      else
+       return probe;
     }
 
   return NULL;
@@ -15545,6 +15609,62 @@ module_state::imported_from () const
   return from;
 }
 
+/* Note that LOC will need writing.  This allows us to prune locations
+   that are not needed.  */
+
+void
+module_state::note_location (location_t loc)
+{
+  if (!macro_table)
+    ;
+  else if (loc < RESERVED_LOCATION_COUNT)
+    ;
+  else if (IS_ADHOC_LOC (loc))
+    {
+      location_t locus = get_location_from_adhoc_loc (line_table, loc);
+      note_location (locus);
+      source_range range = get_range_from_loc (line_table, loc);
+      if (range.m_start != locus)
+       note_location (range.m_start);
+      note_location (range.m_finish);
+    }
+  else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
+    {
+      if (spans.macro (loc))
+       {
+         const line_map *map = linemap_lookup (line_table, loc);
+         const line_map_macro *mac_map = linemap_check_macro (map);
+         hashval_t hv = macro_traits::hash (mac_map);
+         macro_info *slot
+           = macro_table->find_slot_with_hash (mac_map, hv, INSERT);
+         if (!slot->src)
+           {
+             slot->src = mac_map;
+             slot->remap = 0;
+             // Expansion locations could themselves be from a
+             // macro, we need to note them all.
+             note_location (mac_map->expansion);
+             gcc_checking_assert (mac_map->n_tokens);
+             location_t tloc = UNKNOWN_LOCATION;
+             for (unsigned ix = mac_map->n_tokens * 2; ix--;)
+               if (mac_map->macro_locations[ix] != tloc)
+                 {
+                   tloc = mac_map->macro_locations[ix];
+                   note_location (tloc);
+                 }
+           }
+       }                                      
+    }
+  else if (IS_ORDINARY_LOC (loc))
+    {
+      /* This is where we should note we use this location.  See comment
+        about write_ordinary_maps.  */
+    }
+  else
+    gcc_unreachable ();
+  return;
+}
+
 /* If we're not streaming, record that we need location LOC.
    Otherwise stream it.  */
 
@@ -15552,9 +15672,10 @@ void
 module_state::write_location (bytes_out &sec, location_t loc)
 {
   if (!sec.streaming_p ())
-    /* This is where we should note we use this location.  See comment
-       about write_ordinary_maps.  */
-    return;
+    {
+      note_location (loc);
+      return;
+    }
 
   if (loc < RESERVED_LOCATION_COUNT)
     {
@@ -15576,20 +15697,40 @@ module_state::write_location (bytes_out &sec, location_t loc)
     }
   else if (loc >= LINEMAPS_MACRO_LOWEST_LOCATION (line_table))
     {
-      if (const loc_spans::span *span = spans.macro (loc))
+      const macro_info *info = nullptr;
+      unsigned offset = 0;
+      if (unsigned hwm = macro_remap->length ())
        {
-         unsigned off = MAX_LOCATION_T - loc;
+         info = macro_remap->begin ();
+         while (hwm != 1)
+           {
+             unsigned mid = hwm / 2;
+             if (MAP_START_LOCATION (info[mid].src) <= loc)
+               {
+                 info += mid;
+                 hwm -= mid;
+               }
+             else
+               hwm = mid;
+           }
+         offset = loc - MAP_START_LOCATION (info->src);
+         if (offset > info->src->n_tokens)
+           info = nullptr;
+       }
 
-         off -= span->macro_delta;
+      gcc_checking_assert (bool (info) == bool (spans.macro (loc)));
 
+      if (info)
+       {
+         offset += info->remap;
          sec.u (LK_MACRO);
-         sec.u (off);
+         sec.u (offset);
          dump (dumper::LOCATION)
-           && dump ("Macro location %u output %u", loc, off);
+           && dump ("Macro location %u output %u", loc, offset);
        }
       else if (const module_state *import = module_for_macro_loc (loc))
        {
-         unsigned off = import->macro_locs.second - loc - 1;
+         unsigned off = loc - import->macro_locs.first;
          sec.u (LK_IMPORT_MACRO);
          sec.u (import->remap);
          sec.u (off);
@@ -15668,12 +15809,8 @@ module_state::read_location (bytes_in &sec) const
 
        if (macro_locs.first)
          {
-           location_t adjusted = MAX_LOCATION_T - off;
-           adjusted -= slurp->loc_deltas.second;
-           if (adjusted < macro_locs.first)
-             sec.set_overrun ();
-           else if (adjusted < macro_locs.second)
-             locus = adjusted;
+           if (off < macro_locs.second)
+             locus = off + macro_locs.first;
            else
              sec.set_overrun ();
          }
@@ -15733,8 +15870,8 @@ module_state::read_location (bytes_in &sec) const
               {
                 if (!import->macro_locs.first)
                   locus = import->loc;
-                else if (off < import->macro_locs.second - macro_locs.first)
-                  locus = import->macro_locs.second - off - 1;
+                else if (off < import->macro_locs.second)
+                  locus = off + import->macro_locs.first;
                 else
                   sec.set_overrun ();
               }
@@ -15768,8 +15905,14 @@ module_state::read_location (bytes_in &sec) const
 // should decompose locations so that we can have a more graceful
 // degradation upon running out?
 
+void
+module_state::write_init_maps ()
+{
+  macro_table = new hash_table<macro_traits> (EXPERIMENT (1, 400));
+}
+
 location_map_info
-module_state::write_prepare_maps (module_state_config *)
+module_state::write_prepare_maps (module_state_config *cfg)
 {
   dump () && dump ("Preparing locations");
   dump.indent ();
@@ -15840,7 +15983,6 @@ module_state::write_prepare_maps (module_state_config *)
   /* Adjust the maps.  Ordinary ones ascend, and we must maintain
      alignment.  Macro ones descend, but are unaligned.  */
   location_t ord_off = spans[loc_spans::SPAN_FIRST].ordinary.first;
-  location_t mac_off = spans[loc_spans::SPAN_FIRST].macro.second;
   location_t range_mask = (1u << max_range) - 1;
 
   dump () && dump ("Ordinary maps range bits:%u, preserve:%x, zero:%u",
@@ -15850,16 +15992,9 @@ module_state::write_prepare_maps (module_state_config *)
     {
       loc_spans::span &span = spans[ix];
 
-      span.macro_delta = mac_off - span.macro.second;
-      mac_off -= span.macro.second - span.macro.first;
-      dump () && dump ("Macro span:%u [%u,%u):%u->%d(%u)", ix,
-                      span.macro.first, span.macro.second,
-                      span.macro.second - span.macro.first,
-                      span.macro_delta, span.macro.first + span.macro_delta);
-
       line_map_ordinary const *omap
        = linemap_check_ordinary (linemap_lookup (line_table,
-                                                     span.ordinary.first));
+                                                 span.ordinary.first));
       location_t base = MAP_START_LOCATION (omap);
 
       /* Preserve the low MAX_RANGE bits of base by incrementing ORD_OFF.  */
@@ -15888,14 +16023,33 @@ module_state::write_prepare_maps (module_state_config *)
       ord_off = span.ordinary.second + span.ordinary_delta;
     }
 
-  dump () && dump ("Ordinary:%u maps hwm:%u macro:%u maps lwm:%u ",
+  vec_alloc (macro_remap, macro_table->size ());
+  for (auto iter = macro_table->begin (), end = macro_table->end ();
+       iter != end; ++iter)
+    macro_remap->quick_push (*iter);
+  delete macro_table;
+  macro_table = nullptr;
+
+  macro_remap->qsort (&macro_info::compare);
+  unsigned offset = 0;
+  for (auto iter = macro_remap->begin (), end = macro_remap->end ();
+       iter != end; ++iter)
+    {
+      auto mac = iter->src;
+      iter->remap = offset;
+      offset += mac->n_tokens;
+    }
+  info.num_maps.second = macro_remap->length ();
+  cfg->macro_locs = offset;
+
+  dump () && dump ("Ordinary:%u maps hwm:%u macro:%u maps %u locs",
                   info.num_maps.first, ord_off,
-                  info.num_maps.second, mac_off);
+                  info.num_maps.second, cfg->macro_locs);
 
   dump.outdent ();
 
   info.max_range = max_range;
-  
+
   return info;
 }
 
@@ -16077,7 +16231,7 @@ module_state::write_ordinary_maps (elf_out *to, location_map_info &info,
 
 void
 module_state::write_macro_maps (elf_out *to, location_map_info &info,
-                               module_state_config *cfg, unsigned *crc_p)
+                               module_state_config *, unsigned *crc_p)
 {
   dump () && dump ("Writing macro location maps");
   dump.indent ();
@@ -16088,74 +16242,46 @@ module_state::write_macro_maps (elf_out *to, location_map_info &info,
   dump () && dump ("Macro maps:%u", info.num_maps.second);
   sec.u (info.num_maps.second);
 
-  location_t offset = spans[loc_spans::SPAN_FIRST].macro.second;
-  sec.u (offset);
-
   unsigned macro_num = 0;
-  for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
-    {
-      loc_spans::span &span = spans[ix];
-      if (span.macro.first == span.macro.second)
-       /* Empty span.  */
-       continue;
-
-      for (unsigned macro
-            = linemap_lookup_macro_index (line_table, span.macro.second - 1);
-          macro < LINEMAPS_MACRO_USED (line_table);
-          macro++)
+  for (auto iter = macro_remap->end (), begin = macro_remap->begin ();
+       iter-- != begin;)
+    {
+      auto mac = iter->src;
+      sec.u (iter->remap);
+      sec.u (mac->n_tokens);
+      sec.cpp_node (mac->macro);
+      write_location (sec, mac->expansion);
+      const location_t *locs = mac->macro_locations;
+      /* There are lots of identical runs.  */
+      location_t prev = UNKNOWN_LOCATION;
+      unsigned count = 0;
+      unsigned runs = 0;
+      for (unsigned jx = mac->n_tokens * 2; jx--;)
        {
-         line_map_macro const *mmap
-           = LINEMAPS_MACRO_MAP_AT (line_table, macro);
-         location_t start_loc = MAP_START_LOCATION (mmap);
-         if (start_loc < span.macro.first)
-           /* Fallen out of the span.  */
-           break;
-
-         if (!mmap->n_tokens)
-           /* Empty expansion.  */
-           continue;
-
-         sec.u (offset);
-         sec.u (mmap->n_tokens);
-         sec.cpp_node (mmap->macro);
-         write_location (sec, mmap->expansion);
-         const location_t *locs = mmap->macro_locations;
-         /* There are lots of identical runs.  */
-         location_t prev = UNKNOWN_LOCATION;
-         unsigned count = 0;
-         unsigned runs = 0;
-         for (unsigned jx = mmap->n_tokens * 2; jx--;)
+         location_t tok_loc = locs[jx];
+         if (tok_loc == prev)
            {
-             location_t tok_loc = locs[jx];
-             if (tok_loc == prev)
-               {
-                 count++;
-                 continue;
-               }
-             runs++;
-             sec.u (count);
-             count = 1;
-             prev = tok_loc;
-             write_location (sec, tok_loc);
+             count++;
+             continue;
            }
+         runs++;
          sec.u (count);
-         dump (dumper::LOCATION)
-           && dump ("Span:%u macro:%u %I %u/%u*2 locations [%u,%u)->%u",
-                    ix, macro_num, identifier (mmap->macro),
-                    runs, mmap->n_tokens,
-                    start_loc, start_loc + mmap->n_tokens,
-                    start_loc + span.macro_delta);
-         macro_num++;
-         offset -= mmap->n_tokens;
-         gcc_checking_assert (offset == start_loc + span.macro_delta);
+         count = 1;
+         prev = tok_loc;
+         write_location (sec, tok_loc);
        }
+      sec.u (count);
+      dump (dumper::LOCATION)
+       && dump ("Macro:%u %I %u/%u*2 locations [%u,%u)->%u",
+                macro_num, identifier (mac->macro),
+                runs, mac->n_tokens,
+                MAP_START_LOCATION (mac),
+                MAP_START_LOCATION (mac) + mac->n_tokens,
+                iter->remap);
+      macro_num++;
     }
-  dump () && dump ("Macro location lwm:%u", offset);
-  sec.u (offset);
   gcc_assert (macro_num == info.num_maps.second);
 
-  cfg->macro_locs = MAX_LOCATION_T + 1 - offset;
-
   sec.end (to, to->name (MOD_SNAME_PFX ".mlm"), crc_p);
   dump.outdent ();
 }
@@ -16265,7 +16391,7 @@ module_state::read_ordinary_maps ()
 }
 
 bool
-module_state::read_macro_maps ()
+module_state::read_macro_maps (unsigned num_macro_locs)
 {
   bytes_in sec;
 
@@ -16275,24 +16401,22 @@ module_state::read_macro_maps ()
   dump.indent ();
 
   unsigned num_macros = sec.u ();
-  location_t zero = sec.u ();
-  dump () && dump ("Macro maps:%u zero:%u", num_macros, zero);
+  dump () && dump ("Macro maps:%u locs:%u", num_macros, num_macro_locs);
 
   bool propagated = spans.maybe_propagate (this,
                                           line_table->highest_location + 1);
 
   location_t offset = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
-  slurp->loc_deltas.second = zero - offset;
-  macro_locs.second = zero - slurp->loc_deltas.second;
-  dump () && dump ("Macro loc delta %d", slurp->loc_deltas.second);
+  macro_locs.second = num_macro_locs;
+  macro_locs.first = offset - num_macro_locs;
+
+  dump () && dump ("Macro loc delta %d", offset);
+  dump () && dump ("Macro locations [%u,%u)",
+                  macro_locs.first, macro_locs.second);
 
   for (unsigned ix = 0; ix != num_macros && !sec.get_overrun (); ix++)
     {
-      unsigned lwm = sec.u ();
-      /* Record the current LWM so that the below read_location is
-        ok.  */
-      macro_locs.first = lwm - slurp->loc_deltas.second;
-
+      unsigned offset = sec.u ();
       unsigned n_tokens = sec.u ();
       cpp_hashnode *node = sec.cpp_node ();
       location_t exp_loc = read_location (sec);
@@ -16303,6 +16427,8 @@ module_state::read_macro_maps ()
        /* We shouldn't run out of locations, as we checked that we
           had enough before starting.  */
        break;
+      gcc_checking_assert (MAP_START_LOCATION (macro)
+                          == offset + macro_locs.first);
 
       location_t *locs = macro->macro_locations;
       location_t tok_loc = UNKNOWN_LOCATION;
@@ -16326,11 +16452,8 @@ module_state::read_macro_maps ()
                 MAP_START_LOCATION (macro),
                 MAP_START_LOCATION (macro) + n_tokens);
     }
-  location_t lwm = sec.u ();
-  macro_locs.first = lwm - slurp->loc_deltas.second;
 
   dump () && dump ("Macro location lwm:%u", macro_locs.first);
-
   if (propagated)
     spans.close ();
 
@@ -17604,6 +17727,8 @@ module_state::write_begin (elf_out *to, cpp_reader *reader,
     /* No partitions present.  */
     partitions = nullptr;
 
+  write_init_maps ();
+
   /* Find the set of decls we must write out.  */
   depset::hash table (DECL_NAMESPACE_BINDINGS (global_namespace)->size () * 8);
   /* Add the specializations before the writables, so that we can
@@ -17911,7 +18036,7 @@ module_state::read_initial (cpp_reader *reader)
   gcc_assert (!from ()->is_frozen ());
 
   /* Macro maps after the imports.  */
-  if (ok && have_locs && !read_macro_maps ())
+  if (ok && have_locs && !read_macro_maps (config.macro_locs))
     ok = false;
 
   /* Note whether there's an active initializer.  */
diff --git a/gcc/testsuite/g++.dg/modules/loc-prune-1.C b/gcc/testsuite/g++.dg/modules/loc-prune-1.C
new file mode 100644 (file)
index 0000000..6978e49
--- /dev/null
@@ -0,0 +1,19 @@
+//  { dg-additional-options {-fmodules-ts -fdump-lang-module-lineno} }
+
+export module foo;
+// { dg-module-cmi foo }
+#define NOT 1
+#define YES 1
+#define AGAIN_NO (1 + 2)
+#if NOT
+int foo (int = YES)
+{
+  return AGAIN_NO;
+}
+#endif
+
+// { dg-final { scan-lang-dump { Macro maps:1} module } }
+// { dg-final { scan-lang-dump { Macro:0 YES 1/1.2 locations } module } }
+// { dg-final { scan-lang-dump { Ordinary:[0-9]* maps hwm:[0-9]* macro:1 maps 1 locs} module } }
+// { dg-final { scan-lang-dump-not {Macro:. NOT } module } }
+// { dg-final { scan-lang-dump-not {Macro:. AGAIN_NO } module } }
diff --git a/gcc/testsuite/g++.dg/modules/loc-prune-2.C b/gcc/testsuite/g++.dg/modules/loc-prune-2.C
new file mode 100644 (file)
index 0000000..fc4ed78
--- /dev/null
@@ -0,0 +1,14 @@
+//  { dg-additional-options {-fmodules-ts -fdump-lang-module-lineno} }
+
+export module Eve;
+// { dg-module-cmi Eve }
+
+#define BEGIN_NAMESPACE(X) inline namespace X {
+#define END_NAMESPACE(X) }
+
+BEGIN_NAMESPACE (BOB)
+void Alice ();
+END_NAMESPACE (BOB)
+
+// { dg-final { scan-lang-dump { Macro maps:1} module } }
+// { dg-final { scan-lang-dump { Macro:0 BEGIN_NAMESPACE 5/6.2 locations } module } }
diff --git a/gcc/testsuite/g++.dg/modules/loc-prune-3.C b/gcc/testsuite/g++.dg/modules/loc-prune-3.C
new file mode 100644 (file)
index 0000000..40e8aa6
--- /dev/null
@@ -0,0 +1,16 @@
+//  { dg-additional-options {-fmodules-ts -fdump-lang-module-lineno} }
+
+export module Eve;
+// { dg-module-cmi Eve }
+
+#define BEGIN_NAMESPACE(X) inline namespace X {
+#define END_NAMESPACE(X) }
+
+BEGIN_NAMESPACE (BOB)
+namespace inner {
+void Alice ();
+}
+END_NAMESPACE (BOB)
+
+// { dg-final { scan-lang-dump { Macro maps:1} module } }
+// { dg-final { scan-lang-dump { Macro:0 BEGIN_NAMESPACE 5/6.2 locations } module } }
index 0be5f905ee4b7c327292dba79e115c853b709624..ebd95ea1f85318e3d07c2f609549718a0c6e181b 100644 (file)
@@ -14,5 +14,5 @@ namespace std _GLIBCXX_VISIBILITY(default)
 export  module  hello:format;
 // { dg-module-cmi hello:format }
 
-// { dg-final { scan-lang-dump { Ordinary:4 maps hwm:[0-9]* macro:1 maps lwm:214[0-9]*} module } }
-// { dg-final { scan-lang-dump { Span:2 macro:0 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } }
+// { dg-final { scan-lang-dump { Ordinary:4 maps hwm:[0-9]* macro:0 maps 0 locs} module } }
+// { dg-final { scan-lang-dump-not { Macro:. _GLIBCXX_VISIBILITY} module } }
index 50679c8d82c876189d019262ab5a4807c6f5e63e..6cb4698bad5aed0d80a8a338abc16408056685ff 100644 (file)
@@ -14,7 +14,5 @@ export  module  hello;
 export  import  :format;
 // { dg-module-cmi hello }
 
-// { dg-final { scan-lang-dump {Macro:0 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } }
-// { dg-final { scan-lang-dump { Ordinary:8 maps hwm:[0-9]* macro:2 maps lwm:214[0-9]*} module } }
-// { dg-final { scan-lang-dump { Span:2 macro:0 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } }
-// { dg-final { scan-lang-dump { Span:4 macro:1 _GLIBCXX_VISIBILITY 10/11\*2 locations } module } }
+// { dg-final { scan-lang-dump { Ordinary:8 maps hwm:[0-9]* macro:0 maps 0 locs} module } }
+// { dg-final { scan-lang-dump-not { Macro:. _GLIBCXX_VISIBILITY} module } }