sub getSymbolInfo()

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