Skip to content

Commit f87d980

Browse files
committed
genhtml: Rework c++filt name demangling
When running genhtml with command line option --demangle-cpp, do not merge function call data based on demangled function names. Instead mark duplicate function entries in the function view with a version suffix (.<number>). This resolves problems with entries for functions that demangle to the same name, but begin on different lines according to GCC (e.g. virtual destructors). Reported-by: Lukasz Czajczyk <[email protected]> Signed-off-by: Peter Oberparleiter <[email protected]>
1 parent 2e87217 commit f87d980

File tree

1 file changed

+51
-58
lines changed

1 file changed

+51
-58
lines changed

bin/genhtml

Lines changed: 51 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -805,60 +805,6 @@ sub rename_functions($$)
805805
}
806806
}
807807

808-
#
809-
# demangle_cpp(INFO)
810-
#
811-
# Demangle all function names found in INFO.
812-
#
813-
sub demangle_cpp($)
814-
{
815-
my ($info) = @_;
816-
my $fn_list = get_fn_list($info);
817-
my @fn_list_demangled;
818-
my $tmpfile;
819-
my $handle;
820-
my %demangled;
821-
my $changed;
822-
823-
# Nothing to do
824-
return if (!@$fn_list);
825-
826-
# Write list to temp file
827-
(undef, $tmpfile) = tempfile();
828-
die("ERROR: could not create temporary file") if (!defined($tmpfile));
829-
open($handle, ">", $tmpfile) or
830-
die("ERROR: could not write to $tmpfile: $!\n");
831-
print($handle join("\n", @$fn_list));
832-
close($handle);
833-
834-
# Run c++ filt on tempfile file and parse output, creating a hash
835-
open($handle, "-|", "c++filt < $tmpfile") or
836-
die("ERROR: could not run c++filt: $!\n");
837-
@fn_list_demangled = <$handle>;
838-
close($handle);
839-
unlink($tmpfile) or
840-
warn("WARNING: could not remove temporary file $tmpfile: $!\n");
841-
842-
if (scalar(@fn_list_demangled) != scalar(@$fn_list)) {
843-
die("ERROR: c++filt output not as expected (".
844-
scalar(@fn_list_demangled)." vs ".
845-
scalar(@$fn_list).") lines\n");
846-
}
847-
848-
# Build old_name -> new_name
849-
$changed = 0;
850-
for (my $i = 0; $i < scalar(@$fn_list); $i++) {
851-
chomp($fn_list_demangled[$i]);
852-
$demangled{$fn_list->[$i]} = $fn_list_demangled[$i];
853-
$changed++ if ($fn_list->[$i] ne $fn_list_demangled[$i]);
854-
}
855-
856-
info("Demangling $changed function names\n");
857-
858-
# Change all occurrences of function names in INFO
859-
rename_functions($info, \%demangled);
860-
}
861-
862808
#
863809
# gen_html()
864810
#
@@ -916,9 +862,6 @@ sub gen_html()
916862
%info_data = %{apply_baseline(\%info_data, \%base_data)};
917863
}
918864

919-
# Demangle C++ function names if requested
920-
demangle_cpp(\%info_data) if ($demangle_cpp);
921-
922865
@dir_list = get_dir_list(keys(%info_data));
923866

924867
if ($no_prefix)
@@ -5363,6 +5306,47 @@ sub funcview_get_sorted($$$)
53635306
} keys(%{$sumfncdata}));
53645307
}
53655308

5309+
sub demangle_list($)
5310+
{
5311+
my ($list) = @_;
5312+
my $tmpfile;
5313+
my $handle;
5314+
my %demangle;
5315+
my %versions;
5316+
5317+
# Write function names to file
5318+
($handle, $tmpfile) = tempfile();
5319+
die("ERROR: could not create temporary file") if (!defined($tmpfile));
5320+
print($handle join("\n", @$list));
5321+
close($handle);
5322+
5323+
# Build translation hash from c++filt output
5324+
open($handle, "-|", "c++filt < $tmpfile") or
5325+
die("ERROR: could not run c++filt: $!\n");
5326+
foreach my $func (@$list) {
5327+
my $translated = <$handle>;
5328+
my $version;
5329+
5330+
last if (!defined($translated));
5331+
chomp($translated);
5332+
5333+
$version = ++$versions{$translated};
5334+
$translated .= ".$version" if ($version > 1);
5335+
$demangle{$func} = $translated;
5336+
}
5337+
close($handle);
5338+
5339+
if (scalar(keys(%demangle)) != scalar(@$list)) {
5340+
die("ERROR: c++filt output not as expected (".
5341+
scalar(keys(%demangle))." vs ".scalar(@$list).") lines\n");
5342+
}
5343+
5344+
unlink($tmpfile) or
5345+
warn("WARNING: could not remove temporary file $tmpfile: $!\n");
5346+
5347+
return \%demangle;
5348+
}
5349+
53665350
#
53675351
# write_function_table(filehandle, source_file, sumcount, funcdata,
53685352
# sumfnccount, testfncdata, sumbrcount, testbrdata,
@@ -5390,6 +5374,7 @@ sub write_function_table(*$$$$$$$$$$)
53905374
my $func;
53915375
my $func_code;
53925376
my $count_code;
5377+
my $demangle;
53935378

53945379
# Get HTML code for headings
53955380
$func_code = funcview_get_func_code($name, $base, $type);
@@ -5404,7 +5389,12 @@ sub write_function_table(*$$$$$$$$$$)
54045389
</tr>
54055390
END_OF_HTML
54065391
;
5407-
5392+
5393+
# Get demangle translation hash
5394+
if ($demangle_cpp) {
5395+
$demangle = demangle_list([ sort(keys(%{$funcdata})) ]);
5396+
}
5397+
54085398
# Get a sorted table
54095399
foreach $func (funcview_get_sorted($funcdata, $sumfncdata, $type)) {
54105400
if (!defined($funcdata->{$func}))
@@ -5417,6 +5407,9 @@ END_OF_HTML
54175407
my $count = $sumfncdata->{$name};
54185408
my $countstyle;
54195409

5410+
# Replace function name with demangled version if available
5411+
$name = $demangle->{$name} if (exists($demangle->{$name}));
5412+
54205413
# Escape special characters
54215414
$name = escape_html($name);
54225415
if ($startline < 1) {

0 commit comments

Comments
 (0)