Use gdbarch obstack to allocate the TYPE_NAME string in arch_type
[deliverable/binutils-gdb.git] / gdb / make-target-delegates
index f09f89d935dff15d272632ff08f61b1a7c8f9d43..88ea775919ccb782cbe7315e042d5b8c041a2480 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 
-# Copyright (C) 2013-2014 Free Software Foundation, Inc.
+# Copyright (C) 2013-2015 Free Software Foundation, Inc.
 #
 # This file is part of GDB.
 #
@@ -31,10 +31,10 @@ $ENDER = qr,^\s*};$,;
 $SYMBOL = qr,[a-zA-Z_][a-zA-Z0-9_]*,;
 # Match the name part of a method in struct target_ops.
 $NAME_PART = qr,\(\*(?<name>${SYMBOL}+)\)\s,;
-# Match the start of arguments to a method.
-$ARGS_PART = qr,(?<args>\(.*)$,;
-# Match indentation.
-$INTRO_PART = qr,^\s*,;
+# Match the arguments to a method.
+$ARGS_PART = qr,(?<args>\(.*\)),;
+# We strip the indentation so here we only need the caret.
+$INTRO_PART = qr,^,;
 
 # Match the return type when it is "ordinary".
 $SIMPLE_RETURN_PART = qr,[^\(]+,;
@@ -44,17 +44,27 @@ $VEC_RETURN_PART = qr,VEC\s*\([^\)]+\)[^\(]*,;
 # Match the TARGET_DEFAULT_* attribute for a method.
 $TARGET_DEFAULT_PART = qr,TARGET_DEFAULT_(?<style>[A-Z_]+)\s*\((?<default_arg>.*)\),;
 
-# Match the introductory line to a method definition.
+# Match the arguments and trailing attribute of a method definition.
+# Note we don't match the trailing ";".
+$METHOD_TRAILER = qr,\s*${TARGET_DEFAULT_PART}$,;
+
+# Match an entire method definition.
 $METHOD = ($INTRO_PART . "(?<return_type>" . $SIMPLE_RETURN_PART
           . "|" . $VEC_RETURN_PART . ")"
-          . $NAME_PART . $ARGS_PART);
+          . $NAME_PART . $ARGS_PART
+          . $METHOD_TRAILER);
 
-# Match the arguments and trailing attribute of a method definition.
-$METHOD_TRAILER = qr,(?<args>\(.+\))\s*${TARGET_DEFAULT_PART};$,;
+# Match TARGET_DEBUG_PRINTER in an argument type.
+# This must match the whole "sub-expression" including the parens.
+# Reference $1 must refer to the function argument.
+$TARGET_DEBUG_PRINTER = qr,\s*TARGET_DEBUG_PRINTER\s*\(([^)]*)\)\s*,;
 
 sub trim($) {
     my ($result) = @_;
-    $result =~ s,^\s*(\S*)\s*$,\1,;
+
+    $result =~ s,^\s+,,;
+    $result =~ s,\s+$,,;
+
     return $result;
 }
 
@@ -69,6 +79,30 @@ sub find_trigger() {
     die "could not find trigger line\n";
 }
 
