gdb
authorTom Tromey <tromey@redhat.com>
Tue, 30 Sep 2008 17:21:28 +0000 (17:21 +0000)
committerTom Tromey <tromey@redhat.com>
Tue, 30 Sep 2008 17:21:28 +0000 (17:21 +0000)
PR gdb/2484:
* symtab.c (struct add_macro_name_data): New struct.
(add_macro_name): New function.
(default_make_symbol_completion_list): Complete macro names.
* scm-lang.c (scm_language_defn): Update.
* p-lang.c (pascal_language_defn): Update.
* objc-lang.c (objc_language_defn): Update.
* macrotab.h (macro_callback_fn): Add user_data argument.
(macro_for_each): Likewise.
(macro_for_each_in_scope): Declare.
* macrotab.c: (struct macro_for_each_data): New struct.
(foreach_macro): Use it.
(macro_for_each): Likewise.
(foreach_macro_in_scope): New function.
(macro_for_each_in_scope): Likewise.
* macrocmd.c (print_one_macro): Add argument.
(macro_list_command): Pass NULL to macro_for_each.
* m2-lang.c (m2_language_defn): Update.
* language.h (struct language_defn) <la_macro_expansion>: New
field.
(macro_expansion): New enum.
* language.c (unknown_language_defn): Update.  Fix order of
initializers.
(auto_language_defn): Likewise.
(local_language_defn): Update.
* jv-lang.c (java_language_defn): Update.
* f-lang.c (f_language_defn): Update.
* c-lang.c (c_language_defn): Update.
(cplus_language_defn): Likewise.
(asm_language_defn): Likewise.
(minimal_language_defn): Likewise.
* ada-lang.c (ada_language_defn): Update.
gdb/testsuite
* gdb.base/macscp.exp: Add completion tests.
* gdb.base/macscp1.c (FIFTY_SEVEN): New macro.
(TWENTY_THREE): Likewise.
(FORTY_EIGHT): Likewise.

18 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/c-lang.c
gdb/f-lang.c
gdb/jv-lang.c
gdb/language.c
gdb/language.h
gdb/m2-lang.c
gdb/macrocmd.c
gdb/macrotab.c
gdb/macrotab.h
gdb/objc-lang.c
gdb/p-lang.c
gdb/scm-lang.c
gdb/symtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.base/macscp.exp
gdb/testsuite/gdb.base/macscp1.c

index dfa6df18b1d187ef8a0c6aa5b0788066f73dae26..6d33cbbe3cc6d5649dd7820a55862773b1048984 100644 (file)
@@ -1,3 +1,38 @@
+2008-09-30  Tom Tromey  <tromey@redhat.com>
+
+       PR gdb/2484:
+       * symtab.c (struct add_macro_name_data): New struct.
+       (add_macro_name): New function.
+       (default_make_symbol_completion_list): Complete macro names.
+       * scm-lang.c (scm_language_defn): Update.
+       * p-lang.c (pascal_language_defn): Update.
+       * objc-lang.c (objc_language_defn): Update.
+       * macrotab.h (macro_callback_fn): Add user_data argument.
+       (macro_for_each): Likewise.
+       (macro_for_each_in_scope): Declare.
+       * macrotab.c: (struct macro_for_each_data): New struct.
+       (foreach_macro): Use it.
+       (macro_for_each): Likewise.
+       (foreach_macro_in_scope): New function.
+       (macro_for_each_in_scope): Likewise.
+       * macrocmd.c (print_one_macro): Add argument.
+       (macro_list_command): Pass NULL to macro_for_each.
+       * m2-lang.c (m2_language_defn): Update.
+       * language.h (struct language_defn) <la_macro_expansion>: New
+       field.
+       (macro_expansion): New enum.
+       * language.c (unknown_language_defn): Update.  Fix order of
+       initializers.
+       (auto_language_defn): Likewise.
+       (local_language_defn): Update.
+       * jv-lang.c (java_language_defn): Update.
+       * f-lang.c (f_language_defn): Update.
+       * c-lang.c (c_language_defn): Update.
+       (cplus_language_defn): Likewise.
+       (asm_language_defn): Likewise.
+       (minimal_language_defn): Likewise.
+       * ada-lang.c (ada_language_defn): Update.
+
 2008-09-30  Joel Brobecker  <brobecker@adacore.com>
 
        * dwarf2read.c (dwarf2_get_subprogram_pc_bounds): New function.
