]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2002-10-14 David Carlton <carlton@math.stanford.edu>
authorDavid Carlton <carlton@bactrian.org>
Tue, 15 Oct 2002 00:20:32 +0000 (00:20 +0000)
committerDavid Carlton <carlton@bactrian.org>
Tue, 15 Oct 2002 00:20:32 +0000 (00:20 +0000)
* buildsym.c (add_using_directive): Rewrite to match new version
of struct using_direct.
(finish_block): Ditto.

* symtab.c (lookup_symbol_aux_using_loop): Add 'prefix_len'
argument; rewrite to match new version of struct using_direct.

* cp-support.h: Update declaration for cp_add_using.

* cp-support.c (cp_add_using): Rewrite to match new version of
struct using_direct.

* cp-support.h (struct using_direct): Rewrite struct.

* buildsym.h: Declaration for add_using_directive.

* buildsym.c: New variable 'using_list'.
(start_symtab): Initialize using_list.
(end_symtab): Initialize BLOCK_USING of STATIC_BLOCK.
(scan_for_anonymous_namespaces): New function.
(add_symbol_to_list): In C++ case, look for anonymous namespaces.
(add_using_directive): New function.

gdb/ChangeLog
gdb/buildsym.c
gdb/buildsym.h
gdb/cp-support.c
gdb/cp-support.h
gdb/symtab.c

index eb9a49782dca4977a9df2ff41d8dd9d6a29a98ef..c6ddf0a1bf28bb7fc49c5bf00e6360ba79de8ae3 100644 (file)
@@ -1,3 +1,28 @@
+2002-10-14  David Carlton  <carlton@math.stanford.edu>
+
+       * buildsym.c (add_using_directive): Rewrite to match new version
+       of struct using_direct.
+       (finish_block): Ditto.
+
+       * symtab.c (lookup_symbol_aux_using_loop): Add 'prefix_len'
+       argument; rewrite to match new version of struct using_direct.
+
+       * cp-support.h: Update declaration for cp_add_using.
+
+       * cp-support.c (cp_add_using): Rewrite to match new version of
+       struct using_direct.
+
+       * cp-support.h (struct using_direct): Rewrite struct.
+
+       * buildsym.h: Declaration for add_using_directive.
+
+       * buildsym.c: New variable 'using_list'.
+       (start_symtab): Initialize using_list.
+       (end_symtab): Initialize BLOCK_USING of STATIC_BLOCK.
+       (scan_for_anonymous_namespaces): New function.
+       (add_symbol_to_list): In C++ case, look for anonymous namespaces.
+       (add_using_directive): New function.
+
 2002-10-11  David Carlton  <carlton@math.stanford.edu>
 
        * jv-lang.c (get_java_class_symtab): Initialize BLOCK_USING (bl)
index 612f6994a56cecec8174c956c500e1c1b4ae9ff3..a2322e24eeb9c96e631425f929b40941f6e4e624 100644 (file)
@@ -63,8 +63,15 @@ static struct pending *free_pendings;
    otherwise empty symtab from being tossed.  */
 
 static int have_line_numbers;
+
+/* List of using directives that are active in the current file.  */
+
+static struct using_direct_node *using_list;
+
 \f
 static int compare_line_numbers (const void *ln1p, const void *ln2p);
+
+static void scan_for_anonymous_namespaces (struct symbol *symbol);
 \f
 
 /* Initial sizes of data structures.  These are realloc'd larger if
@@ -108,7 +115,9 @@ add_free_pendings (struct pending *list)
     }
 }
       
-/* Add a symbol to one of the lists of symbols.  */
+/* Add a symbol to one of the lists of symbols.  While we're at it,
+   check to see if it references an anonymous namespace; if so, add an
+   appropriate using directive.  */
 
 void
 add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
@@ -139,6 +148,48 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
     }
 
   (*listhead)->symbol[(*listhead)->nsyms++] = symbol;
