sub completeABI()

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"});
        }
    }
}