+# Scan target.h and return a list of possible target_ops method entries.
+sub scan_target_h() {
+    my $all_the_text = '';
+
+    find_trigger();
+    while (<>) {
+       chomp;
+       # Skip the open brace.
+       next if /{/;
+       last if m/$ENDER/;
+
+       # Just in case somebody ever uses C99.
+       $_ =~ s,//.*$,,;
+       $_ = trim ($_);
+
+       $all_the_text .= $_;
+    }
+
+    # Now strip out the C comments.
+    $all_the_text =~ s,/\*(.*?)\*/,,g;
+
+    return split (/;/, $all_the_text);
+}
+
 # Parse arguments into a list.
 sub parse_argtypes($) {
     my ($typestr) = @_;
@@ -115,6 +149,8 @@ sub write_function_header($$@) {
     foreach $iter (@argtypes) {
        my $val = $iter;
 
+       $val =~ s/$TARGET_DEBUG_PRINTER//;
+
        if ($iter !~ m,\*$,) {
            $val .= ' ';
        }
@@ -188,50 +224,111 @@ sub write_tdefault($$$$@) {
     return tdname ($name);
 }
 
+sub munge_type($) {
+    my ($typename) = @_;
+    my ($result);
+
+    if ($typename =~ m/$TARGET_DEBUG_PRINTER/) {
+       $result = $1;
+    } else {
+       ($result = $typename) =~ s/\s+$//;
+       $result =~ s/[ ()]/_/g;
+       $result =~ s/[*]/p/g;
+       $result = 'target_debug_print_' . $result;
+    }
+
+    return $result;
+}
+
+# Write out a debug method.
+sub write_debugmethod($$$$@) {
+    my ($content, $style, $name, $return_type, @argtypes) = @_;
+
+    my ($debugname) = $name;
+    $debugname =~ s/to_/debug_/;
+    my ($targetname) = $name;
+    $targetname =~ s/to_/target_/;
+
+    my (@names) = write_function_header ($debugname, $return_type, @argtypes);
+
+    if ($return_type ne 'void') {
+       print "  $return_type result;\n";
+    }
+
+    print "  fprintf_unfiltered (gdb_stdlog, \"-> %s->$name (...)\\n\", debug_target.to_shortname);\n";
+
+    # Delegate to the beneath target.
+    print "  ";
+    if ($return_type ne 'void') {
+       print "result = ";
+    }
+    print "debug_target." . $name . " (";
+    my @names2 = @names;
+    @names2[0] = "&debug_target";
+    print join (', ', @names2);
+    print ");\n";
+
+    # Now print the arguments.
+    print "  fprintf_unfiltered (gdb_stdlog, \"<- %s->$name (\", debug_target.to_shortname);\n";
+    for my $i (0 .. $#argtypes) {
+       print "  fputs_unfiltered (\", \", gdb_stdlog);\n" if $i > 0;
+       my $printer = munge_type ($argtypes[$i]);
+       print "  $printer ($names2[$i]);\n";
+    }
+    if ($return_type ne 'void') {
+       print "  fputs_unfiltered (\") = \", gdb_stdlog);\n";
+       my $printer = munge_type ($return_type);
+       print "  $printer (result);\n";
+       print "  fputs_unfiltered (\"\\n\", gdb_stdlog);\n";
+    } else {
+       print "  fputs_unfiltered (\")\\n\", gdb_stdlog);\n";
+    }
+
+    if ($return_type ne 'void') {
+       print "  return result;\n";
+    }
+
+    print "}\n\n";
+
+    return $debugname;
+}
+
 print "/* THIS FILE IS GENERATED -*- buffer-read-only: t -*- */\n";
 print "/* vi:set ro: */\n\n";
 print "/* To regenerate this file, run:*/\n";
 print "/*      make-target-delegates target.h > target-delegates.c */\n";
 
-find_trigger();
+@lines = scan_target_h();
+
 
 %tdefault_names = ();
+%debug_names = ();
 @delegators = ();
-$current_line = '';
-while (<>) {
-    chomp;
-    last if m/$ENDER/;
-
-    if ($current_line ne '') {
-       s/^\s*//;
-       $current_line .= $_;
-    } elsif (m/$METHOD/) {
-       $name = $+{name};
-       $current_line = $+{args};
-       $return_type = trim ($+{return_type});
-    }
+foreach $current_line (@lines) {
+    next unless $current_line =~ m/$METHOD/;
 
-    if ($current_line =~ /\);\s*$/) {
-       if ($current_line =~ m,$METHOD_TRAILER,) {
-           $current_args = $+{args};
-           $tdefault = $+{default_arg};
-           $style = $+{style};
+    $name = $+{name};
+    $current_line = $+{args};
+    $return_type = trim ($+{return_type});
+    $current_args = $+{args};
+    $tdefault = $+{default_arg};
+    $style = $+{style};
 
-           @argtypes = parse_argtypes ($current_args);
+    @argtypes = parse_argtypes ($current_args);
 
-           # The first argument must be "this" to be delegatable.
-           if ($argtypes[0] =~ /\s*struct\s+target_ops\s*\*\s*/) {
-               write_delegator ($name, $return_type, @argtypes);
+    # The first argument must be "this" to be delegatable.
+    if ($argtypes[0] =~ /\s*struct\s+target_ops\s*\*\s*/) {
+       write_delegator ($name, $return_type, @argtypes);
 
-               push @delegators, $name;
+       push @delegators, $name;
 
-               $tdefault_names{$name} = write_tdefault ($tdefault, $style,
-                                                        $name, $return_type,
-                                                        @argtypes);
-           }
-       }
+       $tdefault_names{$name} = write_tdefault ($tdefault, $style,
+                                                $name, $return_type,
+                                                @argtypes);
 
-       $current_line = '';
+       $debug_names{$name} = write_debugmethod ($tdefault, $style,
+                                                $name, $return_type,
+                                                @argtypes);
     }
 }
 
@@ -250,4 +347,11 @@ print "static void\ninstall_dummy_methods (struct target_ops *ops)\n{\n";
 for $iter (@delegators) {
     print "  ops->" . $iter . " = " . $tdefault_names{$iter} . ";\n";
 }
+print "}\n\n";
+
+# The debug method code.
+print "static void\ninit_debug_target (struct target_ops *ops)\n{\n";
+for $iter (@delegators) {
+    print "  ops->" . $iter . " = " . $debug_names{$iter} . ";\n";
+}
 print "}\n";
This page took 0.028345 seconds and 4 git commands to generate.