index d4d7dc0352765e1a523bb671fca5a73fa4d23b5c..c425c80d41f3fe0ebdc3e23def656683c5ea7a4e 100644 (file)
@@ -10935,6 +10935,7 @@ const struct language_defn ada_language_defn = {
   case_sensitive_on,            /* Yes, Ada is case-insensitive, but
                                    that's not quite what this means.  */
   array_row_major,
+  macro_expansion_no,
   &ada_exp_descriptor,
   parse,
   ada_error,
index a9cd9c2970ee944e0a4fb26d7385e0930ff2c1bc..a978b17ebc4da498ee01fbfcb63d67a6b3030a84 100644 (file)
@@ -392,6 +392,7 @@ const struct language_defn c_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
   c_preprocess_and_parse,
   c_error,
@@ -509,6 +510,7 @@ const struct language_defn cplus_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
   c_preprocess_and_parse,
   c_error,
@@ -545,6 +547,7 @@ const struct language_defn asm_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
   c_preprocess_and_parse,
   c_error,
@@ -586,6 +589,7 @@ const struct language_defn minimal_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
   c_preprocess_and_parse,
   c_error,
index 4e2f3c44ecd2e3ddd0c3e87ecdca9e3d97613a1d..736d6c60b0ad2341956cfafc5ddd31d1ecc70132 100644 (file)
@@ -316,6 +316,7 @@ const struct language_defn f_language_defn =
   type_check_on,
   case_sensitive_off,
   array_column_major,
+  macro_expansion_no,
   &exp_descriptor_standard,
   f_parse,                     /* parser */
   f_error,                     /* parser error function */
index 69570b43bb41f49bc68eb577fc9a83da8bec0f64..0470eef69dd66f904afb894463daaa47a21ba6bf 100644 (file)
@@ -1102,6 +1102,7 @@ const struct language_defn java_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_no,
   &exp_descriptor_java,
   java_parse,
   java_error,
index 0b21dc3ccc207a55cc0bb2e03d597b6048053813..121fc55c6e1e4d0ce75baab24eb5a97987f63623 100644 (file)
@@ -1135,8 +1135,9 @@ const struct language_defn unknown_language_defn =
   language_unknown,
   range_check_off,
   type_check_off,
-  array_row_major,
   case_sensitive_on,
+  array_row_major,
+  macro_expansion_no,
   &exp_descriptor_standard,
   unk_lang_parser,
   unk_lang_error,
@@ -1172,8 +1173,9 @@ const struct language_defn auto_language_defn =
   language_auto,
   range_check_off,
   type_check_off,
-  array_row_major,
   case_sensitive_on,
+  array_row_major,
+  macro_expansion_no,
   &exp_descriptor_standard,
   unk_lang_parser,
   unk_lang_error,
@@ -1210,6 +1212,7 @@ const struct language_defn local_language_defn =
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_no,
   &exp_descriptor_standard,
   unk_lang_parser,
   unk_lang_error,
index ba28540b564ea612e05458cc20a7bfba5d755462..cc10ff27422a59f065cd42c0c79510b63fcac0dd 100644 (file)
@@ -105,6 +105,17 @@ extern enum case_sensitivity
     case_sensitive_on, case_sensitive_off
   }
 case_sensitivity;
+
+
+/* macro_expansion ==
+   macro_expansion_no:  No macro expansion is available
+   macro_expansion_c:   C-like macro expansion is available  */
+
+enum macro_expansion
+  {
+    macro_expansion_no, macro_expansion_c
+  };
+
 \f
 /* Per architecture (OS/ABI) language information.  */
 
@@ -150,6 +161,9 @@ struct language_defn
     /* Multi-dimensional array ordering */
     enum array_ordering la_array_ordering;
 
+    /* Style of macro expansion, if any, supported by this language.  */
+    enum macro_expansion la_macro_expansion;
+
     /* Definitions related to expression printing, prefixifying, and
        dumping */
 
index 2b3ca6ab47a2aa784ea1a9fba3caa347735420d6..ea59403a24ad49afc2582600058573efc57fd25b 100644 (file)
@@ -367,6 +367,7 @@ const struct language_defn m2_language_defn =
   type_check_on,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_no,
   &exp_descriptor_modula2,
   m2_parse,                    /* parser */
   m2_error,                    /* parser error function */
index c9ab440f794b4514abfd222cc6049c9101ae0455..56e9a48ff22166b7dc0831a9c5a3c5232f80dcb1 100644 (file)
@@ -345,7 +345,8 @@ macro_undef_command (char *exp, int from_tty)
 
 
 static void
