sub readABI()

in src/main/abi-symbols/abi-dumper.pl [2248:2569]


sub readABI()
{
    my %CurID = ();
    
    if(@IDs_I) {
        @IDs = (@IDs_I, @IDs);
    }
    
    my $TPack = undef;
    my $PPack = undef;
    my $NS_Pre = undef;
    
    foreach my $ID (@IDs)
    {
        $ID = "$ID";
        
        my $Kind = $DWARF_Info{$ID}{"kind"};
        my $NS = $DWARF_Info{$ID}{"ns"};
        my $Scope = $CurID{$NS-2};
        
        if(defined $NS_Pre and $NS<=$NS_Pre)
        {
            foreach (0 .. $NS_Pre-$NS) {
                delete($CurID{$NS+$_});
            }
        }
        
        $NS_Pre = $NS;
        
        if($Kind eq "typedef")
        {
            if($DWARF_Info{$Scope}{"kind"} eq "prog")
            {
                $NS = $DWARF_Info{$Scope}{"ns"};
                $Scope = $CurID{$NS-2};
            }
        }
        
        if($Kind ne "prog") {
            delete($DWARF_Info{$ID}{"ns"});
        }
        
        if(defined $IsType{$Kind}
        or defined $MainKind{$Kind})
        {
            if($Kind ne "variable"
            and $Kind ne "typedef")
            {
                $CurID{$NS} = $ID;
            }
            
            if($Scope)
            {
                $NameSpace{$ID} = $Scope;
                if($Kind eq "prog"
                or $Kind eq "variable")
                {
                    if($DWARF_Info{$Scope}{"kind"}=~/class|struct/)
                    {
                        $ClassMethods{$Scope} = 1;
                        if(my $Sp = $DWARF_Info{$Scope}{"spec"}) {
                            $ClassMethods{$Sp} = 1;
                        }
                    }
                }
            }
            
            if(my $Spec = $DWARF_Info{$ID}{"spec"}) {
                $SpecElem{$Spec} = $ID;
            }
            
            if(my $Orig = $DWARF_Info{$ID}{"orig"}) {
                $OrigElem{$Orig} = $ID;
            }
            
            if(defined $IsType{$Kind})
            {
                if(not $DWARF_Info{$ID}{"name"}
                and $DWARF_Info{$ID}{"linkage"})
                {
                    $DWARF_Info{$ID}{"name"} = unmangleString($DWARF_Info{$ID}{"linkage"});
                    
                    # free memory
                    delete($DWARF_Info{$ID}{"linkage"});
                }
            }
        }
        elsif($Kind eq "member")
        {
            if($Scope)
            {
                $NameSpace{$ID} = $Scope;
                
                if(not defined $DWARF_Info{$ID}{"mloc"}
                and $DWARF_Info{$Scope}{"kind"}=~/class|struct/)
                { # variable (global data)
                    next;
                }
            }
            
            $TypeMember{$Scope}{keys(%{$TypeMember{$Scope}})} = $ID;
        }
        elsif($Kind eq "enumerator")
        {
            $TypeMember{$Scope}{keys(%{$TypeMember{$Scope}})} = $ID;
        }
        elsif($Kind eq "inheritance")
        {
            my %In = ();
            $In{"id"} = $DWARF_Info{$ID}{"type"};
            
            if(my $Access = $DWARF_Info{$ID}{"access"})
            {
                if($Access ne "public")
                { # default inheritance access in ABI dump is "public"
                    $In{"access"} = $Access;
                }
            }
            
            if(defined $DWARF_Info{$ID}{"virt"}) {
                $In{"virtual"} = 1;
            }
            $Inheritance{$Scope}{keys(%{$Inheritance{$Scope}})} = \%In;
            
            # free memory
            delete($DWARF_Info{$ID});
        }
        elsif($Kind eq "param")
        {
            if(defined $PPack) {
                $FuncParam{$PPack}{keys(%{$FuncParam{$PPack}})} = $ID;
            }
            else {
                $FuncParam{$Scope}{keys(%{$FuncParam{$Scope}})} = $ID;
            }
        }
        elsif($Kind eq "unspec_params")
        {
            $FuncParam{$Scope}{keys(%{$FuncParam{$Scope}})} = $ID;
            $DWARF_Info{$ID}{"type"} = "-1"; # "..."
        }
        elsif($Kind eq "subrange_type")
        {
            if((my $Bound = $DWARF_Info{$ID}{"upper_bound"}) ne "") {
                $ArrayCount{$Scope} = $Bound + 1;
            }
            
            # free memory
            delete($DWARF_Info{$ID});
        }
        elsif($Kind eq "tmpl_param"
        or $Kind eq "template_value_parameter")
        {
            my %Info = ("key"=>$DWARF_Info{$ID}{"name"});
            
            if(defined $DWARF_Info{$ID}{"type"}) {
                $Info{"type"} = $DWARF_Info{$ID}{"type"};
            }
            else { # void
                $Info{"type"} = "1";
            }
            
            if(defined $DWARF_Info{$ID}{"cval"}) {
                $Info{"value"} = $DWARF_Info{$ID}{"cval"};
            }
            
            if(defined $DWARF_Info{$ID}{"default_value"}) {
                $Info{"default"} = 1;
            }
            
            if(defined $TPack) {
                $TmplParam{$TPack}{keys(%{$TmplParam{$TPack}})} = \%Info;
            }
            else {
                $TmplParam{$Scope}{keys(%{$TmplParam{$Scope}})} = \%Info;
            }
        }
        elsif($Kind eq "GNU_template_parameter_pack") {
            $TPack = $Scope;
        }
        elsif($Kind eq "GNU_formal_parameter_pack") {
            $PPack = $Scope;
        }
        
        if($Kind ne "GNU_template_parameter_pack")
        {
            if(index($Kind, "template_")==-1) {
                $TPack = undef;
            }
        }
        
        if($Kind ne "GNU_formal_parameter_pack")
        {
            if($Kind ne "param") {
                $PPack = undef;
            }
        }
    }
    
    # free memory
    %CurID = ();
    
    foreach my $ID (@IDs)
    {
        if(not defined $DWARF_Info{$ID}) {
            next;
        }
        
        if(my $Kind = $DWARF_Info{$ID}{"kind"})
        {
            if(defined $TypeType{$Kind}
            and not defined $Cache{"getTypeInfo"}{$ID})
            {
                getTypeInfo($ID);
            }
        }
    }
    
    foreach my $Tid (@IDs)
    {
        if(defined $DWARF_Info{$Tid}
        and defined $TypeInfo{$Tid})
        {
            my $Type = $TypeInfo{$Tid}{"Type"};
            
            if(not defined $TypeInfo{$Tid}{"Memb"})
            {
                if($Type=~/Struct|Class|Union|Enum/)
                {
                    if(my $Signature = $DWARF_Info{$Tid}{"signature"})
                    {
                        if(defined $TypeInfo{$Signature})
                        {
                            foreach my $Attr (keys(%{$TypeInfo{$Signature}}))
                            {
                                if(not defined $TypeInfo{$Tid}{$Attr}) {
                                    $TypeInfo{$Tid}{$Attr} = $TypeInfo{$Signature}{$Attr};
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    # delete types info
    foreach my $ID (@IDs)
    {
        if(not defined $DWARF_Info{$ID}) {
            next;
        }
        
        if(my $Kind = $DWARF_Info{$ID}{"kind"})
        {
            if(defined $TypeType{$Kind}) {
                delete($DWARF_Info{$ID});
            }
        }
    }
    
    foreach my $ID (@IDs)
    {
        if(not defined $DWARF_Info{$ID}) {
            next;
        }
        
        if($ID<0)
        { # imported
            next;
        }
        
        if($DWARF_Info{$ID}{"kind"} eq "prog"
        or $DWARF_Info{$ID}{"kind"} eq "variable")
        {
            getSymbolInfo($ID);
        }
    }
    
    if(defined $Compressed
    and not defined $AllUnits)
    {
        if(not $Partial)
        {
            foreach my $ID (@IDs)
            {
                if($DWARF_Info{$ID}{"kind"} ne "base_type") {
                    delete($DWARF_Info{$ID});
                }
            }
        }
        
        # free memory
        %TypeMember = ();
        %ArrayCount = ();
        %FuncParam = ();
        %TmplParam = ();
    }
    else
    {
        %DWARF_Info = ();
        
        # free memory
        %TypeMember = ();
        %ArrayCount = ();
        %FuncParam = ();
        %TmplParam = ();
        
        %Inheritance = ();
        %NameSpace = ();
        %SpecElem = ();
        %OrigElem = ();
        %ClassMethods = ();
        
        %LexicalId = ();
        
        $Cache{"getTypeInfo"} = {"1"=>1, "-1"=>1};
    }
    
    @IDs = ();
    @IDs_I = ();
}