gdb
[external/binutils.git] / gdb / cp-namespace.c
1 /* Helper routines for C++ support in GDB.
2    Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
3    Free Software Foundation, Inc.
4
5    Contributed by David Carlton and by Kealia, Inc.
6
7    This file is part of GDB.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #include "defs.h"
23 #include "cp-support.h"
24 #include "gdb_obstack.h"
25 #include "symtab.h"
26 #include "symfile.h"
27 #include "gdb_assert.h"
28 #include "block.h"
29 #include "objfiles.h"
30 #include "gdbtypes.h"
31 #include "dictionary.h"
32 #include "command.h"
33 #include "frame.h"
34 #include "buildsym.h"
35 #include "language.h"
36
37 static struct symbol *lookup_namespace_scope (const char *name,
38                                               const struct block *block,
39                                               const domain_enum domain,
40                                               const char *scope,
41                                               int scope_len);
42
43 static struct symbol *lookup_symbol_file (const char *name,
44                                           const struct block *block,
45                                           const domain_enum domain,
46                                           int anonymous_namespace);
47
48 static struct type *cp_lookup_transparent_type_loop (const char *name,
49                                                      const char *scope,
50                                                      int scope_len);
51
52 /* Check to see if SYMBOL refers to an object contained within an
53    anonymous namespace; if so, add an appropriate using directive.  */
54
55 /* Optimize away strlen ("(anonymous namespace)").  */
56
57 #define ANONYMOUS_NAMESPACE_LEN 21
58
59 void
60 cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
61 {
62   if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
63     {
64       const char *name = SYMBOL_DEMANGLED_NAME (symbol);
65       unsigned int previous_component;
66       unsigned int next_component;
67
68       /* Start with a quick-and-dirty check for mention of "(anonymous
69          namespace)".  */
70
71       if (!cp_is_anonymous (name))
72         return;
73
74       previous_component = 0;
75       next_component = cp_find_first_component (name + previous_component);
76
77       while (name[next_component] == ':')
78         {
79           if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN
80               && strncmp (name + previous_component,
81                           "(anonymous namespace)",
82                           ANONYMOUS_NAMESPACE_LEN) == 0)
83             {
84               int dest_len = (previous_component == 0
85                               ? 0 : previous_component - 2);
86               int src_len = next_component;
87
88               char *dest = alloca (dest_len + 1);
89               char *src = alloca (src_len + 1);
90
91               memcpy (dest, name, dest_len);
92               memcpy (src, name, src_len);
93
94               dest[dest_len] = '\0';
95               src[src_len] = '\0';
96
97               /* We've found a component of the name that's an
98                  anonymous namespace.  So add symbols in it to the
99                  namespace given by the previous component if there is
100                  one, or to the global namespace if there isn't.  */
101               cp_add_using_directive (dest, src, NULL, NULL,
102                                       &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
103             }
104           /* The "+ 2" is for the "::".  */
105           previous_component = next_component + 2;
106           next_component = (previous_component
107                             + cp_find_first_component (name
108                                                        + previous_component));
109         }
110     }
111 }
112
113
114 /* Add a using directive to using_directives.  If the using directive
115    in question has already been added, don't add it twice.
116
117    Create a new struct using_direct which imports the namespace SRC
118    into the scope DEST.  ALIAS is the name of the imported namespace
119    in the current scope.  If ALIAS is NULL then the namespace is known
120    by its original name.  DECLARATION is the name if the imported
121    varable if this is a declaration import (Eg. using A::x), otherwise
122    it is NULL.  The arguments are copied into newly allocated memory
123    so they can be temporaries.  */
124
125 void
126 cp_add_using_directive (const char *dest,
127                         const char *src,
128                         const char *alias,
129                         const char *declaration,
130                         struct obstack *obstack)
131 {
132   struct using_direct *current;
133   struct using_direct *new;
134   
135   /* Has it already been added?  */
136
137   for (current = using_directives; current != NULL; current = current->next)
138     {
139       if (strcmp (current->import_src, src) == 0
140           && strcmp (current->import_dest, dest) == 0
141           && ((alias == NULL && current->alias == NULL)
142               || (alias != NULL && current->alias != NULL
143                   && strcmp (alias, current->alias) == 0))
144           && ((declaration == NULL && current->declaration == NULL)
145               || (declaration != NULL && current->declaration != NULL
146                   && strcmp (declaration, current->declaration) == 0)))
147         return;
148     }
149
150   new = OBSTACK_ZALLOC (obstack, struct using_direct);
151
152   new->import_src = obsavestring (src, strlen (src), obstack);
153   new->import_dest = obsavestring (dest, strlen (dest), obstack);
154
155   if (alias != NULL)
156     new->alias = obsavestring (alias, strlen (alias), obstack);
157
158   if (declaration != NULL)
159     new->declaration = obsavestring (declaration, strlen (declaration),
160                                      obstack);
161
162   new->next = using_directives;
163   using_directives = new;
164 }
165
166 /* Record the namespace that the function defined by SYMBOL was
167    defined in, if necessary.  BLOCK is the associated block; use
168    OBSTACK for allocation.  */
169
170 void
171 cp_set_block_scope (const struct symbol *symbol,
172                     struct block *block,
173                     struct obstack *obstack,
174                     const char *processing_current_prefix,
175                     int processing_has_namespace_info)
176 {
177   if (processing_has_namespace_info)
178     {
179       block_set_scope
180         (block, obsavestring (processing_current_prefix,
181                               strlen (processing_current_prefix),
182                               obstack),
183          obstack);
184     }
185   else if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
186     {
187       /* Try to figure out the appropriate namespace from the
188          demangled name.  */
189
190       /* FIXME: carlton/2003-04-15: If the function in question is
191          a method of a class, the name will actually include the
192          name of the class as well.  This should be harmless, but
193          is a little unfortunate.  */
194
195       const char *name = SYMBOL_DEMANGLED_NAME (symbol);
196       unsigned int prefix_len = cp_entire_prefix_len (name);
197
198       block_set_scope (block,
199                        obsavestring (name, prefix_len, obstack),
200                        obstack);
201     }
202 }
203
204 /* Test whether or not NAMESPACE looks like it mentions an anonymous
205    namespace; return nonzero if so.  */
206
207 int
208 cp_is_anonymous (const char *namespace)
209 {
210   return (strstr (namespace, "(anonymous namespace)")
211           != NULL);
212 }
213
214 /* The C++-specific version of name lookup for static and global
215    names.  This makes sure that names get looked for in all namespaces
216    that are in scope.  NAME is the natural name of the symbol that
217    we're looking for, BLOCK is the block that we're searching within,
218    DOMAIN says what kind of symbols we're looking for, and if SYMTAB
219    is non-NULL, we should store the symtab where we found the symbol
220    in it.  */
221
222 struct symbol *
223 cp_lookup_symbol_nonlocal (const char *name,
224                            const struct block *block,
225                            const domain_enum domain)
226 {
227   struct symbol *sym;
228   const char *scope = block_scope (block);
229
230   sym = lookup_namespace_scope (name, block,
231                                 domain, scope, 0);
232   if (sym != NULL)
233     return sym;
234
235   return cp_lookup_symbol_namespace (scope, name,
236                                      block, domain);
237 }
238
239 /* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are
240    as in cp_lookup_symbol_nonlocal.  */
241
242 static struct symbol *
243 cp_lookup_symbol_in_namespace (const char *namespace,
244                                const char *name,
245                                const struct block *block,
246                                const domain_enum domain)
247 {
248   if (namespace[0] == '\0')
249     {
250       return lookup_symbol_file (name, block, domain, 0);
251     }
252   else
253     {
254       char *concatenated_name = alloca (strlen (namespace) + 2
255                                         + strlen (name) + 1);
256
257       strcpy (concatenated_name, namespace);
258       strcat (concatenated_name, "::");
259       strcat (concatenated_name, name);
260       return lookup_symbol_file (concatenated_name, block, domain,
261                                  cp_is_anonymous (namespace));
262     }
263 }
264
265 /* Used for cleanups to reset the "searched" flag incase
266    of an error.  */
267
268 static void
269 reset_directive_searched (void *data)
270 {
271   struct using_direct *direct = data;
272   direct->searched = 0;
273 }
274
275 /* Search for NAME by applying all import statements belonging to
276    BLOCK which are applicable in SCOPE.  If DECLARATION_ONLY the
277    search is restricted to using declarations.
278    Example:
279
280      namespace A {
281        int x;
282      }
283      using A::x;
284
285    If SEARCH_PARENTS the search will include imports which are
286    applicable in parents of SCOPE.
287    Example:
288
289      namespace A {
290        using namespace X;
291        namespace B {
292          using namespace Y;
293        }
294      }
295
296    If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of
297    namespaces X and Y will be considered.  If SEARCH_PARENTS is false
298    only the import of Y is considered.  */
299
300 struct symbol *
301 cp_lookup_symbol_imports (const char *scope,
302                           const char *name,
303                           const struct block *block,
304                           const domain_enum domain,
305                           const int declaration_only,
306                           const int search_parents)
307 {
308   struct using_direct *current;
309   struct symbol *sym = NULL;
310   int len;
311   int directive_match;
312   struct cleanup *searched_cleanup;
313
314   /* First, try to find the symbol in the given namespace.  */
315   if (!declaration_only)
316     sym = cp_lookup_symbol_in_namespace (scope, name,
317                                          block, domain);
318   
319   if (sym != NULL)
320     return sym;
321
322   /* Go through the using directives.  If any of them add new names to
323      the namespace we're searching in, see if we can find a match by
324      applying them.  */
325
326   for (current = block_using (block);
327        current != NULL;
328        current = current->next)
329     {
330       len = strlen (current->import_dest);
331       directive_match = (search_parents
332                          ? (strncmp (scope, current->import_dest,
333                                      strlen (current->import_dest)) == 0
334                             && (len == 0
335                                 || scope[len] == ':'
336                                 || scope[len] == '\0'))
337                          : strcmp (scope, current->import_dest) == 0);
338
339       /* If the import destination is the current scope or one of its
340          ancestors then it is applicable.  */
341       if (directive_match && !current->searched)
342         {
343         /* Mark this import as searched so that the recursive call
344            does not search it again.  */
345         current->searched = 1;
346         searched_cleanup = make_cleanup (reset_directive_searched,
347                                          current);
348
349         /* If there is an import of a single declaration, compare the
350            imported declaration (after optional renaming by its alias)
351            with the sought out name.  If there is a match pass
352            current->import_src as NAMESPACE to direct the search
353            towards the imported namespace.  */
354         if (current->declaration
355             && strcmp (name, current->alias
356                        ? current->alias : current->declaration) == 0)
357           sym = cp_lookup_symbol_in_namespace (current->import_src,
358                                                current->declaration,
359                                                block, domain);
360
361         /* If this is a DECLARATION_ONLY search or a symbol was found
362            or this import statement was an import declaration, the
363            search of this import is complete.  */
364         if (declaration_only || sym != NULL || current->declaration)
365           {
366             current->searched = 0;
367             discard_cleanups (searched_cleanup);
368
369             if (sym != NULL)
370               return sym;
371
372             continue;
373           }
374
375         if (current->alias != NULL
376             && strcmp (name, current->alias) == 0)
377           /* If the import is creating an alias and the alias matches
378              the sought name.  Pass current->import_src as the NAME to
379              direct the search towards the aliased namespace.  */
380           {
381             sym = cp_lookup_symbol_in_namespace (scope,
382                                                  current->import_src,
383                                                  block, domain);
384           }
385         else if (current->alias == NULL)
386           {
387             /* If this import statement creates no alias, pass
388                current->inner as NAMESPACE to direct the search
389                towards the imported namespace.  */
390             sym = cp_lookup_symbol_imports (current->import_src,
391                                             name, block,
392                                             domain, 0, 0);
393           }
394         current->searched = 0;
395         discard_cleanups (searched_cleanup);
396
397         if (sym != NULL)
398           return sym;
399         }
400     }
401
402   return NULL;
403 }
404
405 /* Helper function that searches an array of symbols for one named
406    NAME.  */
407
408 static struct symbol *
409 search_symbol_list (const char *name, int num,
410                     struct symbol **syms)
411 {
412   int i;
413
414   /* Maybe we should store a dictionary in here instead.  */
415   for (i = 0; i < num; ++i)
416     {
417       if (strcmp (name, SYMBOL_NATURAL_NAME (syms[i])) == 0)
418         return syms[i];
419     }
420   return NULL;
421 }
422
423 /* Like cp_lookup_symbol_imports, but if BLOCK is a function, it
424    searches through the template parameters of the function and the
425    function's type.  */
426
427 struct symbol *
428 cp_lookup_symbol_imports_or_template (const char *scope,
429                                       const char *name,
430                                       const struct block *block,
431                                       const domain_enum domain)
432 {
433   struct symbol *function = BLOCK_FUNCTION (block);
434
435   if (function != NULL && SYMBOL_LANGUAGE (function) == language_cplus)
436     {
437       int i;
438       struct cplus_specific *cps
439         = function->ginfo.language_specific.cplus_specific;
440
441       /* Search the function's template parameters.  */
442       if (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (function))
443         {
444           struct template_symbol *templ 
445             = (struct template_symbol *) function;
446           struct symbol *result;
447
448           result = search_symbol_list (name,
449                                        templ->n_template_arguments,
450                                        templ->template_arguments);
451           if (result != NULL)
452             return result;
453         }
454
455       /* Search the template parameters of the function's defining
456          context.  */
457       if (SYMBOL_NATURAL_NAME (function))
458         {
459           struct type *context;
460           char *name_copy = xstrdup (SYMBOL_NATURAL_NAME (function));
461           struct cleanup *cleanups = make_cleanup (xfree, name_copy);
462           const struct language_defn *lang = language_def (language_cplus);
463           struct gdbarch *arch = SYMBOL_SYMTAB (function)->objfile->gdbarch;
464           const struct block *parent = BLOCK_SUPERBLOCK (block);
465
466           while (1)
467             {
468               struct symbol *result;
469               unsigned int prefix_len = cp_entire_prefix_len (name_copy);
470
471               if (prefix_len == 0)
472                 context = NULL;
473               else
474                 {
475                   name_copy[prefix_len] = '\0';
476                   context = lookup_typename (lang, arch,
477                                              name_copy,
478                                              parent, 1);
479                 }
480
481               if (context == NULL)
482                 break;
483
484               result
485                 = search_symbol_list (name,
486                                       TYPE_N_TEMPLATE_ARGUMENTS (context),
487                                       TYPE_TEMPLATE_ARGUMENTS (context));
488               if (result != NULL)
489                 return result;
490             }
491
492           do_cleanups (cleanups);
493         }
494     }
495
496   return cp_lookup_symbol_imports (scope, name, block, domain, 1, 1);
497 }
498
499  /* Searches for NAME in the current namespace, and by applying
500     relevant import statements belonging to BLOCK and its parents.
501     SCOPE is the namespace scope of the context in which the search is
502     being evaluated.  */
503
504 struct symbol*
505 cp_lookup_symbol_namespace (const char *scope,
506                             const char *name,
507                             const struct block *block,
508                             const domain_enum domain)
509 {
510   struct symbol *sym;
511   
512   /* First, try to find the symbol in the given namespace.  */
513   sym = cp_lookup_symbol_in_namespace (scope, name,
514                                        block, domain);
515   if (sym != NULL)
516     return sym;
517
518   /* Search for name in namespaces imported to this and parent
519      blocks.  */
520   while (block != NULL)
521     {
522       sym = cp_lookup_symbol_imports (scope, name, block,
523                                       domain, 0, 1);
524
525       if (sym)
526         return sym;
527
528       block = BLOCK_SUPERBLOCK (block);
529     }
530
531   return NULL;
532 }
533
534 /* Lookup NAME at namespace scope (or, in C terms, in static and
535    global variables).  SCOPE is the namespace that the current
536    function is defined within; only consider namespaces whose length
537    is at least SCOPE_LEN.  Other arguments are as in
538    cp_lookup_symbol_nonlocal.
539
540    For example, if we're within a function A::B::f and looking for a
541    symbol x, this will get called with NAME = "x", SCOPE = "A::B", and
542    SCOPE_LEN = 0.  It then calls itself with NAME and SCOPE the same,
543    but with SCOPE_LEN = 1.  And then it calls itself with NAME and
544    SCOPE the same, but with SCOPE_LEN = 4.  This third call looks for
545    "A::B::x"; if it doesn't find it, then the second call looks for
546    "A::x", and if that call fails, then the first call looks for
547    "x".  */
548
549 static struct symbol *
550 lookup_namespace_scope (const char *name,
551                         const struct block *block,
552                         const domain_enum domain,
553                         const char *scope,
554                         int scope_len)
555 {
556   char *namespace;
557
558   if (scope[scope_len] != '\0')
559     {
560       /* Recursively search for names in child namespaces first.  */
561
562       struct symbol *sym;
563       int new_scope_len = scope_len;
564
565       /* If the current scope is followed by "::", skip past that.  */
566       if (new_scope_len != 0)
567         {
568           gdb_assert (scope[new_scope_len] == ':');
569           new_scope_len += 2;
570         }
571       new_scope_len += cp_find_first_component (scope + new_scope_len);
572       sym = lookup_namespace_scope (name, block, domain,
573                                     scope, new_scope_len);
574       if (sym != NULL)
575         return sym;
576     }
577
578   /* Okay, we didn't find a match in our children, so look for the
579      name in the current namespace.  */
580
581   namespace = alloca (scope_len + 1);
582   strncpy (namespace, scope, scope_len);
583   namespace[scope_len] = '\0';
584   return cp_lookup_symbol_in_namespace (namespace, name,
585                                         block, domain);
586 }
587
588 /* Look up NAME in BLOCK's static block and in global blocks.  If
589    ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located
590    within an anonymous namespace.  Other arguments are as in
591    cp_lookup_symbol_nonlocal.  */
592
593 static struct symbol *
594 lookup_symbol_file (const char *name,
595                     const struct block *block,
596                     const domain_enum domain,
597                     int anonymous_namespace)
598 {
599   struct symbol *sym = NULL;
600
601   sym = lookup_symbol_static (name, block, domain);
602   if (sym != NULL)
603     return sym;
604
605   if (anonymous_namespace)
606     {
607       /* Symbols defined in anonymous namespaces have external linkage
608          but should be treated as local to a single file nonetheless.
609          So we only search the current file's global block.  */
610
611       const struct block *global_block = block_global_block (block);
612       
613       if (global_block != NULL)
614         sym = lookup_symbol_aux_block (name, global_block, domain);
615     }
616   else
617     {
618       sym = lookup_symbol_global (name, block, domain);
619     }
620
621   return sym;
622 }
623
624 /* Look up a type named NESTED_NAME that is nested inside the C++
625    class or namespace given by PARENT_TYPE, from within the context
626    given by BLOCK.  Return NULL if there is no such nested type.  */
627
628 struct type *
629 cp_lookup_nested_type (struct type *parent_type,
630                        const char *nested_name,
631                        const struct block *block)
632 {
633   switch (TYPE_CODE (parent_type))
634     {
635     case TYPE_CODE_STRUCT:
636     case TYPE_CODE_NAMESPACE:
637     case TYPE_CODE_UNION:
638       {
639         /* NOTE: carlton/2003-11-10: We don't treat C++ class members
640            of classes like, say, data or function members.  Instead,
641            they're just represented by symbols whose names are
642            qualified by the name of the surrounding class.  This is
643            just like members of namespaces; in particular,
644            lookup_symbol_namespace works when looking them up.  */
645
646         const char *parent_name = TYPE_TAG_NAME (parent_type);
647         struct symbol *sym
648           = cp_lookup_symbol_in_namespace (parent_name, nested_name,
649                                            block, VAR_DOMAIN);
650         char *concatenated_name;
651
652         if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
653           return SYMBOL_TYPE (sym);
654
655         /* Now search all static file-level symbols.  Not strictly
656            correct, but more useful than an error.  We do not try to
657            guess any imported namespace as even the fully specified
658            namespace seach is is already not C++ compliant and more
659            assumptions could make it too magic.  */
660
661         concatenated_name = alloca (strlen (parent_name) + 2
662                                     + strlen (nested_name) + 1);
663         sprintf (concatenated_name, "%s::%s",
664                  parent_name, nested_name);
665         sym = lookup_static_symbol_aux (concatenated_name,
666                                         VAR_DOMAIN);
667         if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
668           return SYMBOL_TYPE (sym);
669
670         return NULL;
671       }
672     default:
673       internal_error (__FILE__, __LINE__,
674                       _("cp_lookup_nested_type called "
675                         "on a non-aggregate type."));
676     }
677 }
678
679 /* The C++-version of lookup_transparent_type.  */
680
681 /* FIXME: carlton/2004-01-16: The problem that this is trying to
682    address is that, unfortunately, sometimes NAME is wrong: it may not
683    include the name of namespaces enclosing the type in question.
684    lookup_transparent_type gets called when the type in question
685    is a declaration, and we're trying to find its definition; but, for
686    declarations, our type name deduction mechanism doesn't work.
687    There's nothing we can do to fix this in general, I think, in the
688    absence of debug information about namespaces (I've filed PR
689    gdb/1511 about this); until such debug information becomes more
690    prevalent, one heuristic which sometimes looks is to search for the
691    definition in namespaces containing the current namespace.
692
693    We should delete this functions once the appropriate debug
694    information becomes more widespread.  (GCC 3.4 will be the first
695    released version of GCC with such information.)  */
696
697 struct type *
698 cp_lookup_transparent_type (const char *name)
699 {
700   /* First, try the honest way of looking up the definition.  */
701   struct type *t = basic_lookup_transparent_type (name);
702   const char *scope;
703
704   if (t != NULL)
705     return t;
706
707   /* If that doesn't work and we're within a namespace, look there
708      instead.  */
709   scope = block_scope (get_selected_block (0));
710
711   if (scope[0] == '\0')
712     return NULL;
713
714   return cp_lookup_transparent_type_loop (name, scope, 0);
715 }
716
717 /* Lookup the type definition associated to NAME in namespaces/classes
718    containing SCOPE whose name is strictly longer than LENGTH.  LENGTH
719    must be the index of the start of a component of SCOPE.  */
720
721 static struct type *
722 cp_lookup_transparent_type_loop (const char *name,
723                                  const char *scope,
724                                  int length)
725 {
726   int scope_length = length + cp_find_first_component (scope + length);
727   char *full_name;
728
729   /* If the current scope is followed by "::", look in the next
730      component.  */
731   if (scope[scope_length] == ':')
732     {
733       struct type *retval
734         = cp_lookup_transparent_type_loop (name, scope,
735                                            scope_length + 2);
736
737       if (retval != NULL)
738         return retval;
739     }
740
741   full_name = alloca (scope_length + 2 + strlen (name) + 1);
742   strncpy (full_name, scope, scope_length);
743   strncpy (full_name + scope_length, "::", 2);
744   strcpy (full_name + scope_length + 2, name);
745
746   return basic_lookup_transparent_type (full_name);
747 }
748
749 /* This used to do something but was removed when it became
750    obsolete.  */
751
752 static void
753 maintenance_cplus_namespace (char *args, int from_tty)
754 {
755   printf_unfiltered (_("The `maint namespace' command was removed.\n"));
756 }
757
758 /* Provide a prototype to silence -Wmissing-prototypes.  */
759 extern initialize_file_ftype _initialize_cp_namespace;
760
761 void
762 _initialize_cp_namespace (void)
763 {
764   struct cmd_list_element *cmd;
765
766   cmd = add_cmd ("namespace", class_maintenance,
767                  maintenance_cplus_namespace,
768                  _("Deprecated placeholder for removed functionality."),
769                  &maint_cplus_cmd_list);
770   deprecate_cmd (cmd, NULL);
771 }