-print_one_macro (const char *name, const struct macro_definition *macro)
+print_one_macro (const char *name, const struct macro_definition *macro,
+                void *ignore)
 {
   fprintf_filtered (gdb_stdout, "macro define %s", name);
   if (macro->kind == macro_function_like)
@@ -366,7 +367,7 @@ print_one_macro (const char *name, const struct macro_definition *macro)
 static void
 macro_list_command (char *exp, int from_tty)
 {
-  macro_for_each (macro_user_macros, print_one_macro);
+  macro_for_each (macro_user_macros, print_one_macro, NULL);
 }
 
 
index 7633c98d4f5c4bb0b66ed59c2fd8277121a3266e..c33c028d225a5009f6000f7c325e2dbb8f78739a 100644 (file)
@@ -887,25 +887,71 @@ macro_definition_location (struct macro_source_file *source,
 }
 
 
+/* The type for callback data for iterating the splay tree in
+   macro_for_each and macro_for_each_in_scope.  Only the latter uses
+   the FILE and LINE fields.  */
+struct macro_for_each_data
+{
+  macro_callback_fn fn;
+  void *user_data;
+  struct macro_source_file *file;
+  int line;
+};
+
 /* Helper function for macro_for_each.  */
 static int
-foreach_macro (splay_tree_node node, void *fnp)
+foreach_macro (splay_tree_node node, void *arg)
 {
-  macro_callback_fn *fn = (macro_callback_fn *) fnp;
+  struct macro_for_each_data *datum = (struct macro_for_each_data *) arg;
   struct macro_key *key = (struct macro_key *) node->key;
   struct macro_definition *def = (struct macro_definition *) node->value;
-  (**fn) (key->name, def);
+  (*datum->fn) (key->name, def, datum->user_data);
   return 0;
 }
 
 /* Call FN for every macro in TABLE.  */
 void
-macro_for_each (struct macro_table *table, macro_callback_fn fn)
+macro_for_each (struct macro_table *table, macro_callback_fn fn,
+               void *user_data)
+{
+  struct macro_for_each_data datum;
+  datum.fn = fn;
+  datum.user_data = user_data;
+  datum.file = NULL;
+  datum.line = 0;
+  splay_tree_foreach (table->definitions, foreach_macro, &datum);
+}
+
+static int
+foreach_macro_in_scope (splay_tree_node node, void *info)
 {
-  /* Note that we pass in the address of 'fn' because, pedantically
-     speaking, we can't necessarily cast a pointer-to-function to a
-     void*.  */
-  splay_tree_foreach (table->definitions, foreach_macro, &fn);
+  struct macro_for_each_data *datum = (struct macro_for_each_data *) info;
+  struct macro_key *key = (struct macro_key *) node->key;
+  struct macro_definition *def = (struct macro_definition *) node->value;
+
+  /* See if this macro is defined before the passed-in line, and
+     extends past that line.  */
+  if (compare_locations (key->start_file, key->start_line,
+                        datum->file, datum->line) < 0
+      && (!key->end_file
+         || compare_locations (key->end_file, key->end_line,
+                               datum->file, datum->line) >= 0))
+    (*datum->fn) (key->name, def, datum->user_data);
+  return 0;
+}
+
+/* Call FN for every macro is visible in SCOPE.  */
+void
+macro_for_each_in_scope (struct macro_source_file *file, int line,
+                        macro_callback_fn fn, void *user_data)
+{
+  struct macro_for_each_data datum;
+  datum.fn = fn;
+  datum.user_data = user_data;
+  datum.file = file;
+  datum.line = line;
+  splay_tree_foreach (file->table->definitions,
+                     foreach_macro_in_scope, &datum);
 }
 
 
index 71f1d3ed5472e685c466531a922b4ccf0db3878b..25b4c5f5f3c70a3c33b18e3fcae4c4129084a334 100644 (file)
@@ -305,12 +305,24 @@ struct macro_source_file *(macro_definition_location
                             int *definition_line));
 
 /* Callback function when walking a macro table.  NAME is the name of
-   the macro, and DEFINITION is the definition.  */
+   the macro, and DEFINITION is the definition.  USER_DATA is an
+   arbitrary pointer which is passed by the caller to macro_for_each
+   or macro_for_each_in_scope.  */
 typedef void (*macro_callback_fn) (const char *name,
-                                  const struct macro_definition *definition);
-
-/* Call the function FN for each macro in the macro table TABLE.  */
-void macro_for_each (struct macro_table *table, macro_callback_fn fn);
+                                  const struct macro_definition *definition,
+                                  void *user_data);
+
+/* Call the function FN for each macro in the macro table TABLE.
+   USER_DATA is passed, untranslated, to FN.  */
+void macro_for_each (struct macro_table *table, macro_callback_fn fn,
+                    void *user_data);
+
+/* Call the function FN for each macro that is visible in a given
+   scope.  The scope is represented by FILE and LINE.  USER_DATA is
+   passed, untranslated, to FN.  */
+void macro_for_each_in_scope (struct macro_source_file *file, int line,
+                             macro_callback_fn fn,
+                             void *user_data);
 
 
 #endif /* MACROTAB_H */