+
+  /* Check to see if we might need to look for a mention of anonymous
+     namespaces.  */
+  /* TODOTODO */
+/*   if (SYMBOL_LANGUAGE (symbol) == language_cplus */
+/*       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL) */
+/*     scan_for_anonymous_namespaces (symbol) */
+}
+
+/* Check to see if a symbol is contained within an anonymous
+   namespace; if so, add an appropriate using directive.  */
+
+/* Optimize away strlen ("(anonymous namespace)").  */
+
+#define ANONYMOUS_NAMESPACE_LEN 21
+
+static void
+scan_for_anonymous_namespaces (struct symbol *symbol)
+{
+  const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
+  const char *beginning, *end;
+
+  /* FIXME: carlton/2002-10-14: Should we do some sort of fast search
+     first to see if the substring "(anonymous namespace)" occurs in
+     name at all?  */
+
+  for (beginning = name, end = cp_find_first_component (name);
+       *end == ':';
+       /* The "+ 2" is for ':'.  */
+       beginning = end + 2, end = cp_find_first_component (beginning))
+    {
+      if ((end - beginning) == ANONYMOUS_NAMESPACE_LEN
+         && strncmp (beginning, "(anonymous namespace)",
+                     ANONYMOUS_NAMESPACE_LEN) == 0)
+       /* We've found a component of the name that's an anonymous
+          namespace.  So add symbols in it to the namespace given by
+          the previous component if there is one, or to the global
+          namespace if there isn't.  */
+       add_using_directive (name,
+                            beginning == name ? 0 : beginning - name - 2,
+                            end - name);
+    }
 }
 
 /* Find a symbol named NAME on a LIST.  NAME need not be
@@ -166,6 +217,32 @@ find_symbol_in_list (struct pending *list, char *name, int length)
   return (NULL);
 }
 
+/* This adds a using directive to using_list.  NAME is the start of a
+   string that should contain the namespaces we want to add as initial
+   substrings, OUTER_INDEX is the end of the outer namespace, and
+   INNER_INDEX is the end of the inner namespace.  If the using
+   directive in question has already been added, don't add it
+   twice.  */
+
+void
+add_using_directive (const char *name, unsigned int outer_index,
+                    unsigned int inner_index)
+{
+  struct using_direct_node *current;
+
+  gdb_assert (outer_index < inner_index);
+
+  /* Has it already been added?  */
+
+  for (current = using_list; current; current = current->next)
+    if (strncmp (current->current->name, name, outer_index) == 0
+       && strncmp (current->current->name, name, inner_index) == 0)
+      return;
+
+  /* TODOTODO */
+}
+
+
 /* At end of reading syms, or in case of quit, really free as many
    `struct pending's as we can easily find. */
 
@@ -366,11 +443,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
               /* The '+ 2' is to skip the '::'.  */
               next = cp_find_first_component (next + 2))
            {
-             const char *namespace_name
-               = obsavestring (name, next - name,
-                               &objfile->symbol_obstack);
              BLOCK_USING (block)
-               = cp_add_using ("", namespace_name, BLOCK_USING (block),
+               = cp_add_using (name, 0, next - name, BLOCK_USING (block),
                                &objfile->symbol_obstack);
            }
 
@@ -803,6 +877,7 @@ start_symtab (char *name, char *dirname, CORE_ADDR start_addr)
   global_symbols = NULL;
   within_function = 0;
   have_line_numbers = 0;
+  using_list = NULL;
 
   /* Context stack is initially empty.  Allocate first one with room
      for 10 levels; reuse it forever afterward.  */
@@ -936,6 +1011,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr,
                    objfile);
       blockvector = make_blockvector (objfile);
+      /* TODOTODO */
+/*       BLOCK_USING (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK)) */
+/*     = cp_copy_usings_obstack (using_list, &objfile->symbol_obstack); */
+/*       cp_deep_free_usings (using_list); */
     }
 
 #ifndef PROCESS_LINENUMBER_HOOK
@@ -1066,6 +1145,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
   return symtab;
 }
 
+/* Search the block for global symbols indicating the presence of
+   anonymous namespaces; add using declarations for them, if
+   found.  */
+
 /* Push a context block.  Args are an identifying nesting level
    (checkable when you pop it), and the starting PC address of this
    context.  */
