in src/main/abi-symbols/abi-dumper.pl [4654:5059]
sub getSymbolInfo($)
{
my $ID = $_[0];
if(my $N = $NameSpace{$ID})
{
if($DWARF_Info{$N}{"kind"} eq "lexical_block"
or $DWARF_Info{$N}{"kind"} eq "prog")
{ # local variables
return;
}
}
my $Orig = $DWARF_Info{$ID}{"orig"};
my $Container = undef;
if(defined $DWARF_Info{$ID}{"container"}) {
$Container = $DWARF_Info{$ID}{"container"};
}
elsif(defined $DWARF_Info{$Orig}{"container"}) {
$Container = $DWARF_Info{$Orig}{"container"};
}
if(defined $Container
and defined $LexicalId{$Container})
{ # local functions
return;
}
if(my $Loc = $DWARF_Info{$ID}{"location"})
{
if($Loc=~/ reg\d+\Z/)
{ # local variables
return;
}
}
my $ShortName = $DWARF_Info{$ID}{"name"};
my $MnglName = getMangled($ID);
if(not $MnglName)
{
if(my $Sp = $SpecElem{$ID})
{
$MnglName = getMangled($Sp);
if(not $MnglName)
{
if(my $OrigSp = $OrigElem{$Sp})
{
$MnglName = getMangled($OrigSp);
}
}
}
}
if(not $MnglName)
{
if($ShortName!~/\W/)
{ # C-func
$MnglName = $ShortName;
}
}
if(defined $Compressed
and not defined $AllUnits)
{
if(not $MnglName)
{
if(not $Partial) {
return;
}
}
}
else
{
if(not $MnglName) {
return;
}
}
if(index($MnglName, "\@")!=-1) {
$MnglName=~s/([\@]+.*?)\Z//;
}
if($MnglName=~/\W/)
{ # unmangled operators, etc.
# foo.part.14
# bar.isra.15
return;
}
if(skipSymbol($MnglName)) {
return;
}
my %SInfo = ();
if($DWARF_Info{$ID}{"kind"} eq "variable")
{ # global data
$SInfo{"Data"} = 1;
}
if($ShortName) {
$SInfo{"ShortName"} = $ShortName;
}
$SInfo{"MnglName"} = $MnglName;
if($MnglName and my $OLD_ID = $Mangled_ID{$MnglName})
{ # duplicates
if(not defined $SymbolInfo{$OLD_ID}{"Header"}) {
setSource($SymbolInfo{$OLD_ID}, $ID, "Header");
}
if(not defined $SymbolInfo{$OLD_ID}{"Line"}) {
setSource($SymbolInfo{$OLD_ID}, $ID, "Line");
}
if(not defined $SymbolInfo{$OLD_ID}{"Source"}) {
setSource($SymbolInfo{$OLD_ID}, $ID, "Source");
}
if(not defined $SymbolInfo{$OLD_ID}{"ShortName"}
and $ShortName) {
$SymbolInfo{$OLD_ID}{"ShortName"} = $ShortName;
}
if(defined $DWARF_Info{$OLD_ID}{"low_pc"}
or not defined $DWARF_Info{$ID}{"low_pc"})
{
if(defined $Checked_Spec{$MnglName}
or not $DWARF_Info{$ID}{"spec"})
{
if(defined $SymbolInfo{$OLD_ID}{"Param"}
or not defined $FuncParam{$ID})
{
if(defined $SymbolInfo{$OLD_ID}{"Return"}
or not defined $DWARF_Info{$ID}{"type"})
{
if(not defined $SpecElem{$ID}
and not defined $OrigElem{$ID}) {
delete($DWARF_Info{$ID});
}
return;
}
}
}
}
}
if($ShortName)
{
if($MnglName eq $ShortName)
{
delete($SInfo{"MnglName"});
$MnglName = $ShortName;
}
elsif($MnglName
and index($MnglName, "_Z")!=0)
{
if($SInfo{"ShortName"})
{
if(index($SInfo{"ShortName"}, ".")==-1) {
$SInfo{"Alias"} = $SInfo{"ShortName"};
}
$SInfo{"ShortName"} = $SInfo{"MnglName"};
}
delete($SInfo{"MnglName"});
$MnglName = $ShortName;
}
}
else
{
if(index($MnglName, "_Z")!=0)
{
$SInfo{"ShortName"} = $SInfo{"MnglName"};
delete($SInfo{"MnglName"});
}
}
if(isExternal($ID)) {
$SInfo{"External"} = 1;
}
if($Orig)
{
if(isExternal($Orig)) {
$SInfo{"External"} = 1;
}
}
if(index($MnglName, "_ZNVK")==0)
{
$SInfo{"Const"} = 1;
$SInfo{"Volatile"} = 1;
}
elsif(index($MnglName, "_ZNV")==0) {
$SInfo{"Volatile"} = 1;
}
elsif(index($MnglName, "_ZNK")==0) {
$SInfo{"Const"} = 1;
}
if($DWARF_Info{$ID}{"art"}) {
$SInfo{"Artificial"} = 1;
}
my ($C, $D) = ();
if($MnglName=~/(C[1-4])[EI].+/)
{
$C = $1;
$SInfo{"Constructor"} = 1;
}
if($MnglName=~/(D[0-4])[EI].+/)
{
$D = $1;
$SInfo{"Destructor"} = 1;
}
if($C or $D)
{
if($Orig)
{
if(my $InLine = $DWARF_Info{$Orig}{"inline"})
{
if(index($InLine, "declared_not_inlined")==0)
{
$SInfo{"InLine"} = 1;
$SInfo{"Artificial"} = 1;
}
}
setSource(\%SInfo, $Orig);
if(my $Spec = $DWARF_Info{$Orig}{"spec"})
{
setSource(\%SInfo, $Spec);
$SInfo{"ShortName"} = $DWARF_Info{$Spec}{"name"};
if($D) {
$SInfo{"ShortName"}=~s/\A\~//g;
}
if(my $Class = $NameSpace{$Spec}) {
$SInfo{"Class"} = $Class;
}
if(my $Virt = $DWARF_Info{$Spec}{"virt"})
{
if(index($Virt, "virtual")!=-1) {
$SInfo{"Virt"} = 1;
}
}
if(my $Access = $DWARF_Info{$Spec}{"access"})
{
if($Access ne "public")
{ # default access of methods in the ABI dump is "public"
$SInfo{ucfirst($Access)} = 1;
}
}
else
{ # NOTE: default access of class methods in the debug info is "private"
if($TypeInfo{$SInfo{"Class"}}{"Type"} eq "Class")
{
$SInfo{"Private"} = 1;
}
}
if(not defined $Compressed
or defined $AllUnits)
{
# clean origin
delete($SymbolInfo{$Spec});
}
}
}
}
else
{
if(my $InLine = $DWARF_Info{$ID}{"inline"})
{
if(index($InLine, "declared_inlined")==0) {
$SInfo{"DeclaredInlined"} = 1;
}
}
}
if(defined $AddrToName)
{
if(not $SInfo{"Alias"}
and not $SInfo{"Constructor"}
and not $SInfo{"Destructor"})
{
if(my $Linkage = $DWARF_Info{$ID}{"linkage"})
{
if($Linkage ne $MnglName) {
$SInfo{"Alias"} = $Linkage;
}
}
}
}
if($SInfo{"Data"})
{
if(my $Spec = $DWARF_Info{$ID}{"spec"})
{
if($DWARF_Info{$Spec}{"kind"} eq "member")
{
setSource(\%SInfo, $Spec);
$SInfo{"ShortName"} = $DWARF_Info{$Spec}{"name"};
if(my $NSp = $NameSpace{$Spec})
{
if($DWARF_Info{$NSp}{"kind"} eq "namespace") {
$SInfo{"NameSpace"} = completeNS($Spec);
}
else {
$SInfo{"Class"} = $NSp;
}
}
}
}
}
if(my $Access = $DWARF_Info{$ID}{"access"})
{
if($Access ne "public")
{ # default access of methods in the ABI dump is "public"
$SInfo{ucfirst($Access)} = 1;
}
}
elsif(not $DWARF_Info{$ID}{"spec"}
and not $Orig)
{
if(my $NS = $NameSpace{$ID})
{
if(defined $TypeInfo{$NS})
{ # NOTE: default access of class methods in the debug info is "private"
if($TypeInfo{$NS}{"Type"} eq "Class")
{
$SInfo{"Private"} = 1;
}
}
}
}
if(my $Class = $DWARF_Info{$ID}{"container"})
{
$SInfo{"Class"} = $Class;
}
if(my $NS = $NameSpace{$ID})
{
if($DWARF_Info{$NS}{"kind"} eq "namespace") {
$SInfo{"NameSpace"} = completeNS($ID);
}
else {
$SInfo{"Class"} = $NS;
}
}
if($SInfo{"Class"} and $MnglName
and index($MnglName, "_Z")!=0) {
return;
}
if(my $Return = $DWARF_Info{$ID}{"type"})
{
$SInfo{"Return"} = $Return;
}
if(my $Spec = $DWARF_Info{$ID}{"spec"})
{
if(not $DWARF_Info{$ID}{"type"})
{
if(my $SpRet = $DWARF_Info{$Spec}{"type"}) {
$SInfo{"Return"} = $SpRet;
}
}
if(my $Value = $DWARF_Info{$Spec}{"cval"})
{
if($Value=~/ block:\s*(.*?)\Z/) {
$Value = $1;
}
$SInfo{"Value"} = $Value;
}
}
if($SInfo{"ShortName"}=~/>\Z/)
{ # foo<T1, T2, ...>
my ($Short, $TParams) = getTParams($ID, $SInfo{"ShortName"});
if($TParams)
{
foreach my $Pos (0 .. $#{$TParams}) {
$SInfo{"TParam"}{$Pos} = $TParams->[$Pos];
}
my @TKeys = getTKeys($TParams);
$SInfo{"ShortName"} = $Short.formatName("<".join(", ", @TKeys).">", "T");
}
}