index 46081688264a6f811d6027a1ee2b75890a7f7f03..553080a113a5239b307b6ee019f09bb52aaddc49 100644 (file)
@@ -504,6 +504,7 @@ const struct language_defn objc_language_defn = {
   type_check_off,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_c,
   &exp_descriptor_standard,
   objc_parse,
   objc_error,
index b829f8d4aad1302572f6b2d453b0df572b6fba51..7ecdd8d08f0b5ab0ea1e89639a365b6e3215703a 100644 (file)
@@ -406,6 +406,7 @@ const struct language_defn pascal_language_defn =
   type_check_on,
   case_sensitive_on,
   array_row_major,
+  macro_expansion_no,
   &exp_descriptor_standard,
   pascal_parse,
   pascal_error,
index 607efb6e5d1f29e8a19860a57f251f1813ca339f..42d25023874653d7ea930868249a95c2c536a24e 100644 (file)
@@ -246,6 +246,7 @@ const struct language_defn scm_language_defn =
   type_check_off,
   case_sensitive_off,
   array_row_major,
+  macro_expansion_no,
   &exp_descriptor_scm,
   scm_parse,
   c_error,
index 10987e25481730280d6ab9c893891843c0c69154..437d4142ec4826942f9b7e0ea7336780bc2fe801 100644 (file)
@@ -58,6 +58,8 @@
 #include "observer.h"
 #include "gdb_assert.h"
 #include "solist.h"
+#include "macrotab.h"
+#include "macroscope.h"
 
 /* Prototypes for local functions */
 
@@ -3640,6 +3642,29 @@ language_search_unquoted_string (char *text, char *p)
   return p;
 }
 
+/* Type of the user_data argument passed to add_macro_name.  The
+   contents are simply whatever is needed by
+   completion_list_add_name.  */
+struct add_macro_name_data
+{
+  char *sym_text;
+  int sym_text_len;
+  char *text;
+  char *word;
+};
+
+/* A callback used with macro_for_each and macro_for_each_in_scope.
+   This adds a macro's name to the current completion list.  */
+static void
+add_macro_name (const char *name, const struct macro_definition *ignore,
+               void *user_data)
+{
+  struct add_macro_name_data *datum = (struct add_macro_name_data *) user_data;
+  completion_list_add_name ((char *) name,
+                           datum->sym_text, datum->sym_text_len,
+                           datum->text, datum->word);
+}
+
 char **
 default_make_symbol_completion_list (char *text, char *word)
 {
@@ -3826,6 +3851,35 @@ default_make_symbol_completion_list (char *text, char *word)
       }
   }
 
+  if (current_language->la_macro_expansion == macro_expansion_c)
+    {
+      struct macro_scope *scope;
+      struct add_macro_name_data datum;
+
+      datum.sym_text = sym_text;
+      datum.sym_text_len = sym_text_len;
+      datum.text = text;
+      datum.word = word;
+
+      /* Add any macros visible in the default scope.  Note that this
+        may yield the occasional wrong result, because an expression
+        might be evaluated in a scope other than the default.  For
+        example, if the user types "break file:line if <TAB>", the
+        resulting expression will be evaluated at "file:line" -- but
+        at there does not seem to be a way to detect this at
+        completion time.  */
+      scope = default_macro_scope ();
+      if (scope)
+       {
+         macro_for_each_in_scope (scope->file, scope->line,
+                                  add_macro_name, &datum);
+         xfree (scope);
+       }
+
+      /* User-defined macros are always visible.  */
+      macro_for_each (macro_user_macros, add_macro_name, &datum);
+    }
+
   return (return_val);
 }
 
index 60adacf7da16b4617acba15df7981c9a1a671eed..d4d08115df461dabad70375ecb73e00727d861c5 100644 (file)
@@ -1,3 +1,10 @@
+2008-09-30  Tom Tromey  <tromey@redhat.com>
+
+       * gdb.base/macscp.exp: Add completion tests.
+       * gdb.base/macscp1.c (FIFTY_SEVEN): New macro.
+       (TWENTY_THREE): Likewise.
+       (FORTY_EIGHT): Likewise.
+
 2008-09-30  Tom Tromey  <tromey@redhat.com>
 
        * gdb.base/macscp.exp: Change "M" to "MACRO_TO_EXPAND"
