in src/main/abi-symbols/abi-dumper.pl [2665:3051]
sub completeABI()
{
# types
my %Incomplete = ();
my %Incomplete_TN = ();
my @TIDs = sort {$a<=>$b} keys(%TypeInfo);
if($AltDebugInfo) {
@TIDs = sort {$b>0<=>$a>0} sort {abs($a)<=>abs($b)} @TIDs;
}
if(defined $Compressed
and not defined $AllUnits)
{
foreach my $Tid (@TIDs)
{
my $TName = $TypeInfo{$Tid}{"Name"};
if(index($TName, "#")!=-1)
{
$TypeInfo{$Tid}{"Name"} = completeTypes($TName);
registerTName($Tid, $TypeInfo{$Tid}{"Name"}, $TypeInfo{$Tid}{"Type"});
}
}
}
foreach my $Tid (@TIDs)
{
my $Name = $TypeInfo{$Tid}{"Name"};
my $Type = $TypeInfo{$Tid}{"Type"};
if(not defined $SpecElem{$Tid}
and not defined $Incomplete_TN{$Type}{$Name})
{
if(not defined $TypeInfo{$Tid}{"Size"})
{
if($Type=~/Struct|Class|Union|Enum/)
{
$Incomplete{$Tid} = 1;
}
}
}
$Incomplete_TN{$Type}{$Name} = 1;
}
# free memory
%Incomplete_TN = ();
foreach my $Tid (sort {$a<=>$b} keys(%Incomplete))
{
my $Name = $TypeInfo{$Tid}{"Name"};
my $Type = $TypeInfo{$Tid}{"Type"};
my @Adv_TIDs = sort {$a<=>$b} keys(%{$TName_Tids{$Type}{$Name}});
if($AltDebugInfo) {
@Adv_TIDs = sort {$b>0<=>$a>0} sort {abs($a)<=>abs($b)} @Adv_TIDs;
}
foreach my $Tid_Adv (@Adv_TIDs)
{
if($Tid_Adv!=$Tid)
{
if(defined $SpecElem{$Tid_Adv}
or defined $TypeInfo{$Tid_Adv}{"Size"})
{
foreach my $Attr (keys(%{$TypeInfo{$Tid_Adv}}))
{
if(not defined $TypeInfo{$Tid}{$Attr})
{
if(ref($TypeInfo{$Tid_Adv}{$Attr}) eq "HASH") {
$TypeInfo{$Tid}{$Attr} = dclone($TypeInfo{$Tid_Adv}{$Attr});
}
else {
$TypeInfo{$Tid}{$Attr} = $TypeInfo{$Tid_Adv}{$Attr};
}
}
}
last;
}
}
}
}
# free memory
%Incomplete = ();
my %ReplacedAnon = ();
foreach my $Tid (sort {$a<=>$b} keys(%TypeInfo))
{
if($TypeInfo{$Tid}{"Type"} eq "Typedef")
{
my $TN = $TypeInfo{$Tid}{"Name"};
my $TL = $TypeInfo{$Tid}{"Line"};
my $NS = $TypeInfo{$Tid}{"NameSpace"};
if(my $BTid = $TypeInfo{$Tid}{"BaseType"})
{
my $BName = $TypeInfo{$BTid}{"Name"};
my $BType = $TypeInfo{$BTid}{"Type"};
if(defined $TypeInfo{$BTid}
and $BName=~/\Aanon\-(\w+)\-/
and $BType=~/Enum|Struct|Union/)
{
$TypeInfo{$Tid} = dclone($TypeInfo{$BTid});
$TypeInfo{$Tid}{"Name"} = lc($TypeInfo{$BTid}{"Type"})." ".$TN;
$TypeInfo{$Tid}{"Line"} = $TL;
my $Name = $TypeInfo{$Tid}{"Name"};
my $Type = $TypeInfo{$Tid}{"Type"};
registerTName($Tid, $Name, $Type);
if($NS) {
$TypeInfo{$Tid}{"NameSpace"} = $NS;
}
$DeletedAnon{$BTid} = $Tid;
foreach my $BTid_S (keys(%{$TName_Tids{$BType}{$BName}})) {
$DeletedAnon{$BTid_S} = $Tid;
}
}
}
}
elsif($TypeInfo{$Tid}{"Type"} eq "Pointer")
{
if(my $BTid = $TypeInfo{$Tid}{"BaseType"})
{
my $To = undef;
if(defined $DeletedAnon{$BTid}) {
$To = $DeletedAnon{$BTid};
}
elsif(defined $ReplacedAnon{$BTid}) {
$To = $BTid;
}
if($To)
{
$TypeInfo{$Tid}{"BaseType"} = $To;
$TypeInfo{$Tid}{"Name"} = $TypeInfo{$To}{"Name"}."*";
my $Name = $TypeInfo{$Tid}{"Name"};
my $Type = $TypeInfo{$Tid}{"Type"};
$TName_Tid{$Type}{$Name} = $Tid;
$TName_Tids{$Type}{$Name}{$Tid} = 1;
$ReplacedAnon{$Tid} = 1;
}
}
}
elsif($TypeInfo{$Tid}{"Type"} eq "Const")
{
if(my $BTid = $TypeInfo{$Tid}{"BaseType"})
{
my $To = undef;
if(defined $DeletedAnon{$BTid}) {
$To = $DeletedAnon{$BTid};
}
elsif(defined $ReplacedAnon{$BTid}) {
$To = $BTid;
}
if($To)
{
$TypeInfo{$Tid}{"BaseType"} = $To;
$TypeInfo{$Tid}{"Name"} = formatName($TypeInfo{$To}{"Name"}." const", "T");
my $Name = $TypeInfo{$Tid}{"Name"};
my $Type = $TypeInfo{$Tid}{"Type"};
$TName_Tid{$Type}{$Name} = $Tid;
$TName_Tids{$Type}{$Name}{$Tid} = 1;
$ReplacedAnon{$Tid} = 1;
}
}
}
}
foreach my $Tid (keys(%DeletedAnon))
{
my $TN = $TypeInfo{$Tid}{"Name"};
my $TT = $TypeInfo{$Tid}{"Type"};
delete($TName_Tid{$TT}{$TN});
delete($TName_Tids{$TT}{$TN}{$Tid});
if(my @TIDs = sort {$a<=>$b} keys(%{$TName_Tids{$TT}{$TN}}))
{ # minimal ID
$TName_Tid{$TT}{$TN} = $TIDs[0];
}
delete($TypeInfo{$Tid});
}
# symbols
foreach my $ID (sort {$a<=>$b} keys(%SymbolInfo))
{
if(defined $Compressed
and not defined $AllUnits)
{ # replace late template arguments
my $ShortName = $SymbolInfo{$ID}{"ShortName"};
if(index($ShortName, "#")!=-1) {
$SymbolInfo{$ID}{"ShortName"} = completeTypes($ShortName);
}
}
# add missed c-tors
if($SymbolInfo{$ID}{"Constructor"})
{
if($SymbolInfo{$ID}{"MnglName"}=~/(C[1-2])([EI]).+/)
{
my ($K1, $K2) = ($1, $2);
foreach ("C1", "C2")
{
if($K1 ne $_)
{
my $Name = $SymbolInfo{$ID}{"MnglName"};
$Name=~s/$K1$K2/$_$K2/;
if(not defined $Mangled_ID{$Name}) {
$Mangled_ID{$Name} = cloneSymbol($ID, $Name);
}
}
}
}
}
# add missed d-tors
if($SymbolInfo{$ID}{"Destructor"})
{
if($SymbolInfo{$ID}{"MnglName"}=~/(D[0-2])([EI]).+/)
{
my ($K1, $K2) = ($1, $2);
foreach ("D0", "D1", "D2")
{
if($K1 ne $_)
{
my $Name = $SymbolInfo{$ID}{"MnglName"};
$Name=~s/$K1$K2/$_$K2/;
if(not defined $Mangled_ID{$Name}) {
$Mangled_ID{$Name} = cloneSymbol($ID, $Name);
}
}
}
}
}
}
foreach my $ID (sort {$a<=>$b} keys(%SymbolInfo))
{
my $SInfo = $SymbolInfo{$ID};
my $Symbol = $SInfo->{"MnglName"};
my $Short = $SInfo->{"ShortName"};
if(not $Symbol) {
$Symbol = $Short;
}
if($LIB_LANG eq "C++")
{
if(not $SInfo->{"MnglName"})
{
if($SInfo->{"Artificial"}
or index($Short, "~")==0)
{
delete($SymbolInfo{$ID});
next;
}
}
}
if($SInfo->{"Class"}
and not $SInfo->{"Data"}
and not $SInfo->{"Constructor"}
and not $SInfo->{"Destructor"}
and not $SInfo->{"Virt"}
and not $SInfo->{"PureVirt"})
{
if(not defined $SInfo->{"Param"}
or $SInfo->{"Param"}{0}{"name"} ne "this")
{
if(not $ExtraDump or index($Symbol, "_ZTV")!=0)
{
$SInfo->{"Static"} = 1;
}
}
}
if(not $SInfo->{"Return"})
{ # void
if(not $SInfo->{"Constructor"}
and not $SInfo->{"Destructor"})
{
$SInfo->{"Return"} = "1";
}
}
if(not $SInfo->{"Header"})
{
if($SInfo->{"Class"})
{ # detect missed header by class
if(defined $TypeInfo{$SInfo->{"Class"}}{"Header"}) {
$SInfo->{"Header"} = $TypeInfo{$SInfo->{"Class"}}{"Header"};
}
}
}
if(defined $PublicHeadersPath) {
fixHeader($SInfo);
}
my $Header = $SInfo->{"Header"};
if(defined $SInfo->{"Source"} and defined $SInfo->{"SourceLine"})
{
if(not defined $Header and not defined $SInfo->{"Line"})
{
$SInfo->{"Line"} = $SInfo->{"SourceLine"};
delete($SInfo->{"SourceLine"});
}
}
if(not $SInfo->{"Constructor"}
and not $SInfo->{"Destructor"})
{
my $InLineDecl = delete($SInfo->{"DeclaredInlined"});
my $Bind = undef;
if(defined $Symbol_Bind{$Symbol}) {
$Bind = $Symbol_Bind{$Symbol};
}
elsif(my $SVer = $SymVer{$Symbol})
{
if(defined $Symbol_Bind{$SVer}) {
$Bind = $Symbol_Bind{$SVer};
}
}
if($Bind ne "GLOBAL" and $Bind ne "LOCAL")
{
# Not enough info in the DWARF dump
if($Bind eq "WEAK")
{
if($InLineDecl) {
$SInfo->{"InLine"} = 1;
}
else {
$SInfo->{"InLine"} = 2;
}
}
#if(not $SInfo->{"InLine"})
#{
# if(defined $PublicHeadersPath)
# {
# if($Short and defined $Header
# and defined $PublicHeader{$Header})
# {
# if(defined $SymbolToHeader{$Short}
# and defined $SymbolToHeader{$Short}{$Header})
# {
# if($SymbolToHeader{$Short}{$Header} eq "function") {
# $SInfo->{"InLine"} = 2;
# }
# }
# }
# }
#}
}
}
if(defined $SInfo->{"PureVirt"}) {
delete($SInfo->{"InLine"});
}
}
}