index 8a252cb2b4c63fbccf496f3df63efa004fbf8885..1e678d0101678ab938f4544a8cd51412139cfc95 100644 (file)
@@ -240,6 +240,9 @@ extern void add_symbol_to_list (struct symbol *symbol,
 extern struct symbol *find_symbol_in_list (struct pending *list,
                                           char *name, int length);
 
+extern void add_using_directive (const char *name, unsigned int outer_index,
+                                unsigned int inner_index);
+
 extern void finish_block (struct symbol *symbol,
                          struct pending **listhead,
                          struct pending_block *old_blocks,
index 09c5d542475dc8594c99e0a72628f39817f9894c..d5ca1a1364cc0a5f0db3c78e396247a232a558bf 100644 (file)
@@ -171,12 +171,14 @@ method_name_from_physname (const char *physname)
 }
 
 /* This allocates a new using_direct structure initialized to contain
-   OUTER and INNER, and puts it at the beginning of the linked list
-   given by NEXT.  It returns the resulting struct using_direct_node.
-   All memory is allocated using OBSTACK.  */
+   NAME, OUTER_LENGTH, and INNER_LENGTH, and puts it at the beginning
+   of the linked list given by NEXT.  It returns the resulting struct
+   using_direct_node.  All memory is allocated using OBSTACK.  */
 
 struct using_direct_node *
-cp_add_using (const char *outer, const char *inner,
+cp_add_using (const char *name,
+             unsigned short outer_length,
+             unsigned short inner_length,
              struct using_direct_node *next,
              struct obstack *obstack)
 {
@@ -185,8 +187,11 @@ cp_add_using (const char *outer, const char *inner,
   struct using_direct_node *retval
     = obstack_alloc (obstack, sizeof (struct using_direct_node));
 
-  current->outer = outer;
-  current->inner = inner;
+  gdb_assert (outer_length < inner_length);
+
+  current->name = name;
+  current->outer_length = outer_length;
+  current->inner_length = inner_length;
   retval->current = current;
   retval->next = next;
 
@@ -195,6 +200,7 @@ cp_add_using (const char *outer, const char *inner,
 
 /* This copies the using_direct_nodes in TOCOPY, using xmalloc, and
    sticks them onto a list ending in TAIL.  */
+
 struct using_direct_node *
 cp_copy_usings (struct using_direct_node *tocopy,
                struct using_direct_node *tail)
index 500521c2d8b78ff0810567d08e962712e98f46e8..31eab6e3ba652ca6c8ac666736178f2f148b2a80 100644 (file)
@@ -31,15 +31,19 @@ extern char *method_name_from_physname (const char *physname);
 extern const char *cp_find_first_component (const char *name);
 
 /* This is a struct to store data from "using directives" and similar
-   language constructs.  It contains two strings, OUTER and INNER;
-   both should be fully-qualified namespace names, OUTER should be a
-   strict initial substring of INNER, and it says that names in the
-   namespace INNER should be imported into namespace OUTER.  For
-   example, if it is used to represent the directive "using namespace
-   std;" then INNER should be "std" and new should be "".  For a more
+   language constructs.  NAME is a pointer to a string; its initial
+   substrings of length OUTER_LENGTH and INNER_LENGTH should both be
+   fully-qualified namespace names.  (And OUTER_LENGTH should be
+   strictly less than INNER_LENGTH).  The meaning is that names in the
+   inner namespace should be imported into outer.
+
+   For example, if it is used to represent the directive "using
+   namespace std;" then NAME should start with "std", INNER_LENGTH
+   should be 0, and OUTER_LENGTH should be "3".  For a more
    complicated example, if there is an anonymous namespace with a
-   named namespace A, then INNER should be "A::(anonymous namespace)"
-   and new should be "A".  */
+   named namespace A, then NAME should start with "A::(anonymous
+   namespace)", INNER_LENGTH should be 1, and OUTER_LENGTH should be
+   strlen ("A::(anonymous namespace)").  */
 
 /* FIXME: carlton/2002-10-07: That anonymous namespace example isn't
    that great, since it really depends not only on what the
@@ -50,8 +54,9 @@ extern const char *cp_find_first_component (const char *name);
 
 struct using_direct
 {
-  const char *outer;
-  const char *inner;
+  const char *name;
+  unsigned short outer_length;
+  unsigned short inner_length;
 };
 
 /* This is a struct for a linked list of using_direct's.  */
@@ -62,8 +67,9 @@ struct using_direct_node
   struct using_direct_node *next;
 };
 
-extern struct using_direct_node *cp_add_using (const char *outer,
-                                              const char *inner,
+extern struct using_direct_node *cp_add_using (const char *name,
+                                              unsigned short outer_length,
+                                              unsigned short inner_length,
                                               struct using_direct_node *next,
                                               struct obstack *obstack);
 
index 341f95f26c58fa39973357d42dc4fdbd4f461cac..5db5b6a559b55c6b53defb3ddc4c7a95a1f566ef 100644 (file)
@@ -126,6 +126,7 @@ struct symbol *lookup_symbol_aux_using (const char *name,
 
 static
 struct symbol *lookup_symbol_aux_using_loop (const char *prefix,
+                                            int prefix_len,
                                             const char *rest,
                                             struct using_direct_node *using,
                                             const char *mangled_name,
@@ -1066,19 +1067,15 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
       block = BLOCK_SUPERBLOCK (block);
     }
 
-  sym = lookup_symbol_aux_using_loop ("", name, using, mangled_name,
+  sym = lookup_symbol_aux_using_loop ("", 0, name, using, mangled_name,
                                      namespace, symtab);
   cp_free_usings (using);
   
   return sym;
 }
 
-/* This tries to look up a symbol whose name is the concatenation of
-   PREFIX, "::", and REST, where "::" is ommitted if PREFIX is the
-   empty string, applying the various using directives given in USING.
-   When applying the using directives, however, it assumes that the
-   part of the name given by PREFIX is immutable, so it only adds
-   symbols to namespaces whose names contain PREFIX.
+/* This tries to look up REST in the namespace given by the initial
+   substring of PREFIX of length PREFIX_LEN.
 
    Basically, assume that we have using directives adding A to the
    global namespace, adding A::inner to namespace A, and adding B to
@@ -1090,11 +1087,7 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
    A::foo, A::inner::foo, and B::foo.  (Though if the original caller
    to lookup_symbol had specified A::foo, we would want to look up
    stuff in A::A::foo, A::inner::A::foo, A::inner::foo, and
-   B::A::foo).
-
-   The reason why this treates the case of PREFIX = "" specially is to
-   avoid having to create temporary strings with "::" stuck on the end
-   of them.  */
+   B::A::foo).  */
 
 /* FIXME: carlton/2002-10-11: There are still some places where this
    will return false positives.  For example, if you have namespaces
@@ -1106,7 +1099,9 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
    for other reasons, but it will take a little while.)  */
 
 static struct symbol *
-lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
+lookup_symbol_aux_using_loop (const char *prefix,
+                             int prefix_len,
+                             const char *rest,
                              struct using_direct_node *using,
                              const char *mangled_name,
                              namespace_enum namespace,
@@ -1114,22 +1109,28 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
 {
   struct using_direct_node *current;
   struct symbol *sym;
-  int prefix_len = strlen (prefix);
 
   for (current = using; current; current = current->next)
     {
       /* First, see if the prefix matches the start of this using
         directive.  */
-      if (strncmp (prefix, current->current->outer, prefix_len) == 0)
+      if (prefix_len >= current->current->outer_length
+         && strncmp (prefix, current->current->name, prefix_len) == 0)
        {
          /* Great, it matches: now does the rest of the using
             directive match the rest of the name?  */
          
-         const char *rest_of_outer = current->current->outer + prefix_len;
-         /* Should we skip some colons?  */
+         const char *rest_of_outer = current->current->name + prefix_len;
+         int rest_of_outer_len
+           = current->current->outer_length - prefix_len;
+         /* Should we skip some colons?  (Should always be true
+            unless PREFIX_LEN is zero (and hence we're in the global
+            namespace.)  */
          if (*rest_of_outer == ':')
-           rest_of_outer += 2;
-         int rest_of_outer_len = strlen (rest_of_outer);
+           {
+             rest_of_outer += 2;
+             rest_of_outer_len -= 2;
+           }
          if (strncmp (rest_of_outer, rest, rest_of_outer_len) == 0)
            {
              /* Everything matches!  Yippee!  So apply the using
@@ -1138,12 +1139,14 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
              if (*new_rest == ':')
                new_rest += 2;
 
-             sym = lookup_symbol_aux_using_loop (current->current->inner,
-                                                 new_rest,
-                                                 using,
-                                                 mangled_name,
-                                                 namespace,
-                                                 symtab);
+             sym = lookup_symbol_aux_using_loop
+               (current->current->name,
+                current->current->inner_length,
+                new_rest,
+                using,
+                mangled_name,
+                namespace,
+                symtab);
              if (sym != NULL)
                return sym;
            }
@@ -1153,6 +1156,7 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
   /* We didn't find anything by applying any of the using directives
      that are still applicable; so let's see if we've got a match
      using the current name.  */
+  
   if (prefix_len == 0)
     {
       return lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, rest, mangled_name,
@@ -1162,7 +1166,7 @@ lookup_symbol_aux_using_loop (const char *prefix, const char *rest,
     {
       char *concatenated_name
        = xmalloc (prefix_len + 2 + strlen (rest) + 1);
-      strcpy (concatenated_name, prefix);
+      strncpy (concatenated_name, prefix, prefix_len);
       strcpy (concatenated_name + prefix_len, "::");
       strcpy (concatenated_name + prefix_len + 2, rest);
       sym = lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, concatenated_name,