index 152e006d4ff54cfc0c07f60a1a6df183f674a6f5..2a43a28eb2dcfe76cefd26da5309de9cc4f32c5c 100644 (file)
@@ -480,6 +480,76 @@ gdb_test "macro undef" \
     "usage: macro undef.*" \
     "macro undef with no arguments"
 
+# Completion tests.
+
+# The macro FIFTY_SEVEN is in scope at this point.
+send_gdb "p FIFTY_\t"
+gdb_expect  {
+        -re "^p FIFTY_SEVEN $"\
+            { send_gdb "\n"
+              gdb_expect {
+                      -re "^.* = 57.*$gdb_prompt $"\
+                                        { pass "complete 'p FIFTY_SEVEN'"}
+                      -re ".*$gdb_prompt $" { fail "complete 'p FIFTY_SEVEN'"}
+                      timeout           {fail "(timeout) complete 'p FIFTY_SEVEN'"}
+                     }
+            }
+        -re ".*$gdb_prompt $"       { fail "complete 'p FIFTY_SEVEN'" }
+        timeout         { fail "(timeout) complete 'p FIFTY_SEVEN' 2" }
+        }
+
+# The macro TWENTY_THREE is not in scope.
+send_gdb "p TWENTY_\t"
+gdb_expect  {
+        -re "^p TWENTY_\\\x07$"\
+            { send_gdb "\n"
+              gdb_expect {
+                      -re "No symbol \"TWENTY_\" in current context\\..*$gdb_prompt $"\
+                                        { pass "complete 'p TWENTY_'"}
+                      -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_'"}
+                      timeout           {fail "(timeout) complete 'p TWENTY_'"}
+                     }
+            }
+        -re ".*$gdb_prompt $"       { fail "complete 'p TWENTY_'" }
+        timeout         { fail "(timeout) complete 'p TWENTY_' 2" }
+        }
+
+# The macro FORTY_EIGHT was undefined and thus is not in scope.
+send_gdb "p FORTY_\t"
+gdb_expect  {
+        -re "^p FORTY_\\\x07$"\
+            { send_gdb "\n"
+              gdb_expect {
+                      -re "No symbol \"FORTY_\" in current context\\..*$gdb_prompt $"\
+                                        { pass "complete 'p FORTY_'"}
+                      -re ".*$gdb_prompt $" { fail "complete 'p FORTY_'"}
+                      timeout           {fail "(timeout) complete 'p FORTY_'"}
+                     }
+            }
+        -re ".*$gdb_prompt $"       { fail "complete 'p FORTY_'" }
+        timeout         { fail "(timeout) complete 'p FORTY_' 2" }
+        }
+
+gdb_test "macro define TWENTY_THREE 25" \
+  "" \
+  "defining TWENTY_THREE"
+
+# User-defined macros are always in scope.
+send_gdb "p TWENTY_\t"
+gdb_expect  {
+        -re "^p TWENTY_THREE $"\
+            { send_gdb "\n"
+              gdb_expect {
+                      -re "^.* = 25.*$gdb_prompt $"\
+                                        { pass "complete 'p TWENTY_THREE'"}
+                      -re ".*$gdb_prompt $" { fail "complete 'p TWENTY_THREE'"}
+                      timeout           {fail "(timeout) complete 'p TWENTY_THREE'"}
+                     }
+            }
+        -re ".*$gdb_prompt $"       { fail "complete 'p TWENTY_THREE'" }
+        timeout         { fail "(timeout) complete 'p TWENTY_THREE' 2" }
+        }
+
 # Splicing tests.
 
 gdb_test "macro expand SPLICE(x, y)" \
index 0be78c6d9c1c6098e1d5fac9399e56f92d81f8ff..40f1217b2d615dae11d70123627015bab1993ae2 100644 (file)
@@ -5,6 +5,11 @@
 #define STRINGIFY(a) INNER_STRINGIFY(a)
 #define INNER_STRINGIFY(a) #a
 
+#define FIFTY_SEVEN 57
+
+#define FORTY_EIGHT 48
+#undef  FORTY_EIGHT
+
 /* A macro named UNTIL_<func> is #defined until just before the
    definition of the function <func>.
 
@@ -75,6 +80,8 @@ macscp_expr (void)
   foo = 2;
 }
 
+#define TWENTY_THREE 23
+
 int
 main (int argc, char **argv)
 {