ABI Compliance Checker 1.99
diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl
index c9687b3..f3ff680 100755
--- a/abi-compliance-checker.pl
+++ b/abi-compliance-checker.pl
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 ###########################################################################
-# ABI Compliance Checker (ACC) 1.98.8
+# ABI Compliance Checker (ACC) 1.99
 # A tool for checking backward compatibility of a C/C++ library API
 #
 # Copyright (C) 2009-2010 The Linux Foundation
@@ -58,10 +58,10 @@
 use Data::Dumper;
 use Config;
 
-my $TOOL_VERSION = "1.98.8";
-my $ABI_DUMP_VERSION = "2.20";
+my $TOOL_VERSION = "1.99";
+my $ABI_DUMP_VERSION = "3.0";
 my $OLDEST_SUPPORTED_VERSION = "1.18";
-my $XML_REPORT_VERSION = "1.0";
+my $XML_REPORT_VERSION = "1.1";
 my $XML_ABI_DUMP_VERSION = "1.2";
 my $OSgroup = get_OSgroup();
 my $ORIG_DIR = cwd();
@@ -79,14 +79,14 @@
 $TestTool, $DumpAPI, $SymbolsListPath, $CheckHeadersOnly_Opt, $UseDumps,
 $CheckObjectsOnly_Opt, $AppPath, $StrictCompat, $DumpVersion, $ParamNamesPath,
 %RelativeDirectory, $TargetLibraryFName, $TestDump, $CheckImpl, $LoggingPath,
-%TargetVersion, $InfoMsg, $UseOldDumps, %UsedDump, $CrossGcc, %OutputLogPath,
+%TargetVersion, $InfoMsg, $UseOldDumps, $CrossGcc, %OutputLogPath,
 $OutputReportPath, $OutputDumpPath, $ShowRetVal, $SystemRoot_Opt, $DumpSystem,
 $CmpSystems, $TargetLibsPath, $Debug, $CrossPrefix, $UseStaticLibs, $NoStdInc,
 $TargetComponent_Opt, $TargetSysInfo, $TargetHeader, $ExtendedCheck, $Quiet,
 $SkipHeadersPath, $CppCompat, $LogMode, $StdOut, $ListAffected, $ReportFormat,
 $UserLang, $TargetHeadersPath, $BinaryOnly, $SourceOnly, $BinaryReportPath,
 $SourceReportPath, $UseXML, $Browse, $OpenReport, $SortDump, $DumpFormat,
-$ExtraInfo, $ExtraDump, $Force, $Tolerance, $Tolerant);
+$ExtraInfo, $ExtraDump, $Force, $Tolerance, $Tolerant, $SkipSymbolsListPath);
 
 my $CmdName = get_filename($0);
 my %OS_LibExt = (
@@ -216,7 +216,10 @@
   "v2|version2=s" => \$TargetVersion{2},
   "s|strict!" => \$StrictCompat,
   "symbols-list=s" => \$SymbolsListPath,
+  "skip-symbols=s" => \$SkipSymbolsListPath,
+  "headers-list=s" => \$TargetHeadersPath,
   "skip-headers=s" => \$SkipHeadersPath,
+  "header=s" => \$TargetHeader,
   "headers-only|headers_only!" => \$CheckHeadersOnly_Opt,
   "objects-only!" => \$CheckObjectsOnly_Opt,
   "check-impl|check-implementation!" => \$CheckImpl,
@@ -227,8 +230,6 @@
   "sysinfo=s" => \$TargetSysInfo,
   "cmp-systems!" => \$CmpSystems,
   "libs-list=s" => \$TargetLibsPath,
-  "headers-list=s" => \$TargetHeadersPath,
-  "header=s" => \$TargetHeader,
   "ext|extended!" => \$ExtendedCheck,
   "q|quiet!" => \$Quiet,
   "stdout!" => \$StdOut,
@@ -398,10 +399,10 @@
       transfer it anywhere and pass instead of the descriptor. Also
       it can be used for debugging the tool.
       
-      Supported ABI dump versions: ".majorVersion($ABI_DUMP_VERSION).".0<=V<=$ABI_DUMP_VERSION
+      Supported ABI dump versions: 2.0<=V<=$ABI_DUMP_VERSION
 
   -old-dumps
-      Enable support for old-version ABI dumps ($OLDEST_SUPPORTED_VERSION<=V<".majorVersion($ABI_DUMP_VERSION).".0).\n";
+      Enable support for old-version ABI dumps ($OLDEST_SUPPORTED_VERSION<=V<2.0).\n";
 
 sub HELP_MESSAGE() {
     printMsg("INFO", $HelpMessage."
@@ -483,9 +484,18 @@
   -symbols-list PATH
       This option allows to specify a file with a list of symbols (mangled
       names in C++) that should be checked, other symbols will not be checked.
+      
+  -skip-symbols PATH
+      The list of symbols that should NOT be checked.
 
+  -headers-list PATH
+      The file with a list of headers, that should be checked/dumped.
+      
   -skip-headers PATH
       The file with the list of header files, that should not be checked.
+      
+  -header NAME
+      Check/Dump ABI of this header only.
 
   -use-dumps
       Make dumps for two versions of a library and compare dumps. This should
@@ -570,12 +580,6 @@
       The file with a list of libraries, that should be dumped by
       the -dump-system option or should be checked by the -cmp-systems option.
 
-  -header NAME
-      Check/Dump ABI of this header only.
-
-  -headers-list PATH
-      The file with a list of headers, that should be checked/dumped.
-
   -ext|-extended
       If your library A is supposed to be used by other library B and you
       want to control the ABI of B, then you should enable this option. The
@@ -1442,6 +1446,7 @@
   "1"=>{},
   "2"=>{} );
 my %SymbolsList;
+my %SkipSymbolsList;
 my %SymbolsList_App;
 my %CheckedSymbols;
 my %Symbol_Library = (
@@ -1462,6 +1467,9 @@
 my %Interface_Impl;
 my %GlobalDataObject;
 my %WeakSymbols;
+my %Library_Needed= (
+  "1"=>{},
+  "2"=>{} );
 
 # Extra Info
 my %UndefinedSymbols;
@@ -1472,6 +1480,7 @@
     "1"=>[],
     "2"=>[] );
 my %Registered_Headers;
+my %Registered_Sources;
 my %HeaderName_Paths;
 my %Header_Dependency;
 my %Include_Neighbors;
@@ -1558,8 +1567,12 @@
 
 # Calling Conventions
 my %UseConv_Real = (
-  "1"=>0,
-  "2"=>0 );
+  1=>{ "R"=>0, "P"=>0 },
+  2=>{ "R"=>0, "P"=>0 }
+);
+
+# ABI Dump
+my %UsedDump;
 
 # OS Compliance
 my %TargetLibs;
@@ -2220,9 +2233,12 @@
 {
     foreach my $Constant (keys(%{$Constants{$Version}}))
     {
-        my $Value = $Constants{$Version}{$Constant}{"Value"};
-        if(defined $EnumConstants{$Version}{$Value}) {
-            $Constants{$Version}{$Constant}{"Value"} = $EnumConstants{$Version}{$Value}{"Value"};
+        if(defined $Constants{$Version}{$Constant}{"Header"})
+        {
+            my $Value = $Constants{$Version}{$Constant}{"Value"};
+            if(defined $EnumConstants{$Version}{$Value}) {
+                $Constants{$Version}{$Constant}{"Value"} = $EnumConstants{$Version}{$Value}{"Value"};
+            }
         }
     }
 }
@@ -2471,9 +2487,7 @@
         my %MissedInfo = ( # typedef info
             "Name" => $TypedefName,
             "NameSpace" => $TypedefNS,
-            "BaseType" => {
-                            "Tid" => $Tid
-                          },
+            "BaseType" => $Tid,
             "Type" => "Typedef",
             "Tid" => "$MAX_ID" );
         my ($H, $L) = getLocation($MissedTDid);
@@ -2663,7 +2677,7 @@
         if(my $Algn = getAlgn($TypeId)) {
             $TypeAttr{"Algn"} = $Algn/$BYTE_SIZE;
         }
-        $TypeAttr{"BaseType"}{"Tid"} = $BTid;
+        $TypeAttr{"BaseType"} = $BTid;
         if(my %BTAttr = getTypeAttr($BTid))
         {
             if(not $BTAttr{"Name"}) {
@@ -2725,26 +2739,26 @@
         if(not $BTid) {
             return ();
         }
-        $TypeAttr{"BaseType"}{"Tid"} = $BTid;
+        $TypeAttr{"BaseType"} = $BTid;
         if(defined $MissedTypedef{$Version}{$BTid})
         {
             if(my $MissedTDid = $MissedTypedef{$Version}{$BTid}{"TDid"})
             {
                 if($MissedTDid ne $TypeDeclId) {
-                    $TypeAttr{"BaseType"}{"Tid"} = $MissedTypedef{$Version}{$BTid}{"Tid"};
+                    $TypeAttr{"BaseType"} = $MissedTypedef{$Version}{$BTid}{"Tid"};
                 }
             }
         }
-        my %BTAttr = getTypeAttr($TypeAttr{"BaseType"}{"Tid"});
+        my %BTAttr = getTypeAttr($TypeAttr{"BaseType"});
         if(not $BTAttr{"Name"})
         { # templates
             return ();
         }
         if($BTAttr{"Type"} eq "Typedef")
         { # relinking typedefs
-            my %BaseBase = get_Type($BTAttr{"BaseType"}{"Tid"}, $Version);
+            my %BaseBase = get_Type($BTAttr{"BaseType"}, $Version);
             if($BTAttr{"Name"} eq $BaseBase{"Name"}) {
-                $TypeAttr{"BaseType"}{"Tid"} = $BaseBase{"Tid"};
+                $TypeAttr{"BaseType"} = $BaseBase{"Tid"};
             }
         }
         if($BTSpec)
@@ -4565,19 +4579,14 @@
     }
     if($SymbolInfo{$Version}{$InfoId}{"Class"}
     or $SymbolInfo{$Version}{$InfoId}{"NameSpace"})
-    { # identify language
+    {
         if($COMMON_LANGUAGE{$Version} ne "C++")
-        {
-            if(my $ShortName = $SymbolInfo{$Version}{$InfoId}{"ShortName"})
-            {
-                if(index($ShortName, "__")!=0)
-                { # skip C++ symbols from pthread.h:
-                  # __pthread_cleanup_class, __restore, __defer, __setdoit, etc.
-                    setLanguage($Version, "C++");
-                }
-            }
+        { # skip
+            return 1;
         }
     }
+    
+    return 0;
 }
 
 sub debugMangling($)
@@ -4746,7 +4755,16 @@
             return;
         }
     }
-    set_Class_And_Namespace($InfoId);
+    if($LibInfo{$Version}{"info"}{$InfoId}=~/ artificial /i) {
+        $SymbolInfo{$Version}{$InfoId}{"Artificial"} = 1;
+    }
+    
+    if(set_Class_And_Namespace($InfoId))
+    {
+        delete($SymbolInfo{$Version}{$InfoId});
+        return;
+    }
+    
     if(my $ClassId = $SymbolInfo{$Version}{$InfoId}{"Class"})
     {
         if(not $TypeInfo{$Version}{$ClassId}{"Name"})
@@ -4790,6 +4808,10 @@
             }
         }
     }
+    else
+    { # not mangled in C
+        $SymbolInfo{$Version}{$InfoId}{"MnglName"} = $SymbolInfo{$Version}{$InfoId}{"ShortName"};
+    }
     if(not $CheckHeadersOnly
     and $SymbolInfo{$Version}{$InfoId}{"Type"} eq "Function"
     and not $SymbolInfo{$Version}{$InfoId}{"Class"})
@@ -4841,9 +4863,6 @@
     if(hasThrow($InfoId)) {
         $SymbolInfo{$Version}{$InfoId}{"Throw"} = 1;
     }
-    if($LibInfo{$Version}{"info"}{$InfoId}=~/ artificial /i) {
-        $SymbolInfo{$Version}{$InfoId}{"Artificial"} = 1;
-    }
     if($SymbolInfo{$Version}{$InfoId}{"Constructor"}
     and my $ClassId = $SymbolInfo{$Version}{$InfoId}{"Class"})
     {
@@ -5022,10 +5041,9 @@
                 next;
             }
             my $StructMembName = getTreeStr(getTreeAttr_Name($MInfoId));
-            if(index($StructMembName, "_vptr.")!=-1)
+            if(index($StructMembName, "_vptr.")==0)
             { # virtual tables
-                $MInfoId = getNextElem($MInfoId);
-                next;
+                $StructMembName = "_vptr";
             }
             if(not $StructMembName)
             { # unnamed fields
@@ -6009,13 +6027,13 @@
             and not $LocalIncludes{$Dir})
             {
                 registerDir($Dir, 1, $LibVersion);
-                if(my $OutDir = get_dirname($Dir))
-                { # registering the outer directory
-                    if(not grep { $OutDir eq $_ } (@{$SystemPaths{"include"}})
-                    and not $LocalIncludes{$OutDir}) {
-                        registerDir($OutDir, 0, $LibVersion);
-                    }
-                }
+                # if(my $OutDir = get_dirname($Dir))
+                # { # registering the outer directory
+                #     if(not grep { $OutDir eq $_ } (@{$SystemPaths{"include"}})
+                #     and not $LocalIncludes{$OutDir}) {
+                #         registerDir($OutDir, 0, $LibVersion);
+                #     }
+                # }
             }
         }
     }
@@ -6063,8 +6081,7 @@
     { # 4 - skip headers included by others
         foreach my $Path (keys(%{$Registered_Headers{$LibVersion}}))
         {
-            if(defined $Header_Includes_R{$LibVersion}{$Path})
-            {
+            if(defined $Header_Includes_R{$LibVersion}{$Path}) {
                 delete($Registered_Headers{$LibVersion}{$Path});
             }
         }
@@ -6234,10 +6251,19 @@
 { # system GLIBC header
     my $Path = $_[0];
     my ($Dir, $Name) = separate_path($Path);
-    if(get_filename($Dir)=~/\A(include|libc)\Z/ and $GlibcHeader{$Name})
-    { # /usr/include/{stdio, ...}.h
-      # epoc32/include/libc/{stdio, ...}.h
-        return 1;
+    if($OStarget eq "symbian")
+    {
+        if(get_filename($Dir) eq "libc" and $GlibcHeader{$Name})
+        { # epoc32/include/libc/{stdio, ...}.h
+            return 1;
+        }
+    }
+    else
+    {
+        if($Dir eq "/usr/include" and $GlibcHeader{$Name})
+        { # /usr/include/{stdio, ...}.h
+            return 1;
+        }
     }
     return 0;
 }
@@ -6246,10 +6272,21 @@
 { # system GLIBC directory
     my $Dir = $_[0];
     my ($OutDir, $Name) = separate_path($Dir);
-    if(get_filename($OutDir)=~/\A(include|libc)\Z/
-    and ($Name=~/\Aasm(|-.+)\Z/ or $GlibcDir{$Name}))
-    { # /usr/include/{sys,bits,asm,asm-*}/*.h
-        return 1;
+    if($OStarget eq "symbian")
+    {
+        if(get_filename($OutDir) eq "libc"
+        and ($Name=~/\Aasm(|-.+)\Z/ or $GlibcDir{$Name}))
+        { # epoc32/include/libc/{sys,bits,asm,asm-*}/*.h
+            return 1;
+        }
+    }
+    else
+    { # linux
+        if($OutDir eq "/usr/include"
+        and ($Name=~/\Aasm(|-.+)\Z/ or $GlibcDir{$Name}))
+        { # /usr/include/{sys,bits,asm,asm-*}/*.h
+            return 1;
+        }
     }
     return 0;
 }
@@ -7055,20 +7092,26 @@
     my $ShortName = $CompleteSignature{$LibVersion}{$Symbol}{"ShortName"};
     if($Symbol=~/\A(_Z|\?)/)
     {
-        if(my $ClassId = $CompleteSignature{$LibVersion}{$Symbol}{"Class"}) {
-            $Signature = $TypeInfo{$LibVersion}{$ClassId}{"Name"}."::".(($CompleteSignature{$LibVersion}{$Symbol}{"Destructor"})?"~":"").$ShortName;
+        if(my $ClassId = $CompleteSignature{$LibVersion}{$Symbol}{"Class"})
+        {
+            $Signature .= $TypeInfo{$LibVersion}{$ClassId}{"Name"}."::";
+            if($CompleteSignature{$LibVersion}{$Symbol}{"Destructor"}) {
+                $Signature .= "~";
+            }
+            $Signature .= $ShortName;
         }
         elsif(my $NameSpace = $CompleteSignature{$LibVersion}{$Symbol}{"NameSpace"}) {
-            $Signature = $NameSpace."::".$ShortName;
+            $Signature .= $NameSpace."::".$ShortName;
         }
         else {
-            $Signature = $ShortName;
+            $Signature .= $ShortName;
         }
         my ($Short, $Params) = split_Signature($tr_name{$MnglName});
         @Param_Types_FromUnmangledName = separate_Params($Params, 0, 1);
     }
-    else {
-        $Signature = $MnglName;
+    else
+    {
+        $Signature .= $MnglName;
     }
     my @ParamArray = ();
     foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Symbol}{"Param"}}))
@@ -7858,7 +7901,11 @@
             if($S eq $FwdTypedefs[$N+1])
             {
                 $Content=~s/typedef\s+enum\s+\Q$S\E\s+\Q$S\E;//g;
-                $CppMode{$Version}=1;
+                $CppMode{$Version} = 1;
+                
+                if($Debug) {
+                    printMsg("INFO", "Detected code: \"typedef enum $S $S;\"");
+                }
             }
             $N+=2;
         }
@@ -8362,7 +8409,7 @@
         }
         return $Contents[0];
     }
-    elsif($FileName=~s/\Q.tar.gz\E\Z//g)
+    elsif($FileName=~s/\Q.tar.gz\E(\.\w+|)\Z//g)
     { # *.tar.gz
         if($OSgroup eq "windows")
         { # -xvzf option is not implemented in tar.exe (2003)
@@ -8550,7 +8597,8 @@
         foreach my $RecInc (keys(%{$RecursiveIncludes{$LibVersion}{$RegHeader}}))
         {
             my $Dir = get_dirname($RecInc);
-            if($Dir=~/\A\Q$RegDir\E([\/\\]|\Z)/
+            
+            if(familiarDirs($Dir, $RegDir) 
             or $RecursiveIncludes{$LibVersion}{$RegHeader}{$RecInc}!=1)
             { # in the same directory or included by #include "..."
                 $TargetHeaders{$LibVersion}{get_filename($RecInc)}=1;
@@ -8559,6 +8607,25 @@
     }
 }
 
+sub familiarDirs($$)
+{
+    my ($D1, $D2) = @_;
+    if($D1 eq $D2) {
+        return 1;
+    }
+    while($D1=~s/[\/\\]+.*?\Z//)
+    {
+        $D2=~s/[\/\\]+.*?\Z//;
+        if($D1 eq "/usr/include") {
+            return 0;
+        }
+        if($D1 eq $D2) {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 sub readHeaders($)
 {
     $Version = $_[0];
@@ -8806,6 +8873,14 @@
             %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}} = %{$SymbolInfo{$LibVersion}{$InfoId}};
         }
         
+        if(my $Alias = $CompleteSignature{$LibVersion}{$MnglName}{"Alias"})
+        {
+            %{$CompleteSignature{$LibVersion}{$Alias}} = %{$SymbolInfo{$LibVersion}{$InfoId}};
+            if($SymVer{$LibVersion}{$Alias}) {
+                %{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$Alias}}} = %{$SymbolInfo{$LibVersion}{$InfoId}};
+            }
+        }
+        
         # clean memory
         delete($SymbolInfo{$LibVersion}{$InfoId});
     }
@@ -8990,7 +9065,7 @@
         elsif($TInfo{"Type"}=~/\A(Const|ConstVolatile|Volatile|Pointer|Ref|Restrict|Array|Typedef)\Z/)
         {
             $UsedType{$LibVersion}{$TypeId} = 1;
-            register_TypeUsage($TInfo{"BaseType"}{"Tid"}, $LibVersion);
+            register_TypeUsage($TInfo{"BaseType"}, $LibVersion);
             return 1;
         }
         elsif($TInfo{"Type"} eq "Intrinsic")
@@ -9183,13 +9258,6 @@
     return 0;
 }
 
-sub removeGarbage($)
-{
-    my $LibVersion = $_[0];
-    
-    
-}
-
 sub removeUnused($$)
 { # remove unused data types from the ABI dump
     my ($LibVersion, $Kind) = @_;
@@ -9206,7 +9274,7 @@
             { # register "this" pointer
                 $UsedType{$LibVersion}{$ThisId} = 1;
                 if(my %ThisType = get_Type($ThisId, $LibVersion)) {
-                    register_TypeUsage($ThisType{"BaseType"}{"Tid"}, $LibVersion);
+                    register_TypeUsage($ThisType{"BaseType"}, $LibVersion);
                 }
             }
         }
@@ -9412,19 +9480,33 @@
     my $LibVersion = $_[0];
     foreach my $ClassName (keys(%{$VirtualTable{$LibVersion}}))
     {
-        my ($Num, $RelPos, $AbsNum) = (1, 0, 1);
-        foreach my $VirtFunc (sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})}
-        sort keys(%{$VirtualTable{$LibVersion}{$ClassName}}))
+        my ($Num, $Rel) = (1, 0);
+        
+        if(my @Funcs = sort keys(%{$VirtualTable{$LibVersion}{$ClassName}}))
         {
-            $VirtualTable{$LibVersion}{$ClassName}{$VirtFunc}=$Num++;
-            
-            # set relative positions
-            if(defined $VirtualTable{1}{$ClassName} and defined $VirtualTable{1}{$ClassName}{$VirtFunc}
-            and defined $VirtualTable{2}{$ClassName} and defined $VirtualTable{2}{$ClassName}{$VirtFunc})
-            { # relative position excluding added and removed virtual functions
-                if(not $CompleteSignature{1}{$VirtFunc}{"Override"}
-                and not $CompleteSignature{2}{$VirtFunc}{"Override"}) {
-                    $CompleteSignature{$LibVersion}{$VirtFunc}{"RelPos"} = $RelPos++;
+            if($UsedDump{$LibVersion}{"DWARF"}) {
+                @Funcs = sort {int($CompleteSignature{$LibVersion}{$a}{"VirtPos"}) <=> int($CompleteSignature{$LibVersion}{$b}{"VirtPos"})} @Funcs;
+            }
+            else {
+                @Funcs = sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} @Funcs;
+            }
+            foreach my $VirtFunc (@Funcs)
+            {
+                if($UsedDump{$LibVersion}{"DWARF"}) {
+                    $VirtualTable{$LibVersion}{$ClassName}{$VirtFunc} = $CompleteSignature{$LibVersion}{$VirtFunc}{"VirtPos"};
+                }
+                else {
+                    $VirtualTable{$LibVersion}{$ClassName}{$VirtFunc} = $Num++;
+                }
+                
+                # set relative positions
+                if(defined $VirtualTable{1}{$ClassName} and defined $VirtualTable{1}{$ClassName}{$VirtFunc}
+                and defined $VirtualTable{2}{$ClassName} and defined $VirtualTable{2}{$ClassName}{$VirtFunc})
+                { # relative position excluding added and removed virtual functions
+                    if(not $CompleteSignature{1}{$VirtFunc}{"Override"}
+                    and not $CompleteSignature{2}{$VirtFunc}{"Override"}) {
+                        $CompleteSignature{$LibVersion}{$VirtFunc}{"RelPos"} = $Rel++;
+                    }
                 }
             }
         }
@@ -9433,7 +9515,7 @@
     {
         my $AbsNum = 1;
         foreach my $VirtFunc (getVTable_Model($TName_Tid{$LibVersion}{$ClassName}, $LibVersion)) {
-            $VirtualTable_Model{$LibVersion}{$ClassName}{$VirtFunc}=$AbsNum++;
+            $VirtualTable_Model{$LibVersion}{$ClassName}{$VirtFunc} = $AbsNum++;
         }
     }
 }
@@ -9487,9 +9569,14 @@
         {
             if(defined $VirtualTable{$LibVersion}{$BName})
             {
-                my @VFunctions = keys(%{$VirtualTable{$LibVersion}{$BName}});
-                @VFunctions = sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} @VFunctions;
-                foreach my $VFunc (@VFunctions) {
+                my @VFuncs = keys(%{$VirtualTable{$LibVersion}{$BName}});
+                if($UsedDump{$LibVersion}{"DWARF"}) {
+                    @VFuncs = sort {int($CompleteSignature{$LibVersion}{$a}{"VirtPos"}) <=> int($CompleteSignature{$LibVersion}{$b}{"VirtPos"})} @VFuncs;
+                }
+                else {
+                    @VFuncs = sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} @VFuncs;
+                }
+                foreach my $VFunc (@VFuncs) {
                     push(@Elements, $VFunc);
                 }
             }
@@ -10336,6 +10423,7 @@
                 {
                     my $VPos_Old = $VirtualTable{1}{$CName}{$Interface};
                     my $VPos_New = $VirtualTable{2}{$CName}{$Interface};
+                    
                     if($VPos_Added<=$VPos_Old and $VPos_Old!=$VPos_New)
                     {
                         my @Affected = ($Interface, keys(%{$OverriddenMethods{1}{$Interface}}));
@@ -10595,17 +10683,24 @@
 sub nonComparable($$)
 {
     my ($T1, $T2) = @_;
-    if($T1->{"Name"} ne $T2->{"Name"}
-    and not isAnon($T1->{"Name"})
-    and not isAnon($T2->{"Name"}))
+    
+    my $N1 = $T1->{"Name"};
+    my $N2 = $T2->{"Name"};
+    
+    $N1=~s/\A(struct|union|enum) //;
+    $N2=~s/\A(struct|union|enum) //;
+    
+    if($N1 ne $N2
+    and not isAnon($N1)
+    and not isAnon($N2))
     { # different names
         if($T1->{"Type"} ne "Pointer"
         or $T2->{"Type"} ne "Pointer")
         { # compare base types
             return 1;
         }
-        if($T1->{"Name"}!~/\Avoid\s*\*/
-        and $T2->{"Name"}=~/\Avoid\s*\*/)
+        if($N1!~/\Avoid\s*\*/
+        and $N2=~/\Avoid\s*\*/)
         {
             return 1;
         }
@@ -10632,6 +10727,30 @@
     return 0;
 }
 
+sub isOpaque($)
+{
+    my $T = $_[0];
+    if(not defined $T->{"Memb"})
+    {
+        return 1;
+    }
+    return 0;
+}
+
+sub removeVPtr($)
+{ # support for old ABI dumps
+    my $TPtr = $_[0];
+    my @Pos = sort {int($a)<=>int($b)} keys(%{$TPtr->{"Memb"}});
+    if($#Pos>=1)
+    {
+        foreach my $Pos (0 .. $#Pos-1)
+        {
+            %{$TPtr->{"Memb"}{$Pos}} = %{$TPtr->{"Memb"}{$Pos+1}};
+        }
+        delete($TPtr->{"Memb"}{$#Pos});
+    }
+}
+
 sub mergeTypes($$$)
 {
     my ($Type1_Id, $Type2_Id, $Level) = @_;
@@ -10646,10 +10765,29 @@
     if(not $Type1{"Name"} or not $Type2{"Name"}) {
         return ();
     }
-    $CheckedTypes{$Level}{$Type1{"Name"}}=1;
+    
+    $CheckedTypes{$Level}{$Type1{"Name"}} = 1;
     my %Type1_Pure = get_PureType($Type1_Id, $TypeInfo{1});
     my %Type2_Pure = get_PureType($Type2_Id, $TypeInfo{2});
-    $CheckedTypes{$Level}{$Type1_Pure{"Name"}}=1;
+    $CheckedTypes{$Level}{$Type1_Pure{"Name"}} = 1;
+    
+    if($Type1_Pure{"Name"} eq $Type2_Pure{"Name"})
+    {
+        if($Type1_Pure{"Type"}=~/Struct|Union/
+        and $Type2_Pure{"Type"}=~/Struct|Union/)
+        {
+            if(isOpaque(\%Type2_Pure) and not isOpaque(\%Type1_Pure))
+            {
+                %{$SubProblems{"Type_Became_Opaque"}{$Type1_Pure{"Name"}}}=(
+                    "Target"=>$Type1_Pure{"Name"},
+                    "Type_Name"=>$Type1_Pure{"Name"}  );
+                
+                %{$Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id}} = %SubProblems;
+                return %SubProblems;
+            }
+        }
+    }
+    
     if(not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"})
     { # including a case when "class Class { ... };" changed to "class Class;"
         return ();
@@ -10662,8 +10800,40 @@
     return () if($SkipTypes{1}{$Type1_Pure{"Name"}});
     return () if($SkipTypes{1}{$Type1{"Name"}});
     
+    if($Type1_Pure{"Type"}=~/Class|Struct/ and $Type2_Pure{"Type"}=~/Class|Struct/)
+    { # support for old ABI dumps
+      # _vptr field added in 3.0
+        if(not checkDump(1, "3.0") and checkDump(2, "3.0"))
+        {
+            if(defined $Type2_Pure{"Memb"}
+            and $Type2_Pure{"Memb"}{0}{"name"} eq "_vptr")
+            {
+                if(keys(%{$Type2_Pure{"Memb"}})==1) {
+                    delete($Type2_Pure{"Memb"}{0});
+                }
+                else {
+                    removeVPtr(\%Type2_Pure);
+                }
+            }
+        }
+        if(checkDump(1, "3.0") and not checkDump(2, "3.0"))
+        {
+            if(defined $Type1_Pure{"Memb"}
+            and $Type1_Pure{"Memb"}{0}{"name"} eq "_vptr")
+            {
+                if(keys(%{$Type1_Pure{"Memb"}})==1) {
+                    delete($Type1_Pure{"Memb"}{0});
+                }
+                else {
+                    removeVPtr(\%Type1_Pure);
+                }
+            }
+        }
+    }
+    
     my %Typedef_1 = goToFirst($Type1{"Tid"}, 1, "Typedef");
     my %Typedef_2 = goToFirst($Type2{"Tid"}, 2, "Typedef");
+    
     if(not $UseOldDumps and %Typedef_1 and %Typedef_2
     and $Typedef_1{"Type"} eq "Typedef" and $Typedef_2{"Type"} eq "Typedef"
     and $Typedef_1{"Name"} eq $Typedef_2{"Name"})
@@ -10698,23 +10868,25 @@
             }
             my %Base1_Pure = get_PureType($Base_1{"Tid"}, $TypeInfo{1});
             my %Base2_Pure = get_PureType($Base_2{"Tid"}, $TypeInfo{2});
-            if(diffTypes($Base1_Pure{"Tid"}, $Base2_Pure{"Tid"}, $Level))
+            if(tNameLock($Base_1{"Tid"}, $Base_2{"Tid"}))
             {
-                %{$SubProblems{"Typedef_BaseType_Format"}{$Typedef_1{"Name"}}}=(
-                    "Target"=>$Typedef_1{"Name"},
-                    "Type_Name"=>$Typedef_1{"Name"},
-                    "Old_Value"=>$Base_1{"Name"},
-                    "New_Value"=>$Base_2{"Name"}  );
+                if(diffTypes($Base1_Pure{"Tid"}, $Base2_Pure{"Tid"}, $Level))
+                {
+                    %{$SubProblems{"Typedef_BaseType_Format"}{$Typedef_1{"Name"}}}=(
+                        "Target"=>$Typedef_1{"Name"},
+                        "Type_Name"=>$Typedef_1{"Name"},
+                        "Old_Value"=>$Base_1{"Name"},
+                        "New_Value"=>$Base_2{"Name"}  );
+                }
+                else
+                {
+                    %{$SubProblems{"Typedef_BaseType"}{$Typedef_1{"Name"}}}=(
+                        "Target"=>$Typedef_1{"Name"},
+                        "Type_Name"=>$Typedef_1{"Name"},
+                        "Old_Value"=>$Base_1{"Name"},
+                        "New_Value"=>$Base_2{"Name"}  );
+                }
             }
-            else
-            {
-                %{$SubProblems{"Typedef_BaseType"}{$Typedef_1{"Name"}}}=(
-                    "Target"=>$Typedef_1{"Name"},
-                    "Type_Name"=>$Typedef_1{"Name"},
-                    "Old_Value"=>$Base_1{"Name"},
-                    "New_Value"=>$Base_2{"Name"}  );
-            }
-            
         }
     }
     if(nonComparable(\%Type1_Pure, \%Type2_Pure))
@@ -10763,7 +10935,8 @@
                     if(int($Type2_Pure{"Size"})>int($Type1_Pure{"Size"})) {
                         $ProblemKind = "Size_Of_Allocable_Class_Increased";
                     }
-                    else {
+                    else
+                    {
                         # descreased size of allocable class
                         # it has no special effects
                     }
@@ -10777,10 +10950,10 @@
                 "InitialType_Type"=>$Type1_Pure{"Type"}  );
         }
     }
-    if(defined $Type1_Pure{"BaseType"} and $Type1_Pure{"BaseType"}{"Tid"}
-    and defined $Type2_Pure{"BaseType"} and $Type2_Pure{"BaseType"}{"Tid"})
+    if(defined $Type1_Pure{"BaseType"}
+    and defined $Type2_Pure{"BaseType"})
     { # checking base types
-        %Sub_SubProblems = mergeTypes($Type1_Pure{"BaseType"}{"Tid"}, $Type2_Pure{"BaseType"}{"Tid"}, $Level);
+        %Sub_SubProblems = mergeTypes($Type1_Pure{"BaseType"}, $Type2_Pure{"BaseType"}, $Level);
         foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
         {
             foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
@@ -11002,11 +11175,11 @@
                     $ProblemType = "Removed_Private_Field";
                 }
                 if($Level eq "Binary"
-                and not isMemPadded($Member_Pos, -1, \%Type1_Pure, \%RemovedField, $TypeInfo{1}, $WORD_SIZE{1}))
+                and not isMemPadded($Member_Pos, -1, \%Type1_Pure, \%RemovedField, $TypeInfo{1}, getArch(1), $WORD_SIZE{1}))
                 {
                     if(my $MNum = isAccessible(\%Type1_Pure, \%RemovedField, $Member_Pos+1, -1))
                     { # affected fields
-                        if(getOffset($MNum-1, \%Type1_Pure, $TypeInfo{1}, $WORD_SIZE{1})!=getOffset($RelatedField{$MNum-1}, \%Type2_Pure, $TypeInfo{2}, $WORD_SIZE{2}))
+                        if(getOffset($MNum-1, \%Type1_Pure, $TypeInfo{1}, getArch(1), $WORD_SIZE{1})!=getOffset($RelatedField{$MNum-1}, \%Type2_Pure, $TypeInfo{2}, getArch(2), $WORD_SIZE{2}))
                         { # changed offset
                             $ProblemType .= "_And_Layout";
                         }
@@ -11062,6 +11235,9 @@
                     if(isLastElem($Member_Pos, \%Type1_Pure)) {
                         $ProblemType = "Enum_Last_Member_Value";
                     }
+                    if($SkipConstants{1}{$Member_Name}) {
+                        $ProblemType = "Enum_Private_Member_Value";
+                    }
                     %{$SubProblems{$ProblemType}{$Member_Name}}=(
                         "Target"=>$Member_Name,
                         "Type_Name"=>$Type1_Pure{"Name"},
@@ -11071,6 +11247,25 @@
             }
             elsif($Type2_Pure{"Type"}=~/\A(Struct|Class|Union)\Z/)
             {
+                my $Access1 = $Type1_Pure{"Memb"}{$Member_Pos}{"access"};
+                my $Access2 = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"access"};
+                
+                if($Access1 ne "private"
+                and $Access2 eq "private")
+                {
+                    %{$SubProblems{"Field_Became_Private"}{$Member_Name}}=(
+                        "Target"=>$Member_Name,
+                        "Type_Name"=>$Type1_Pure{"Name"});
+                }
+                elsif($Access1 ne "protected"
+                and $Access1 ne "private"
+                and $Access2 eq "protected")
+                {
+                    %{$SubProblems{"Field_Became_Protected"}{$Member_Name}}=(
+                        "Target"=>$Member_Name,
+                        "Type_Name"=>$Type1_Pure{"Name"});
+                }
+                
                 my $MemberType1_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
                 my $MemberType2_Id = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"type"};
                 my $SizeV1 = $TypeInfo{1}{$MemberType1_Id}{"Size"}*$BYTE_SIZE;
@@ -11099,11 +11294,12 @@
                           # example: "abidata" members in GStreamer types
                             $ProblemType = "Private_".$ProblemType;
                         }
-                        if(not isMemPadded($Member_Pos, $TypeInfo{2}{$MemberType2_Id}{"Size"}*$BYTE_SIZE, \%Type1_Pure, \%RemovedField, $TypeInfo{1}, $WORD_SIZE{1}))
+                        if(not isMemPadded($Member_Pos, $TypeInfo{2}{$MemberType2_Id}{"Size"}*$BYTE_SIZE, \%Type1_Pure, \%RemovedField, $TypeInfo{1}, getArch(1), $WORD_SIZE{1}))
                         { # check an effect
-                            if(my $MNum = isAccessible(\%Type1_Pure, \%RemovedField, $Member_Pos+1, -1))
+                            if($Type2_Pure{"Type"} ne "Union"
+                            and my $MNum = isAccessible(\%Type1_Pure, \%RemovedField, $Member_Pos+1, -1))
                             { # public fields after the current
-                                if(getOffset($MNum-1, \%Type1_Pure, $TypeInfo{1}, $WORD_SIZE{1})!=getOffset($RelatedField{$MNum-1}, \%Type2_Pure, $TypeInfo{2}, $WORD_SIZE{2}))
+                                if(getOffset($MNum-1, \%Type1_Pure, $TypeInfo{1}, getArch(1), $WORD_SIZE{1})!=getOffset($RelatedField{$MNum-1}, \%Type2_Pure, $TypeInfo{2}, getArch(2), $WORD_SIZE{2}))
                                 { # changed offset
                                     $ProblemType .= "_And_Layout";
                                 }
@@ -11143,7 +11339,7 @@
                     elsif($Type1_Pure{"Memb"}{$Member_Pos}{"mutable"}
                     and not $Type2_Pure{"Memb"}{$MemberPair_Pos}{"mutable"})
                     {
-                        %{$SubProblems{"Field_Became_NonMutable"}{$Member_Name}}=(
+                        %{$SubProblems{"Field_Became_Non_Mutable"}{$Member_Name}}=(
                             "Target"=>$Member_Name,
                             "Type_Name"=>$Type1_Pure{"Name"});
                     }
@@ -11153,26 +11349,19 @@
                 {
                     my $Old_Value = $Sub_SubProblems{$ProblemType}{"Old_Value"};
                     my $New_Value = $Sub_SubProblems{$ProblemType}{"New_Value"};
+                    
+                    # quals
                     if($ProblemType eq "Field_Type"
-                    or $ProblemType eq "Field_Type_And_Size")
+                    or $ProblemType eq "Field_Type_And_Size"
+                    or $ProblemType eq "Field_Type_Format")
                     {
                         if(checkDump(1, "2.6") and checkDump(2, "2.6"))
                         {
-                            if(my $RA = addedQual($Old_Value, $New_Value, "volatile"))
-                            {
+                            if(addedQual($Old_Value, $New_Value, "volatile")) {
                                 %{$Sub_SubProblems{"Field_Became_Volatile"}} = %{$Sub_SubProblems{$ProblemType}};
-                                if($Level eq "Source"
-                                and cmpBTypes($Old_Value, $New_Value, 1, 2)) {
-                                    delete($Sub_SubProblems{$ProblemType});
-                                }
                             }
-                            elsif(my $RR = removedQual($Old_Value, $New_Value, "volatile"))
-                            {
-                                %{$Sub_SubProblems{"Field_Became_NonVolatile"}} = %{$Sub_SubProblems{$ProblemType}};
-                                if($Level eq "Source"
-                                and cmpBTypes($Old_Value, $New_Value, 1, 2)) {
-                                    delete($Sub_SubProblems{$ProblemType});
-                                }
+                            elsif(removedQual($Old_Value, $New_Value, "volatile")) {
+                                %{$Sub_SubProblems{"Field_Became_Non_Volatile"}} = %{$Sub_SubProblems{$ProblemType}};
                             }
                         }
                         if(my $RA = addedQual($Old_Value, $New_Value, "const"))
@@ -11183,10 +11372,6 @@
                             else {
                                 %{$Sub_SubProblems{"Field_Became_Const"}} = %{$Sub_SubProblems{$ProblemType}};
                             }
-                            if($Level eq "Source"
-                            and cmpBTypes($Old_Value, $New_Value, 1, 2)) {
-                                delete($Sub_SubProblems{$ProblemType});
-                            }
                         }
                         elsif(my $RR = removedQual($Old_Value, $New_Value, "const"))
                         {
@@ -11194,15 +11379,28 @@
                                 %{$Sub_SubProblems{"Field_Removed_Const"}} = %{$Sub_SubProblems{$ProblemType}};
                             }
                             else {
-                                %{$Sub_SubProblems{"Field_Became_NonConst"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubProblems{"Field_Became_Non_Const"}} = %{$Sub_SubProblems{$ProblemType}};
                             }
-                            if($Level eq "Source"
-                            and cmpBTypes($Old_Value, $New_Value, 1, 2)) {
+                        }
+                    }
+                }
+                
+                if($Level eq "Source")
+                {
+                    foreach my $ProblemType (keys(%Sub_SubProblems))
+                    {
+                        my $Old_Value = $Sub_SubProblems{$ProblemType}{"Old_Value"};
+                        my $New_Value = $Sub_SubProblems{$ProblemType}{"New_Value"};
+                        
+                        if($ProblemType eq "Field_Type")
+                        {
+                            if(cmpBTypes($Old_Value, $New_Value, 1, 2)) {
                                 delete($Sub_SubProblems{$ProblemType});
                             }
                         }
                     }
                 }
+                
                 foreach my $ProblemType (keys(%Sub_SubProblems))
                 {
                     my $ProblemType_Init = $ProblemType;
@@ -11212,11 +11410,12 @@
                         or isUnnamed($Member_Name)) {
                             $ProblemType = "Private_".$ProblemType;
                         }
-                        if(not isMemPadded($Member_Pos, $TypeInfo{2}{$MemberType2_Id}{"Size"}*$BYTE_SIZE, \%Type1_Pure, \%RemovedField, $TypeInfo{1}, $WORD_SIZE{1}))
+                        if(not isMemPadded($Member_Pos, $TypeInfo{2}{$MemberType2_Id}{"Size"}*$BYTE_SIZE, \%Type1_Pure, \%RemovedField, $TypeInfo{1}, getArch(1), $WORD_SIZE{1}))
                         { # check an effect
-                            if(my $MNum = isAccessible(\%Type1_Pure, \%RemovedField, $Member_Pos+1, -1))
+                            if($Type2_Pure{"Type"} ne "Union"
+                            and my $MNum = isAccessible(\%Type1_Pure, \%RemovedField, $Member_Pos+1, -1))
                             { # public fields after the current
-                                if(getOffset($MNum-1, \%Type1_Pure, $TypeInfo{1}, $WORD_SIZE{1})!=getOffset($RelatedField{$MNum-1}, \%Type2_Pure, $TypeInfo{2}, $WORD_SIZE{2}))
+                                if(getOffset($MNum-1, \%Type1_Pure, $TypeInfo{1}, getArch(1), $WORD_SIZE{1})!=getOffset($RelatedField{$MNum-1}, \%Type2_Pure, $TypeInfo{2}, getArch(2), $WORD_SIZE{2}))
                                 { # changed offset
                                     $ProblemType .= "_And_Layout";
                                 }
@@ -11289,11 +11488,11 @@
                     $ProblemType = "Added_Private_Field";
                 }
                 if($Level eq "Binary"
-                and not isMemPadded($Member_Pos, -1, \%Type2_Pure, \%AddedField, $TypeInfo{2}, $WORD_SIZE{2}))
+                and not isMemPadded($Member_Pos, -1, \%Type2_Pure, \%AddedField, $TypeInfo{2}, getArch(2), $WORD_SIZE{2}))
                 {
                     if(my $MNum = isAccessible(\%Type2_Pure, \%AddedField, $Member_Pos, -1))
                     { # public fields after the current
-                        if(getOffset($MNum-1, \%Type2_Pure, $TypeInfo{2}, $WORD_SIZE{2})!=getOffset($RelatedField_Rev{$MNum-1}, \%Type1_Pure, $TypeInfo{1}, $WORD_SIZE{1}))
+                        if(getOffset($MNum-1, \%Type2_Pure, $TypeInfo{2}, getArch(2), $WORD_SIZE{2})!=getOffset($RelatedField_Rev{$MNum-1}, \%Type1_Pure, $TypeInfo{1}, getArch(1), $WORD_SIZE{1}))
                         { # changed offset
                             $ProblemType .= "_And_Layout";
                         }
@@ -11371,9 +11570,8 @@
     return () if(not $Type{"Type"});
     if($Type{"Type"} ne $Type_Type)
     {
-        return () if(not defined $Type{"BaseType"});
-        return () if(not $Type{"BaseType"}{"Tid"});
-        %Type = goToFirst($Type{"BaseType"}{"Tid"}, $LibVersion, $Type_Type);
+        return () if(not $Type{"BaseType"});
+        %Type = goToFirst($Type{"BaseType"}, $LibVersion, $Type_Type);
     }
     $Cache{"goToFirst"}{$TypeId}{$LibVersion}{$Type_Type} = \%Type;
     return %Type;
@@ -11398,10 +11596,9 @@
         return %{$Cache{"get_PureType"}{$TypeId}{$Info}};
     }
     my %Type = %{$Info->{$TypeId}};
-    return %Type if(not defined $Type{"BaseType"});
-    return %Type if(not $Type{"BaseType"}{"Tid"});
+    return %Type if(not $Type{"BaseType"});
     if($TypeSpecAttributes{$Type{"Type"}}) {
-        %Type = get_PureType($Type{"BaseType"}{"Tid"}, $Info);
+        %Type = get_PureType($Type{"BaseType"}, $Info);
     }
     $Cache{"get_PureType"}{$TypeId}{$Info} = \%Type;
     return %Type;
@@ -11416,16 +11613,15 @@
     }
     return 0 if(not $TypeInfo{$LibVersion}{$TypeId});
     my %Type = %{$TypeInfo{$LibVersion}{$TypeId}};
-    return 1 if($Type{"Type"}=~/FuncPtr|MethodPtr|FieldPtr/);
-    return 0 if(not defined $Type{"BaseType"});
-    return 0 if(not $Type{"BaseType"}{"Tid"});
-    my $PointerLevel = 0;
-    if($Type{"Type"} =~/Pointer|Ref|FuncPtr|MethodPtr|FieldPtr/) {
-        $PointerLevel += 1;
+    return 1 if($Type{"Type"}=~/FuncPtr|FieldPtr/);
+    my $PLevel = 0;
+    if($Type{"Type"} =~/Pointer|Ref|FuncPtr|FieldPtr/) {
+        $PLevel += 1;
     }
-    $PointerLevel += get_PLevel($Type{"BaseType"}{"Tid"}, $LibVersion);
-    $Cache{"get_PLevel"}{$TypeId}{$LibVersion} = $PointerLevel;
-    return $PointerLevel;
+    return $PLevel if(not $Type{"BaseType"});
+    $PLevel += get_PLevel($Type{"BaseType"}, $LibVersion);
+    $Cache{"get_PLevel"}{$TypeId}{$LibVersion} = $PLevel;
+    return $PLevel;
 }
 
 sub get_BaseType($$)
@@ -11437,9 +11633,8 @@
     }
     return () if(not $TypeInfo{$LibVersion}{$TypeId});
     my %Type = %{$TypeInfo{$LibVersion}{$TypeId}};
-    return %Type if(not defined $Type{"BaseType"});
-    return %Type if(not $Type{"BaseType"}{"Tid"});
-    %Type = get_BaseType($Type{"BaseType"}{"Tid"}, $LibVersion);
+    return %Type if(not $Type{"BaseType"});
+    %Type = get_BaseType($Type{"BaseType"}, $LibVersion);
     $Cache{"get_BaseType"}{$TypeId}{$LibVersion} = \%Type;
     return %Type;
 }
@@ -11450,8 +11645,7 @@
     return "" if(not $TypeId);
     return "" if(not $TypeInfo{$LibVersion}{$TypeId});
     my %Type = %{$TypeInfo{$LibVersion}{$TypeId}};
-    return "" if(not defined $Type{"BaseType"});
-    return "" if(not $Type{"BaseType"}{"Tid"});
+    return "" if(not $Type{"BaseType"});
     my $Qual = "";
     if($Type{"Type"} eq "Pointer") {
         $Qual .= "*";
@@ -11467,7 +11661,7 @@
     or $Type{"Type"} eq "Restrict") {
         $Qual .= lc($Type{"Type"});
     }
-    my $BQual = get_BaseTypeQual($Type{"BaseType"}{"Tid"}, $LibVersion);
+    my $BQual = get_BaseTypeQual($Type{"BaseType"}, $LibVersion);
     return $BQual.$Qual;
 }
 
@@ -11479,8 +11673,8 @@
         return ();
     }
     my %Type = %{$Info->{$TypeId}};
-    return %Type if(not defined $Type{"BaseType"});
-    if(my $BTid = $Type{"BaseType"}{"Tid"})
+    return %Type if(not $Type{"BaseType"});
+    if(my $BTid = $Type{"BaseType"})
     {
         if($Info->{$BTid}) {
             return %{$Info->{$BTid}};
@@ -11633,6 +11827,10 @@
         { # user defined symbols
             return 0;
         }
+        if($SkipSymbolsListPath and $SkipSymbolsList{$Symbol})
+        { # user defined symbols
+            return 0;
+        }
         if($AppPath and not $SymbolsList_App{$Symbol})
         { # user defined symbols (in application)
             return 0;
@@ -12326,7 +12524,7 @@
                         }
                         else
                         {
-                            %{$CompatProblems{$Level}{$Symbol}{"Symbol_Became_NonStatic"}{$tr_name{$Symbol}}}=(
+                            %{$CompatProblems{$Level}{$Symbol}{"Symbol_Became_Non_Static"}{$tr_name{$Symbol}}}=(
                                 "Target"=>$tr_name{$Symbol},
                                 "Old_Value"=>$Symbol,
                                 "New_Value"=>$NewSym  );
@@ -12343,7 +12541,7 @@
                         }
                         else
                         {
-                            %{$CompatProblems{$Level}{$Symbol}{"Symbol_Became_NonVirtual"}{$tr_name{$Symbol}}}=(
+                            %{$CompatProblems{$Level}{$Symbol}{"Symbol_Became_Non_Virtual"}{$tr_name{$Symbol}}}=(
                                 "Target"=>$tr_name{$Symbol},
                                 "Old_Value"=>$Symbol,
                                 "New_Value"=>$NewSym  );
@@ -12399,7 +12597,7 @@
                     if($CompleteSignature{1}{$Symbol}{"Const"}
                     and not $CompleteSignature{2}{$NewSym}{"Const"})
                     { # "const" to non-"const"
-                        %{$CompatProblems{$Level}{$Symbol}{"Method_Became_NonConst"}{$tr_name{$Symbol}}}=(
+                        %{$CompatProblems{$Level}{$Symbol}{"Method_Became_Non_Const"}{$tr_name{$Symbol}}}=(
                             "Type_Name"=>$TypeInfo{1}{$CompleteSignature{1}{$Symbol}{"Class"}}{"Name"},
                             "Target"=>$tr_name{$Symbol},
                             "New_Signature"=>get_Signature($NewSym, 2),
@@ -12419,7 +12617,7 @@
                     and not $CompleteSignature{2}{$NewSym}{"Volatile"})
                     { # "volatile" to non-"volatile"
                         
-                        %{$CompatProblems{$Level}{$Symbol}{"Method_Became_NonVolatile"}{$tr_name{$Symbol}}}=(
+                        %{$CompatProblems{$Level}{$Symbol}{"Method_Became_Non_Volatile"}{$tr_name{$Symbol}}}=(
                             "Target"=>$tr_name{$Symbol},
                             "New_Signature"=>get_Signature($NewSym, 2),
                             "Old_Value"=>$Symbol,
@@ -12589,7 +12787,7 @@
         elsif(not $CompleteSignature{2}{$PSymbol}{"Static"}
         and $CompleteSignature{1}{$Symbol}{"Static"} and $Symbol=~/\A(_Z|\?)/)
         {
-            %{$CompatProblems{$Level}{$Symbol}{"Method_Became_NonStatic"}{""}}=(
+            %{$CompatProblems{$Level}{$Symbol}{"Method_Became_Non_Static"}{""}}=(
                 "Target"=>get_Signature($Symbol, 1)
             );
         }
@@ -12801,48 +12999,83 @@
         my $ReturnType1_Id = $CompleteSignature{1}{$Symbol}{"Return"};
         my $ReturnType2_Id = $CompleteSignature{2}{$PSymbol}{"Return"};
         %SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return", $Level);
+        
         foreach my $SubProblemType (keys(%SubProblems))
         {
             my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
             my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
-            my $NewProblemType = $SubProblemType;
-            my $AddProblemType = undef;
+            my %ProblemTypes = ();
             
-            if($SubProblemType eq "Return_Type_And_Size"
-            and $CompleteSignature{1}{$Symbol}{"Data"}) {
-                $NewProblemType = "Global_Data_Type_And_Size";
-            }
-            elsif($SubProblemType eq "Return_Type")
+            if($CompleteSignature{1}{$Symbol}{"Data"})
             {
-                if($CompleteSignature{1}{$Symbol}{"Data"})
+                if($SubProblemType eq "Return_Type_And_Size") {
+                    $ProblemTypes{"Global_Data_Type_And_Size"} = 1;
+                }
+                elsif($SubProblemType eq "Return_Type_Format") {
+                    $ProblemTypes{"Global_Data_Type_Format"} = 1;
+                }
+                else {
+                    $ProblemTypes{"Global_Data_Type"} = 1;
+                }
+                
+                # quals
+                if($SubProblemType eq "Return_Type"
+                or $SubProblemType eq "Return_Type_And_Size"
+                or $SubProblemType eq "Return_Type_Format")
                 {
-                    if(removedQual($Old_Value, $New_Value, "const"))
-                    { # const -> non-const global data
-                        $NewProblemType = "Global_Data_Became_Non_Const";
-                        $AddProblemType = "Global_Data_Type";
+                    if(my $RR = removedQual($Old_Value, $New_Value, "const"))
+                    { # const to non-const
+                        if($RR==2) {
+                            $ProblemTypes{"Global_Data_Removed_Const"} = 1;
+                        }
+                        else {
+                            $ProblemTypes{"Global_Data_Became_Non_Const"} = 1;
+                        }
+                        $ProblemTypes{"Global_Data_Type"} = 1;
                     }
-                    elsif(addedQual($Old_Value, $New_Value, "const"))
-                    { # non-const -> const global data
-                        $NewProblemType = "Global_Data_Became_Const";
-                        $AddProblemType = "Global_Data_Type";
-                    }
-                    else {
-                        $NewProblemType = "Global_Data_Type";
+                    elsif(my $RA = addedQual($Old_Value, $New_Value, "const"))
+                    { # non-const to const
+                        if($RA==2) {
+                            $ProblemTypes{"Global_Data_Added_Const"} = 1;
+                        }
+                        else {
+                            $ProblemTypes{"Global_Data_Became_Const"} = 1;
+                        }
+                        $ProblemTypes{"Global_Data_Type"} = 1;
                     }
                 }
-                else
+            }
+            else
+            {
+                # quals
+                if($SubProblemType eq "Return_Type"
+                or $SubProblemType eq "Return_Type_And_Size"
+                or $SubProblemType eq "Return_Type_Format")
                 {
-                    if(addedQual($Old_Value, $New_Value, "const"))
+                    if(checkDump(1, "2.6") and checkDump(2, "2.6"))
                     {
-                        $NewProblemType = "Return_Type_Became_Const";
-                        $AddProblemType = "Return_Type";
+                        if(addedQual($Old_Value, $New_Value, "volatile"))
+                        {
+                            $ProblemTypes{"Return_Value_Became_Volatile"} = 1;
+                            if($Level ne "Source"
+                            or not cmpBTypes($Old_Value, $New_Value, 1, 2)) {
+                                $ProblemTypes{"Return_Type"} = 1;
+                            }
+                        }
                     }
-                }
-            }
-            elsif($SubProblemType eq "Return_Type_Format")
-            {
-                if($CompleteSignature{1}{$Symbol}{"Data"}) {
-                    $NewProblemType = "Global_Data_Type_Format";
+                    if(my $RA = addedQual($Old_Value, $New_Value, "const"))
+                    {
+                        if($RA==2) {
+                            $ProblemTypes{"Return_Type_Added_Const"} = 1;
+                        }
+                        else {
+                            $ProblemTypes{"Return_Type_Became_Const"} = 1;
+                        }
+                        if($Level ne "Source"
+                        or not cmpBTypes($Old_Value, $New_Value, 1, 2)) {
+                            $ProblemTypes{"Return_Type"} = 1;
+                        }
+                    }
                 }
             }
             if($Level eq "Binary"
@@ -12855,7 +13088,7 @@
                     ($Arch1, $Arch2) = ("unknown", "unknown");
                 }
                 my (%Conv1, %Conv2) = ();
-                if($UseConv_Real{1} and $UseConv_Real{1})
+                if($UseConv_Real{1}{"R"} and $UseConv_Real{2}{"R"})
                 {
                     %Conv1 = callingConvention_R_Real($CompleteSignature{1}{$Symbol});
                     %Conv2 = callingConvention_R_Real($CompleteSignature{2}{$PSymbol});
@@ -12871,10 +13104,10 @@
                     if(keys(%{$CompleteSignature{1}{$Symbol}{"Param"}}))
                     { # parameters stack has been affected
                         if($Conv1{"Method"} eq "stack") {
-                            $NewProblemType = "Return_Type_Became_Void_And_Stack_Layout";
+                            $ProblemTypes{"Return_Type_Became_Void_And_Stack_Layout"} = 1;
                         }
                         elsif($Conv1{"Hidden"}) {
-                            $NewProblemType = "Return_Type_Became_Void_And_Register";
+                            $ProblemTypes{"Return_Type_Became_Void_And_Register"} = 1;
                         }
                     }
                 }
@@ -12883,10 +13116,10 @@
                     if(keys(%{$CompleteSignature{1}{$Symbol}{"Param"}}))
                     { # parameters stack has been affected
                         if($Conv2{"Method"} eq "stack") {
-                            $NewProblemType = "Return_Type_From_Void_And_Stack_Layout";
+                            $ProblemTypes{"Return_Type_From_Void_And_Stack_Layout"} = 1;
                         }
                         elsif($Conv2{"Hidden"}) {
-                            $NewProblemType = "Return_Type_From_Void_And_Register";
+                            $ProblemTypes{"Return_Type_From_Void_And_Register"} = 1;
                         }
                     }
                 }
@@ -12898,10 +13131,10 @@
                     {
                         if($Conv1{"Method"} eq "stack")
                         { # returns in a register instead of a hidden first parameter
-                            $NewProblemType = "Return_Type_From_Stack_To_Register";
+                            $ProblemTypes{"Return_Type_From_Stack_To_Register"} = 1;
                         }
                         else {
-                            $NewProblemType = "Return_Type_From_Register_To_Stack";
+                            $ProblemTypes{"Return_Type_From_Register_To_Stack"} = 1;
                         }
                     }
                     else
@@ -12911,37 +13144,66 @@
                             if($Conv1{"Registers"} ne $Conv2{"Registers"})
                             {
                                 if($Conv1{"Hidden"}) {
-                                    $NewProblemType = "Return_Type_And_Register_Was_Hidden_Parameter";
+                                    $ProblemTypes{"Return_Type_And_Register_Was_Hidden_Parameter"} = 1;
                                 }
                                 elsif($Conv2{"Hidden"}) {
-                                    $NewProblemType = "Return_Type_And_Register_Became_Hidden_Parameter";
+                                    $ProblemTypes{"Return_Type_And_Register_Became_Hidden_Parameter"} = 1;
                                 }
                                 else {
-                                    $NewProblemType = "Return_Type_And_Register";
+                                    $ProblemTypes{"Return_Type_And_Register"} = 1;
                                 }
                             }
                         }
                     }
                 }
             }
-            @{$CompatProblems{$Level}{$Symbol}{$NewProblemType}{"retval"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
-            if(defined $AddProblemType) {
-                @{$CompatProblems{$Level}{$Symbol}{$AddProblemType}{"retval"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
+            
+            if(not keys(%ProblemTypes))
+            { # default
+                $ProblemTypes{$SubProblemType} = 1;
+            }
+            
+            foreach my $ProblemType (keys(%ProblemTypes))
+            { # additional
+                @{$CompatProblems{$Level}{$Symbol}{$ProblemType}{"retval"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
             }
         }
         if($ReturnType1_Id and $ReturnType2_Id)
         {
             @RecurTypes = ();
             %SubProblems = mergeTypes($ReturnType1_Id, $ReturnType2_Id, $Level);
-            foreach my $SubProblemType (keys(%SubProblems))
-            { # add "Global_Data_Size" problem
-                my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
-                my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
-                if($SubProblemType eq "DataType_Size"
-                and $CompleteSignature{1}{$Symbol}{"Data"}
-                and get_PLevel($ReturnType1_Id, 1)==0)
-                { # add a new problem
-                    %{$SubProblems{"Global_Data_Size"}} = %{$SubProblems{$SubProblemType}};
+            
+            if($CompleteSignature{1}{$Symbol}{"Data"})
+            {
+                if($Level eq "Binary")
+                {
+                    if(get_PLevel($ReturnType1_Id, 1)==0)
+                    {
+                        foreach my $SubProblemType (keys(%SubProblems))
+                        { # add "Global_Data_Size" problem
+                            my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
+                            my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
+                            if($SubProblemType eq "DataType_Size")
+                            { # add a new problem
+                                %{$SubProblems{"Global_Data_Size"}} = %{$SubProblems{$SubProblemType}};
+                            }
+                        }
+                    }
+                    if(not defined $SubProblems{"Global_Data_Size"})
+                    {
+                        if(defined $GlobalDataObject{1}{$Symbol}
+                        and defined $GlobalDataObject{2}{$Symbol})
+                        {
+                            my $Old_Size = $GlobalDataObject{1}{$Symbol};
+                            my $New_Size = $GlobalDataObject{2}{$Symbol};
+                            if($Old_Size!=$New_Size)
+                            {
+                                %{$SubProblems{"Global_Data_Size"}{"retval"}} = (
+                                    "Old_Size"=>$Old_Size*$BYTE_SIZE,
+                                    "New_Size"=>$New_Size*$BYTE_SIZE );
+                            }
+                        }
+                    }
                 }
             }
             foreach my $SubProblemType (keys(%SubProblems))
@@ -13022,16 +13284,16 @@
 sub addedQual($$$)
 {
     my ($Old_Value, $New_Value, $Qual) = @_;
-    return removedQual_($New_Value, $Old_Value, 2, 1, $Qual);
+    return removedQual_I($New_Value, $Old_Value, 2, 1, $Qual);
 }
 
 sub removedQual($$$)
 {
     my ($Old_Value, $New_Value, $Qual) = @_;
-    return removedQual_($Old_Value, $New_Value, 1, 2, $Qual);
+    return removedQual_I($Old_Value, $New_Value, 1, 2, $Qual);
 }
 
-sub removedQual_($$$$$)
+sub removedQual_I($$$$$)
 {
     my ($Old_Value, $New_Value, $V1, $V2, $Qual) = @_;
     $Old_Value = uncover_typedefs($Old_Value, $V1);
@@ -13134,6 +13396,27 @@
     return $Value;
 }
 
+sub getRegs($$$)
+{
+    my ($LibVersion, $Symbol, $Pos) = @_;
+    
+    if(defined $CompleteSignature{$LibVersion}{$Symbol}{"Reg"})
+    {
+        my $PName = $CompleteSignature{$LibVersion}{$Symbol}{"Param"}{$Pos}{"name"};
+        my %Regs = ();
+        foreach my $Elem (sort keys(%{$CompleteSignature{$LibVersion}{$Symbol}{"Reg"}}))
+        {
+            if($Elem=~/\A$PName([\.\+]|\Z)/) {
+                $Regs{$CompleteSignature{$LibVersion}{$Symbol}{"Reg"}{$Elem}} = 1;
+            }
+        }
+        
+        return join(", ", sort keys(%Regs));
+    }
+    
+    return undef;
+}
+
 sub mergeParameters($$$$$)
 {
     my ($Symbol, $PSymbol, $ParamPos1, $ParamPos2, $Level) = @_;
@@ -13172,6 +13455,53 @@
                     "Param_Pos"=>$ParamPos1  );
             }
         }
+        
+        if(defined $UsedDump{1}{"DWARF"}
+        and defined $UsedDump{2}{"DWARF"})
+        {
+            if(checkDump(1, "3.0") and checkDump(2, "3.0"))
+            {
+                my $Old_Regs = getRegs(1, $Symbol, $ParamPos1);
+                my $New_Regs = getRegs(2, $PSymbol, $ParamPos2);
+                if($Old_Regs and $New_Regs)
+                {
+                    if($Old_Regs ne $New_Regs)
+                    {
+                        %{$CompatProblems{$Level}{$Symbol}{"Parameter_Changed_Register"}{$Parameter_Location}}=(
+                            "Target"=>$PName1,
+                            "Param_Pos"=>$ParamPos1,
+                            "Old_Value"=>$Old_Regs,
+                            "New_Value"=>$New_Regs  );
+                    }
+                }
+                elsif($Old_Regs and not $New_Regs)
+                {
+                    %{$CompatProblems{$Level}{$Symbol}{"Parameter_From_Register"}{$Parameter_Location}}=(
+                        "Target"=>$PName1,
+                        "Param_Pos"=>$ParamPos1,
+                        "Old_Value"=>$Old_Regs  );
+                }
+                elsif(not $Old_Regs and $New_Regs)
+                {
+                    %{$CompatProblems{$Level}{$Symbol}{"Parameter_To_Register"}{$Parameter_Location}}=(
+                        "Target"=>$PName1,
+                        "Param_Pos"=>$ParamPos1,
+                        "New_Value"=>$New_Regs  );
+                }
+                if((my $Old_Offset = $CompleteSignature{1}{$Symbol}{"Param"}{$ParamPos1}{"offset"}) ne ""
+                and (my $New_Offset = $CompleteSignature{2}{$PSymbol}{"Param"}{$ParamPos2}{"offset"}) ne "")
+                {
+                    if($Old_Offset ne $New_Offset)
+                    {
+                        %{$CompatProblems{$Level}{$Symbol}{"Parameter_Changed_Offset"}{$Parameter_Location}}=(
+                            "Target"=>$PName1,
+                            "Param_Pos"=>$ParamPos1,
+                            "Old_Value"=>$Old_Offset,
+                            "New_Value"=>$New_Offset  );
+                    }
+                }
+            }
+        }
     }
     if(checkDump(1, "2.0") and checkDump(2, "2.0"))
     { # "default" attribute added in ACC 1.22 (dump 2.0 format)
@@ -13249,25 +13579,25 @@
     { # add new problems, remove false alarms
         my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
         my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
-        if($SubProblemType eq "Parameter_Type")
+        
+        # quals
+        if($SubProblemType eq "Parameter_Type"
+        or $SubProblemType eq "Parameter_Type_And_Size"
+        or $SubProblemType eq "Parameter_Type_Format")
         {
             if(checkDump(1, "2.6") and checkDump(2, "2.6"))
             {
-                if(my $RA = addedQual($Old_Value, $New_Value, "restrict"))
-                {
+                if(addedQual($Old_Value, $New_Value, "restrict")) {
                     %{$SubProblems{"Parameter_Became_Restrict"}} = %{$SubProblems{$SubProblemType}};
-                    if($Level eq "Source"
-                    and cmpBTypes($Old_Value, $New_Value, 1, 2)) {
-                        delete($SubProblems{$SubProblemType});
-                    }
                 }
-                elsif(my $RR = removedQual($Old_Value, $New_Value, "restrict"))
-                {
-                    %{$SubProblems{"Parameter_Became_NonRestrict"}} = %{$SubProblems{$SubProblemType}};
-                    if($Level eq "Source"
-                    and cmpBTypes($Old_Value, $New_Value, 1, 2)) {
-                        delete($SubProblems{$SubProblemType});
-                    }
+                elsif(removedQual($Old_Value, $New_Value, "restrict")) {
+                    %{$SubProblems{"Parameter_Became_Non_Restrict"}} = %{$SubProblems{$SubProblemType}};
+                }
+            }
+            if(checkDump(1, "2.6") and checkDump(2, "2.6"))
+            {
+                if(removedQual($Old_Value, $New_Value, "volatile")) {
+                    %{$SubProblems{"Parameter_Became_Non_Volatile"}} = %{$SubProblems{$SubProblemType}};
                 }
             }
             if($Type2{"Type"} eq "Const" and $BaseType2{"Name"} eq $Type1{"Name"}
@@ -13275,19 +13605,46 @@
             { # int to "int const"
                 delete($SubProblems{$SubProblemType});
             }
-            if($Type1{"Type"} eq "Const" and $BaseType1{"Name"} eq $Type2{"Name"}
+            elsif($Type1{"Type"} eq "Const" and $BaseType1{"Name"} eq $Type2{"Name"}
             and $Type2{"Type"}=~/Intrinsic|Class|Struct|Union|Enum/)
             { # "int const" to int
                 delete($SubProblems{$SubProblemType});
             }
+            elsif(my $RR = removedQual($Old_Value, $New_Value, "const"))
+            { # "const" to non-"const"
+                if($RR==2) {
+                    %{$SubProblems{"Parameter_Removed_Const"}} = %{$SubProblems{$SubProblemType}};
+                }
+                else {
+                    %{$SubProblems{"Parameter_Became_Non_Const"}} = %{$SubProblems{$SubProblemType}};
+                }
+            }
         }
     }
+    
+    if($Level eq "Source")
+    {
+        foreach my $SubProblemType (keys(%SubProblems))
+        {
+            my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
+            my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
+            
+            if($SubProblemType eq "Parameter_Type")
+            {
+                if(cmpBTypes($Old_Value, $New_Value, 1, 2)) {
+                    delete($SubProblems{$SubProblemType});
+                }
+            }
+        }
+    }
+    
     foreach my $SubProblemType (keys(%SubProblems))
     { # modify/register problems
         my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
         my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
         my $New_Size = $SubProblems{$SubProblemType}{"New_Size"};
         my $Old_Size = $SubProblems{$SubProblemType}{"Old_Size"};
+        
         my $NewProblemType = $SubProblemType;
         if($Old_Value eq "..." and $New_Value ne "...")
         { # change from "..." to "int"
@@ -13295,7 +13652,7 @@
             { # ISO C requires a named argument before "..."
                 next;
             }
-            $NewProblemType = "Parameter_Became_NonVaList";
+            $NewProblemType = "Parameter_Became_Non_VaList";
         }
         elsif($New_Value eq "..." and $Old_Value ne "...")
         { # change from "int" to "..."
@@ -13305,11 +13662,6 @@
             }
             $NewProblemType = "Parameter_Became_VaList";
         }
-        elsif($SubProblemType eq "Parameter_Type"
-        and removedQual($Old_Value, $New_Value, "const"))
-        { # parameter: "const" to non-"const"
-            $NewProblemType = "Parameter_Became_Non_Const";
-        }
         elsif($Level eq "Binary" and ($SubProblemType eq "Parameter_Type_And_Size"
         or $SubProblemType eq "Parameter_Type" or $SubProblemType eq "Parameter_Type_Format"))
         {
@@ -13321,7 +13673,7 @@
                 ($Arch1, $Arch2) = ("unknown", "unknown");
             }
             my (%Conv1, %Conv2) = ();
-            if($UseConv_Real{1} and $UseConv_Real{1})
+            if($UseConv_Real{1}{"P"} and $UseConv_Real{2}{"P"})
             { # real
                 %Conv1 = callingConvention_P_Real($CompleteSignature{1}{$Symbol}, $ParamPos1);
                 %Conv2 = callingConvention_P_Real($CompleteSignature{2}{$Symbol}, $ParamPos2);
@@ -13473,27 +13825,43 @@
         "double",
         "long double"
     );
-    if($Type1_Pure{"Type"} ne $Type2_Pure{"Type"})
+    
+    my $T1 = $Type1_Pure{"Type"};
+    my $T2 = $Type2_Pure{"Type"};
+    
+    if($T1 eq "Struct"
+    and $T2 eq "Class")
+    { # compare as data structures
+        $T2 = "Struct";
+    }
+    
+    if($T1 eq "Class"
+    and $T2 eq "Struct")
+    { # compare as data structures
+        $T1 = "Struct";
+    }
+    
+    if($T1 ne $T2)
     { # different types
-        if($Type1_Pure{"Type"} eq "Intrinsic"
-        and $Type2_Pure{"Type"} eq "Enum")
+        if($T1 eq "Intrinsic"
+        and $T2 eq "Enum")
         { # "int" to "enum"
             return 0;
         }
-        elsif($Type2_Pure{"Type"} eq "Intrinsic"
-        and $Type1_Pure{"Type"} eq "Enum")
+        elsif($T2 eq "Intrinsic"
+        and $T1 eq "Enum")
         { # "enum" to "int"
             return 0;
         }
         else
-        { # "union" to "struct"
+        { # union to struct
           #  ...
             return 1;
         }
     }
     else
     {
-        if($Type1_Pure{"Type"} eq "Intrinsic")
+        if($T1 eq "Intrinsic")
         {
             if($FloatType{$Type1_Pure{"Name"}}
             or $FloatType{$Type2_Pure{"Name"}})
@@ -13508,11 +13876,12 @@
                 }
             }
         }
-        elsif($Type1_Pure{"Type"}=~/Class|Struct|Union|Enum/)
+        elsif($T1=~/Class|Struct|Union|Enum/)
         {
             my @Membs1 = keys(%{$Type1_Pure{"Memb"}});
             my @Membs2 = keys(%{$Type2_Pure{"Memb"}});
-            if(not @Membs2)
+            if(not @Membs1
+            or not @Membs2)
             { # private
                 return 0;
             }
@@ -13520,7 +13889,7 @@
             { # different number of elements
                 return 1;
             }
-            if($Type1_Pure{"Type"} eq "Enum")
+            if($T1 eq "Enum")
             {
                 foreach my $Pos (@Membs1)
                 { # compare elements by name and value
@@ -13723,12 +14092,14 @@
             }
             else
             {
-                if($Type2_PLevel>$Type1_PLevel) {
+                if($Type2_PLevel>$Type1_PLevel)
+                {
                     %{$LocalProblems{$Prefix."_PointerLevel_Increased"}}=(
                         "Old_Value"=>$Type1_PLevel,
                         "New_Value"=>$Type2_PLevel);
                 }
-                else {
+                else
+                {
                     %{$LocalProblems{$Prefix."_PointerLevel_Decreased"}}=(
                         "Old_Value"=>$Type1_PLevel,
                         "New_Value"=>$Type2_PLevel);
@@ -14368,24 +14739,42 @@
 
 sub get_SourceInfo()
 {
-    my ($CheckedHeaders, $CheckedLibs) = ("", "");
+    my ($CheckedHeaders, $CheckedSources, $CheckedLibs) = ("", "");
     if(not $CheckObjectsOnly)
     {
-        $CheckedHeaders = "<a name='Headers'></a><h2>Header Files (".keys(%{$Registered_Headers{1}}).")</h2><hr/>\n";
-        $CheckedHeaders .= "<div class='h_list'>\n";
-        foreach my $Header_Path (sort {lc($Registered_Headers{1}{$a}{"Identity"}) cmp lc($Registered_Headers{1}{$b}{"Identity"})} keys(%{$Registered_Headers{1}}))
+        if(my @Headers = keys(%{$Registered_Headers{1}}))
         {
-            my $Identity = $Registered_Headers{1}{$Header_Path}{"Identity"};
-            my $Header_Name = get_filename($Identity);
-            my $Dest_Comment = ($Identity=~/[\/\\]/)?" ($Identity)":"";
-            $CheckedHeaders .= $Header_Name.$Dest_Comment."<br/>\n";
+            $CheckedHeaders = "<a name='Headers'></a><h2>Header Files (".($#Headers+1).")</h2><hr/>\n";
+            $CheckedHeaders .= "<div class='h_list'>\n";
+            foreach my $Header_Path (sort {lc($Registered_Headers{1}{$a}{"Identity"}) cmp lc($Registered_Headers{1}{$b}{"Identity"})} @Headers)
+            {
+                my $Identity = $Registered_Headers{1}{$Header_Path}{"Identity"};
+                my $Name = get_filename($Identity);
+                my $Comment = ($Identity=~/[\/\\]/)?" ($Identity)":"";
+                $CheckedHeaders .= $Name.$Comment."<br/>\n";
+            }
+            $CheckedHeaders .= "</div>\n";
+            $CheckedHeaders .= "<br/>$TOP_REF<br/>\n";
         }
-        $CheckedHeaders .= "</div>\n";
-        $CheckedHeaders .= "<br/>$TOP_REF<br/>\n";
+        
+        if(my @Sources = keys(%{$Registered_Sources{1}}))
+        {
+            $CheckedSources = "<a name='Sources'></a><h2>Source Files (".($#Sources+1).")</h2><hr/>\n";
+            $CheckedSources .= "<div class='h_list'>\n";
+            foreach my $Header_Path (sort {lc($Registered_Sources{1}{$a}{"Identity"}) cmp lc($Registered_Sources{1}{$b}{"Identity"})} @Sources)
+            {
+                my $Identity = $Registered_Sources{1}{$Header_Path}{"Identity"};
+                my $Name = get_filename($Identity);
+                my $Comment = ($Identity=~/[\/\\]/)?" ($Identity)":"";
+                $CheckedSources .= $Name.$Comment."<br/>\n";
+            }
+            $CheckedSources .= "</div>\n";
+            $CheckedSources .= "<br/>$TOP_REF<br/>\n";
+        }
     }
     if(not $CheckHeadersOnly)
     {
-        $CheckedLibs = "<a name='Libs'></a><h2>".ucfirst($SLIB_TYPE)." Libraries (".keys(%{$Library_Symbol{1}}).")</h2><hr/>\n";
+        $CheckedLibs = "<a name='Libs'></a><h2>".get_ObjTitle()." (".keys(%{$Library_Symbol{1}}).")</h2><hr/>\n";
         $CheckedLibs .= "<div class='lib_list'>\n";
         foreach my $Library (sort {lc($a) cmp lc($b)}  keys(%{$Library_Symbol{1}}))
         {
@@ -14395,7 +14784,17 @@
         $CheckedLibs .= "</div>\n";
         $CheckedLibs .= "<br/>$TOP_REF<br/>\n";
     }
-    return $CheckedHeaders.$CheckedLibs;
+    return $CheckedHeaders.$CheckedSources.$CheckedLibs;
+}
+
+sub get_ObjTitle()
+{
+    if(defined $UsedDump{1}{"DWARF"}) {
+        return "Objects";
+    }
+    else {
+        return ucfirst($SLIB_TYPE)." Libraries";
+    }
 }
 
 sub get_TypeProblems_Count($$$)
@@ -14652,14 +15051,29 @@
         $TestInfo = "<test_info>\n".$TestInfo."</test_info>\n\n";
         
         # test results
-        $TestResults .= "  <headers>\n";
-        foreach my $Name (sort {lc($Registered_Headers{1}{$a}{"Identity"}) cmp lc($Registered_Headers{1}{$b}{"Identity"})} keys(%{$Registered_Headers{1}}))
+        if(my @Headers = keys(%{$Registered_Headers{1}}))
         {
-            my $Identity = $Registered_Headers{1}{$Name}{"Identity"};
-            my $Comment = ($Identity=~/[\/\\]/)?" ($Identity)":"";
-            $TestResults .= "    <name>".get_filename($Name).$Comment."</name>\n";
+            $TestResults .= "  <headers>\n";
+            foreach my $Name (sort {lc($Registered_Headers{1}{$a}{"Identity"}) cmp lc($Registered_Headers{1}{$b}{"Identity"})} @Headers)
+            {
+                my $Identity = $Registered_Headers{1}{$Name}{"Identity"};
+                my $Comment = ($Identity=~/[\/\\]/)?" ($Identity)":"";
+                $TestResults .= "    <name>".get_filename($Name).$Comment."</name>\n";
+            }
+            $TestResults .= "  </headers>\n";
         }
-        $TestResults .= "  </headers>\n";
+        
+        if(my @Sources = keys(%{$Registered_Sources{1}}))
+        {
+            $TestResults .= "  <sources>\n";
+            foreach my $Name (sort {lc($Registered_Sources{1}{$a}{"Identity"}) cmp lc($Registered_Sources{1}{$b}{"Identity"})} @Sources)
+            {
+                my $Identity = $Registered_Sources{1}{$Name}{"Identity"};
+                my $Comment = ($Identity=~/[\/\\]/)?" ($Identity)":"";
+                $TestResults .= "    <name>".get_filename($Name).$Comment."</name>\n";
+            }
+            $TestResults .= "  </sources>\n";
+        }
         
         $TestResults .= "  <libs>\n";
         foreach my $Library (sort {lc($a) cmp lc($b)}  keys(%{$Library_Symbol{1}}))
@@ -14767,15 +15181,26 @@
         $TestResults = "<h2>Test Results</h2><hr/>\n";
         $TestResults .= "<table class='summary'>";
         
-        my $Headers_Link = "0";
-        $Headers_Link = "<a href='#Headers' style='color:Blue;'>".keys(%{$Registered_Headers{1}})."</a>" if(keys(%{$Registered_Headers{1}})>0);
-        $TestResults .= "<tr><th>Total Header Files</th><td>".($CheckObjectsOnly?"0&#160;(not&#160;analyzed)":$Headers_Link)."</td></tr>\n";
+        if(my @Headers = keys(%{$Registered_Headers{1}}))
+        {
+            my $Headers_Link = "<a href='#Headers' style='color:Blue;'>".($#Headers + 1)."</a>";
+            $TestResults .= "<tr><th>Total Header Files</th><td>".$Headers_Link."</td></tr>\n";
+        }
+        elsif($CheckObjectsOnly) {
+            $TestResults .= "<tr><th>Total Header Files</th><td>0&#160;(not&#160;analyzed)</td></tr>\n";
+        }
+        
+        if(my @Sources = keys(%{$Registered_Sources{1}}))
+        {
+            my $Src_Link = "<a href='#Sources' style='color:Blue;'>".($#Sources + 1)."</a>";
+            $TestResults .= "<tr><th>Total Source Files</th><td>".$Src_Link."</td></tr>\n";
+        }
         
         if(not $ExtendedCheck)
         {
             my $Libs_Link = "0";
             $Libs_Link = "<a href='#Libs' style='color:Blue;'>".keys(%{$Library_Symbol{1}})."</a>" if(keys(%{$Library_Symbol{1}})>0);
-            $TestResults .= "<tr><th>Total ".ucfirst($SLIB_TYPE)." Libraries</th><td>".($CheckHeadersOnly?"0&#160;(not&#160;analyzed)":$Libs_Link)."</td></tr>\n";
+            $TestResults .= "<tr><th>Total ".get_ObjTitle()."</th><td>".($CheckHeadersOnly?"0&#160;(not&#160;analyzed)":$Libs_Link)."</td></tr>\n";
         }
         
         $TestResults .= "<tr><th>Total Symbols / Types</th><td>".(keys(%{$CheckedSymbols{$Level}}) - keys(%ExtendedSymbols))." / ".$TotalTypes."</td></tr>\n";
@@ -15012,6 +15437,7 @@
                     my $Change = $CompatRules{$Level}{$Kind}{"Change"};
                     my $Effect = $CompatRules{$Level}{$Kind}{"Effect"};
                     my $Overcome = $CompatRules{$Level}{$Kind}{"Overcome"};
+                    
                     $CHANGED_CONSTANTS .= "      <problem id=\"$Kind\">\n";
                     $CHANGED_CONSTANTS .= "        <change".getXmlParams($Change, $CompatProblems_Constants{$Level}{$Constant}{$Kind}).">$Change</change>\n";
                     $CHANGED_CONSTANTS .= "        <effect".getXmlParams($Effect, $CompatProblems_Constants{$Level}{$Constant}{$Kind}).">$Effect</effect>\n";
@@ -15512,7 +15938,7 @@
             foreach my $DyLib (sort {lc($a) cmp lc($b)} keys(%{$ReportMap{$HeaderName}}))
             {
                 $INTERFACE_PROBLEMS .= "    <library name=\"$DyLib\">\n";
-                foreach my $Symbol (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%SymbolChanges))
+                foreach my $Symbol (sort {lc($tr_name{$a}?$tr_name{$a}:$a) cmp lc($tr_name{$b}?$tr_name{$b}:$b)} keys(%SymbolChanges))
                 {
                     $INTERFACE_PROBLEMS .= "      <symbol name=\"$Symbol\">\n";
                     foreach my $Kind (keys(%{$SymbolChanges{$Symbol}}))
@@ -15553,7 +15979,7 @@
                 foreach my $NameSpace (sort keys(%NameSpaceSymbols))
                 {
                     $INTERFACE_PROBLEMS .= getTitle($HeaderName, $DyLib, $NameSpace);
-                    my @SortedInterfaces = sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%{$NameSpaceSymbols{$NameSpace}});
+                    my @SortedInterfaces = sort {lc($tr_name{$a}?$tr_name{$a}:$a) cmp lc($tr_name{$b}?$tr_name{$b}:$b)} keys(%{$NameSpaceSymbols{$NameSpace}});
                     foreach my $Symbol (@SortedInterfaces)
                     {
                         my $Signature = get_Signature($Symbol, 1);
@@ -15904,7 +16330,7 @@
     if($VEntry=~/\A_ZThn.+\Z/) {
         $VEntry = "non-virtual thunk";
     }
-    $VEntry=~s/\A\(int \(\*\)\(...\)\)([^\(\d])/$1/i;
+    $VEntry=~s/\A\(int \(\*\)\(...\)\)\s*([a-z_])/$1/i;
     # support for old GCC versions
     $VEntry=~s/\A0u\Z/(int (*)(...))0/;
     $VEntry=~s/\A4294967268u\Z/(int (*)(...))-0x000000004/;
@@ -16567,25 +16993,33 @@
                     next;
                 }
                 
+                if(substr($CurHeaderName, 0, 1) eq "<")
+                { # <built-in>, <command-line>, etc.
+                    $CurHeaderName = "";
+                    $CurHeader = "";
+                }
+                
                 if($ExtraInfo)
                 {
-                    if(substr($CurHeaderName, 0, 1) ne "<")
-                    { # skip <built-in>, <command-line>, etc.
+                    if($CurHeaderName) {
                         $PreprocessedHeaders{$Version}{$CurHeader} = 1;
                     }
                 }
             }
             if(not $ExtraDump)
             {
-                if(not $Include_Neighbors{$Version}{$CurHeaderName}
-                and not $Registered_Headers{$Version}{$CurHeader})
-                { # not a target
-                    next;
-                }
-                if(not is_target_header($CurHeaderName, 1)
-                and not is_target_header($CurHeaderName, 2))
-                { # user-defined header
-                    next;
+                if($CurHeaderName)
+                {
+                    if(not $Include_Neighbors{$Version}{$CurHeaderName}
+                    and not $Registered_Headers{$Version}{$CurHeader})
+                    { # not a target
+                        next;
+                    }
+                    if(not is_target_header($CurHeaderName, 1)
+                    and not is_target_header($CurHeaderName, 2))
+                    { # user-defined header
+                        next;
+                    }
                 }
             }
             
@@ -16596,7 +17030,9 @@
                 {
                     $Constants{$Version}{$Name}{"Access"} = "public";
                     $Constants{$Version}{$Name}{"Value"} = $Value;
-                    $Constants{$Version}{$Name}{"Header"} = $CurHeaderName;
+                    if($CurHeaderName) {
+                        $Constants{$Version}{$Name}{"Header"} = $CurHeaderName;
+                    }
                 }
             }
             elsif($Line=~/\A\#[ \t]*undef[ \t]+([_A-Z]+)[ \t]*/) {
@@ -16652,10 +17088,11 @@
     if(defined $Cache{"uncoverConstant"}{$LibVersion}{$Constant}) {
         return $Cache{"uncoverConstant"}{$LibVersion}{$Constant};
     }
-    my $Value = $Constants{$LibVersion}{$Constant}{"Value"};
-    if(defined $Value)
+    
+    if(defined $Constants{$LibVersion}{$Constant})
     {
-        if($Value=~/\A[A-Z0-9_]+\Z/ and $Value=~/[A-Z]/)
+        my $Value = $Constants{$LibVersion}{$Constant}{"Value"};
+        if(defined $Constants{$LibVersion}{$Value})
         {
             push(@RecurConstant, $Constant);
             my $Uncovered = uncoverConstant($LibVersion, $Value);
@@ -16664,13 +17101,51 @@
             }
             pop(@RecurConstant);
         }
+        
         # FIXME: uncover $Value using all the enum constants
-        # USECASE: change of define NC_LONG from NC_INT (enum value) to NC_INT (define)
+        # USE CASE: change of define NC_LONG from NC_INT (enum value) to NC_INT (define)
         return ($Cache{"uncoverConstant"}{$LibVersion}{$Constant} = $Value);
     }
     return ($Cache{"uncoverConstant"}{$LibVersion}{$Constant} = "");
 }
 
+sub simpleConstant($$)
+{
+    my ($LibVersion, $Value) = @_;
+    if($Value=~/\W/)
+    {
+        my $Value_Copy = $Value;
+        while($Value_Copy=~s/([a-z_]\w+)/\@/i)
+        {
+            my $Word = $1;
+            if($Value!~/$Word\s*\(/)
+            {
+                my $Val = uncoverConstant($LibVersion, $Word);
+                if($Val ne "")
+                {
+                    $Value=~s/\b$Word\b/$Val/g;
+                }
+            }
+        }
+    }
+    return $Value;
+}
+
+sub computeValue($)
+{
+    my $Value = $_[0];
+    
+    if($Value=~/\A\((-?[\d]+)\)\Z/) {
+        return $1;
+    }
+    
+    if($Value=~/\A[\d\-\+()]+\Z/) {
+        return eval($Value);
+    }
+    
+    return $Value;
+}
+
 my %IgnoreConstant = map {$_=>1} (
     "VERSION",
     "VERSIONCODE",
@@ -16726,6 +17201,10 @@
     
     if($Level eq "Binary")
     {
+        if($Name=~/_t\Z/)
+        { # __malloc_ptr_t
+            return 1;
+        }
         foreach (keys(%IgnoreConstant))
         {
             if($Name=~/(\A|_)$_(_|\Z)/)
@@ -16748,17 +17227,26 @@
         { # /lib64:/usr/lib64:/lib:/usr/lib:/usr/X11R6/lib/Xaw3d ...
             return 1;
         }
-        if($Value=~/\A\(*[a-z_]+(\s+|\|)/i)
-        { # static int gcry_pth_init ( void) { return ...
+        
+        if($Value=~/\A["'].*['"]/i)
+        { # string
+            return 0;
+        }
+        
+        if($Value=~/\A[({]*\s*[a-z_]+\w*(\s+|[\|,])/i)
+        { # static int gcry_pth_init
+          # extern ABC
           # (RE_BACKSLASH_ESCAPE_IN_LISTS | RE...
+          # { H5FD_MEM_SUPER, H5FD_MEM_SUPER, ...
             return 1;
         }
-        if($Value=~/\(/i and $Value!~/\A[\"\']/i)
+        if($Value=~/\w+\s*\(/i)
         { # foo(p)
             return 1;
         }
-        if($Value=~/\A[a-z]+\w*\Z/i)
+        if($Value=~/\A[a-z_]+\w*\Z/i)
         { # asn1_node_st
+          # __SMTH_P
             return 1;
         }
     }
@@ -16776,10 +17264,15 @@
             next;
         }
         
-        my $Header = $Constants{1}{$Constant}{"Header"};
-        if(not is_target_header($Header, 1)
-        and not is_target_header($Header, 2))
-        { # user-defined header
+        if(my $Header = $Constants{1}{$Constant}{"Header"})
+        {
+            if(not is_target_header($Header, 1)
+            and not is_target_header($Header, 2))
+            { # user-defined header
+                next;
+            }
+        }
+        else {
             next;
         }
         
@@ -16815,8 +17308,17 @@
         $New_Value_Pure=~s/\s+(\W)/$1/g;
         
         next if($New_Value_Pure eq "" or $Old_Value_Pure eq "");
+        
         if($New_Value_Pure ne $Old_Value_Pure)
         { # different values
+            if(simpleConstant(1, $Old_Value) eq simpleConstant(2, $New_Value))
+            { # complex values
+                next;
+            }
+            if(computeValue($Old_Value) eq computeValue($New_Value))
+            { # expressions
+                next;
+            }
             if(convert_integer($Old_Value) eq convert_integer($New_Value))
             { # 0x0001 and 0x1, 0x1 and 1 equal constants
                 next;
@@ -16845,10 +17347,15 @@
                 next;
             }
             
-            my $Header = $Constants{2}{$Constant}{"Header"};
-            if(not is_target_header($Header, 1)
-            and not is_target_header($Header, 2))
-            { # user-defined header
+            if(my $Header = $Constants{2}{$Constant}{"Header"})
+            {
+                if(not is_target_header($Header, 1)
+                and not is_target_header($Header, 2))
+                { # user-defined header
+                    next;
+                }
+            }
+            else {
                 next;
             }
             
@@ -16921,28 +17428,38 @@
             {
                 foreach my $Symbol (keys(%{$UndefinedSymbols{$LibVersion}{$LibName}}))
                 {
-                    if(not $Symbol_Library{$LibVersion}{$Symbol}
-                    and not $DepSymbol_Library{$LibVersion}{$Symbol})
-                    {
-                        foreach my $Path (find_SymbolLibs($LibVersion, $Symbol)) {
-                            $UndefinedLibs{$Path} = 1;
+                    if($Symbol_Library{$LibVersion}{$Symbol}
+                    or $DepSymbol_Library{$LibVersion}{$Symbol})
+                    { # exported by target library
+                        next;
+                    }
+                    if(index($Symbol, '@')!=-1)
+                    { # exported default symbol version (@@)
+                        $Symbol=~s/\@/\@\@/;
+                        if($Symbol_Library{$LibVersion}{$Symbol}
+                        or $DepSymbol_Library{$LibVersion}{$Symbol}) {
+                            next;
                         }
                     }
+                    foreach my $Path (find_SymbolLibs($LibVersion, $Symbol)) {
+                        $UndefinedLibs{$Path} = 1;
+                    }
                 }
             }
         }
         if($ExtraInfo)
         { # extra information for other tools
-            if(my @Paths = keys(%UndefinedLibs))
+            if(my @Paths = sort keys(%UndefinedLibs))
             {
                 my $LibString = "";
+                my %Dirs = ();
                 foreach (@Paths)
                 {
                     $KnownLibs{$_} = 1;
                     my ($Dir, $Name) = separate_path($_);
                     
                     if(not grep {$Dir eq $_} (@{$SystemPaths{"lib"}})) {
-                        $LibString .= " -L".esc($Dir);
+                        $Dirs{esc($Dir)} = 1;
                     }
                     
                     $Name = parse_libname($Name, "name", $OStarget);
@@ -16950,6 +17467,12 @@
                     
                     $LibString .= " -l$Name";
                 }
+                
+                foreach my $Dir (sort {$b cmp $a} keys(%Dirs))
+                {
+                    $LibString = " -L".esc($Dir).$LibString;
+                }
+                
                 writeFile($ExtraInfo."/libs-string", $LibString);
             }
         }
@@ -17430,8 +17953,17 @@
     my @Info = split(/\s+/, $_[0]);
     #  Num:   Value      Size Type   Bind   Vis       Ndx  Name
     #  3629:  000b09c0   32   FUNC   GLOBAL DEFAULT   13   _ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4
+    #  135:   00000000    0   FUNC   GLOBAL DEFAULT   UND  av_image_fill_pointers@LIBAVUTIL_52 (3)
     shift(@Info); # spaces
     shift(@Info); # num
+    
+    if($#Info==7)
+    { # UND SYMBOL (N)
+        if($Info[7]=~/\(\d+\)/) {
+            pop(@Info);
+        }
+    }
+    
     if($#Info!=6)
     { # other lines
         return ();
@@ -17532,8 +18064,10 @@
     
     my $Lib_Name = get_filename($Real_Path);
     
-    if($ExtraInfo) {
+    if($ExtraInfo)
+    {
         $KnownLibs{$Real_Path} = 1;
+        $KnownLibs{$Lib_Path} = 1; # links
     }
     
     if($IsNeededLib)
@@ -17787,8 +18321,8 @@
                 $Short=~s/\@.+//g;
                 if($Type eq "OBJECT")
                 { # global data
-                    $GlobalDataObject{$LibVersion}{$Symbol} = 1;
-                    $GlobalDataObject{$LibVersion}{$Short} = 1;
+                    $GlobalDataObject{$LibVersion}{$Symbol} = $Size;
+                    $GlobalDataObject{$LibVersion}{$Short} = $Size;
                 }
                 if($IsNeededLib)
                 {
@@ -17840,29 +18374,52 @@
     {
         if(not $IsNeededLib and $LIB_EXT eq "so")
         { # get symbol versions
+            my %Found = ();
+            
+            # by value
             foreach my $Symbol (keys(%{$Library_Symbol{$LibVersion}{$Lib_Name}}))
             {
                 next if(index($Symbol,"\@")==-1);
                 if(my $Value = $Interface_Value{$LibVersion}{$Symbol})
                 {
-                    my $Interface_SymName = "";
                     foreach my $Symbol_SameValue (keys(%{$Value_Interface{$LibVersion}{$Value}}))
                     {
                         if($Symbol_SameValue ne $Symbol
                         and index($Symbol_SameValue,"\@")==-1)
                         {
                             $SymVer{$LibVersion}{$Symbol_SameValue} = $Symbol;
-                            $Interface_SymName = $Symbol_SameValue;
+                            $Found{$Symbol} = 1;
                             last;
                         }
                     }
-                    if(not $Interface_SymName)
-                    {
-                        if($Symbol=~/\A([^\@\$\?]*)[\@\$]+([^\@\$]*)\Z/
-                        and not $SymVer{$LibVersion}{$1}) {
-                            $SymVer{$LibVersion}{$1} = $Symbol;
-                        }
-                    }
+                }
+            }
+            
+            # default
+            foreach my $Symbol (keys(%{$Library_Symbol{$LibVersion}{$Lib_Name}}))
+            {
+                next if(defined $Found{$Symbol});
+                next if(index($Symbol,"\@\@")==-1);
+                
+                if($Symbol=~/\A([^\@]*)\@\@/
+                and not $SymVer{$LibVersion}{$1})
+                {
+                    $SymVer{$LibVersion}{$1} = $Symbol;
+                    $Found{$Symbol} = 1;
+                }
+            }
+            
+            # non-default
+            foreach my $Symbol (keys(%{$Library_Symbol{$LibVersion}{$Lib_Name}}))
+            {
+                next if(defined $Found{$Symbol});
+                next if(index($Symbol,"\@")==-1);
+                
+                if($Symbol=~/\A([^\@]*)\@([^\@]*)/
+                and not $SymVer{$LibVersion}{$1})
+                {
+                    $SymVer{$LibVersion}{$1} = $Symbol;
+                    $Found{$Symbol} = 1;
                 }
             }
         }
@@ -17871,6 +18428,8 @@
     {
         foreach my $DyLib (sort keys(%NeededLib))
         {
+            $Library_Needed{$LibVersion}{$Lib_Name}{get_filename($DyLib)} = 1;
+            
             if(my $DepPath = get_LibPath($LibVersion, $DyLib))
             {
                 if(not $CheckedDyLib{$LibVersion}{get_filename($DepPath)}) {
@@ -17957,6 +18516,7 @@
         if(not -e $Dest) {
             exitStatus("Access_Error", "can't access \'$Dest\'");
         }
+        $Dest = get_abs_path($Dest);
         my @SoPaths_Dest = getSOPaths_Dest($Dest, $LibVersion);
         foreach (@SoPaths_Dest) {
             push(@Paths, $_);
@@ -18388,16 +18948,23 @@
         $DVersion = $ToolVersion;
     }
     $UsedDump{$LibVersion}{"V"} = $DVersion;
-    if(majorVersion($DVersion) ne majorVersion($ABI_DUMP_VERSION))
-    { # should be compatible with dumps of the same major version
+    
+    if($ABI->{"ABI_DUMP_VERSION"})
+    {
         if(cmpVersions($DVersion, $ABI_DUMP_VERSION)>0)
         { # Don't know how to parse future dump formats
             exitStatus("Dump_Version", "incompatible version \'$DVersion\' of specified ABI dump (newer than $ABI_DUMP_VERSION)");
         }
-        elsif(cmpVersions($DVersion, $TOOL_VERSION)>0 and not $ABI->{"ABI_DUMP_VERSION"})
+    }
+    else
+    { # support for old ABI dumps
+        if(cmpVersions($DVersion, $TOOL_VERSION)>0)
         { # Don't know how to parse future dump formats
             exitStatus("Dump_Version", "incompatible version \'$DVersion\' of specified ABI dump (newer than $TOOL_VERSION)");
         }
+    }
+    if(majorVersion($DVersion)<2)
+    { # support for old ABI dumps
         if($UseOldDumps)
         {
             if(cmpVersions($DVersion, $OLDEST_SUPPORTED_VERSION)<0) {
@@ -18406,13 +18973,24 @@
         }
         else
         {
-            my $Msg = "incompatible version \'$DVersion\' of specified ABI dump (allowed only ".majorVersion($ABI_DUMP_VERSION).".0<=V<=$ABI_DUMP_VERSION)";
+            my $Msg = "incompatible version \'$DVersion\' of specified ABI dump (allowed only 2.0<=V<=$ABI_DUMP_VERSION)";
             if(cmpVersions($DVersion, $OLDEST_SUPPORTED_VERSION)>=0) {
-                $Msg .= "\nUse -old-dumps option to use old-version dumps ($OLDEST_SUPPORTED_VERSION<=V<".majorVersion($ABI_DUMP_VERSION).".0)";
+                $Msg .= "\nUse -old-dumps option to use old-version dumps ($OLDEST_SUPPORTED_VERSION<=V<2.0)";
             }
             exitStatus("Dump_Version", $Msg);
         }
     }
+    
+    if(defined $ABI->{"ABI_DUMPER_VERSION"})
+    { # DWARF ABI Dump
+        $UseConv_Real{$LibVersion}{"P"} = 1;
+        $UseConv_Real{$LibVersion}{"R"} = 0; # not implemented yet
+        
+        $UsedDump{$LibVersion}{"DWARF"} = 1;
+        
+        $TargetComponent = "module";
+    }
+    
     if(not checkDump($LibVersion, "2.11"))
     { # old ABI dumps
         $UsedDump{$LibVersion}{"BinOnly"} = 1;
@@ -18425,6 +19003,7 @@
     { # default
         $UsedDump{$LibVersion}{"SrcBin"} = 1;
     }
+    
     if(defined $ABI->{"Mode"}
     and $ABI->{"Mode"} eq "Extended")
     { # --ext option
@@ -18495,10 +19074,10 @@
                 my $Bid = $Info{"BaseType"}{"Tid"};
                 my $BDid = $Info{"BaseType"}{"TDid"};
                 $BDid="" if(not defined $BDid);
-                if(defined $NewID{$BDid} and my $ID = $NewID{$BDid}{$Bid}) {
-                    $TypeInfo{$LibVersion}{$Tid}{"BaseType"}{"Tid"} = $ID;
-                }
                 delete($TypeInfo{$LibVersion}{$Tid}{"BaseType"}{"TDid"});
+                if(defined $NewID{$BDid} and my $ID = $NewID{$BDid}{$Bid}) {
+                    $TypeInfo{$LibVersion}{$Tid}{"BaseType"} = $ID;
+                }
             }
             delete($TypeInfo{$LibVersion}{$Tid}{"TDid"});
         }
@@ -18558,7 +19137,7 @@
         my ($CPath, $Type) = classifyPath($Path);
         $SkipHeaders{$LibVersion}{$Type}{$CPath} = $ABI->{"SkipHeaders"}{$Path};
     }
-    read_Headers_DumpInfo($ABI, $LibVersion);
+    read_Source_DumpInfo($ABI, $LibVersion);
     read_Libs_DumpInfo($ABI, $LibVersion);
     if(not checkDump($LibVersion, "2.10.1")
     or not $TargetHeaders{$LibVersion})
@@ -18566,8 +19145,18 @@
         foreach (keys(%{$Registered_Headers{$LibVersion}})) {
             $TargetHeaders{$LibVersion}{get_filename($_)}=1;
         }
+        foreach (keys(%{$Registered_Sources{$LibVersion}})) {
+            $TargetHeaders{$LibVersion}{get_filename($_)}=1;
+        }
     }
     $Constants{$LibVersion} = $ABI->{"Constants"};
+    if(defined $ABI->{"GccConstants"})
+    { # 3.0
+        foreach my $Name (keys(%{$ABI->{"GccConstants"}})) {
+            $Constants{$LibVersion}{$Name}{"Value"} = $ABI->{"GccConstants"}{$Name};
+        }
+    }
+    
     $NestedNameSpaces{$LibVersion} = $ABI->{"NameSpaces"};
     if(not $NestedNameSpaces{$LibVersion})
     { # support for old dumps
@@ -18589,7 +19178,7 @@
             $Symbol_Library{$LibVersion}{$Symbol} = $Lib_Name;
             if($Library_Symbol{$LibVersion}{$Lib_Name}{$Symbol}<=-1)
             { # data marked as -size in the dump
-                $GlobalDataObject{$LibVersion}{$Symbol}=1;
+                $GlobalDataObject{$LibVersion}{$Symbol} = -$Library_Symbol{$LibVersion}{$Lib_Name}{$Symbol};
             }
             if($COMMON_LANGUAGE{$LibVersion} ne "C++")
             {
@@ -18621,6 +19210,19 @@
     translateSymbols(keys(%{$Symbol_Library{$LibVersion}}), $LibVersion);
     translateSymbols(keys(%{$DepSymbol_Library{$LibVersion}}), $LibVersion);
     
+    if(not checkDump($LibVersion, "3.0"))
+    { # support for old ABI dumps
+        foreach my $TypeId (sort {int($a)<=>int($b)} keys(%{$TypeInfo{$LibVersion}}))
+        {
+            if(my $BaseType = $TypeInfo{$LibVersion}{$TypeId}{"BaseType"})
+            {
+                if(ref($BaseType) eq "HASH") {
+                    $TypeInfo{$LibVersion}{$TypeId}{"BaseType"} = $TypeInfo{$LibVersion}{$TypeId}{"BaseType"}{"Tid"};
+                }
+            }
+        }
+    }
+    
     if(not checkDump($LibVersion, "2.20"))
     { # support for old ABI dumps
         foreach my $TypeId (sort {int($a)<=>int($b)} keys(%{$TypeInfo{$LibVersion}}))
@@ -18632,7 +19234,7 @@
                 next;
             }
             
-            if(my $BaseId = $TypeInfo{$LibVersion}{$TypeId}{"BaseType"}{"Tid"})
+            if(my $BaseId = $TypeInfo{$LibVersion}{$TypeId}{"BaseType"})
             {
                 my $BType = lc($TypeInfo{$LibVersion}{$BaseId}{"Type"});
                 if($BType=~/Struct|Union|Enum/i)
@@ -18672,6 +19274,10 @@
         { # support for old ABI dumps
             $TypeInfo{$LibVersion}{$TypeId}{"Header"} = path_format($Header, $OSgroup);
         }
+        elsif(my $Source = $TypeInfo{$LibVersion}{$TypeId}{"Source"})
+        { # DWARF ABI Dumps
+            $TypeInfo{$LibVersion}{$TypeId}{"Header"} = $Source;
+        }
         if(not defined $TypeInfo{$LibVersion}{$TypeId}{"Tid"}) {
             $TypeInfo{$LibVersion}{$TypeId}{"Tid"} = $TypeId;
         }
@@ -18697,10 +19303,13 @@
                 }
             }
         }
-        if($TInfo{"Type"} eq "Typedef" and not $TInfo{"Artificial"}
-        and defined $TInfo{"BaseType"})
+        if($TInfo{"BaseType"} eq $TypeId)
+        { # fix ABI dump
+            delete($TypeInfo{$LibVersion}{$TypeId}{"BaseType"});
+        }
+        if($TInfo{"Type"} eq "Typedef" and not $TInfo{"Artificial"})
         {
-            if(my $BTid = $TInfo{"BaseType"}{"Tid"})
+            if(my $BTid = $TInfo{"BaseType"})
             {
                 my $BName = $TypeInfo{$LibVersion}{$BTid}{"Name"};
                 if(not $BName)
@@ -18719,7 +19328,7 @@
         }
         if(not $TName_Tid{$LibVersion}{$TInfo{"Name"}})
         { # classes: class (id1), typedef (artificial, id2 > id1)
-            $TName_Tid{$LibVersion}{$TInfo{"Name"}} = $TypeId;
+            $TName_Tid{$LibVersion}{formatName($TInfo{"Name"}, "T")} = $TypeId;
         }
     }
     
@@ -18754,6 +19363,10 @@
         { # support for old ABI dumps
             $SymbolInfo{$LibVersion}{$InfoId}{"Header"} = path_format($Header, $OSgroup);
         }
+        elsif(my $Source = $SymbolInfo{$LibVersion}{$InfoId}{"Source"})
+        { # DWARF ABI Dumps
+            $SymbolInfo{$LibVersion}{$InfoId}{"Header"} = $Source;
+        }
     }
     
     $Descriptor{$LibVersion}{"Dump"} = 1;
@@ -18817,9 +19430,10 @@
     }
 }
 
-sub read_Headers_DumpInfo($$)
+sub read_Source_DumpInfo($$)
 {
     my ($ABI, $LibVersion) = @_;
+    
     if(keys(%{$ABI->{"Headers"}})
     and not $DumpAPI) {
         $Descriptor{$LibVersion}{"Headers"} = "OK";
@@ -18834,6 +19448,16 @@
         $Registered_Headers{$LibVersion}{$Identity}{"Identity"} = $Identity;
         $Registered_Headers{$LibVersion}{$Identity}{"Pos"} = $ABI->{"Headers"}{$Identity};
     }
+    
+    if(keys(%{$ABI->{"Sources"}})
+    and not $DumpAPI) {
+        $Descriptor{$LibVersion}{"Sources"} = "OK";
+    }
+    foreach my $Name (sort {$ABI->{"Sources"}{$a}<=>$ABI->{"Sources"}{$b}} keys(%{$ABI->{"Sources"}}))
+    { # headers info is stored in the old dumps in the different way
+        $Registered_Sources{$LibVersion}{$Name}{"Identity"} = $Name;
+        $Registered_Sources{$LibVersion}{$Name}{"Pos"} = $ABI->{"Headers"}{$Name};
+    }
 }
 
 sub find_libs($$$)
@@ -19378,12 +20002,15 @@
 sub parse_libname_I($$$)
 {
     my ($Name, $Type, $Target) = @_;
+    
     if($Target eq "symbian") {
         return parse_libname_symbian($Name, $Type);
     }
     elsif($Target eq "windows") {
         return parse_libname_windows($Name, $Type);
     }
+    
+    # unix
     my $Ext = getLIB_EXT($Target);
     if($Name=~/((((lib|).+?)([\-\_][\d\-\.\_]+.*?|))\.$Ext)(\.(.+)|)\Z/)
     { # libSDL-1.2.so.0.7.1
@@ -20014,6 +20641,12 @@
             readDescriptor(1, createDescriptor(1, $Part));
         }
     }
+    
+    if(not $Descriptor{1}{"Version"})
+    { # set to default: X
+        $Descriptor{1}{"Version"} = "X";
+    }
+    
     initLogging(1);
     detect_default_paths("inc|lib|bin|gcc"); # complete analysis
     
@@ -20080,8 +20713,7 @@
         }
     }
     my %HeadersInfo = ();
-    foreach my $HPath (keys(%{$Registered_Headers{1}}))
-    { # headers info stored without paths in the dump
+    foreach my $HPath (keys(%{$Registered_Headers{1}})) {
         $HeadersInfo{$Registered_Headers{1}{$HPath}{"Identity"}} = $Registered_Headers{1}{$HPath}{"Pos"};
     }
     if($ExtraDump)
@@ -20107,6 +20739,17 @@
             }
         }
     }
+    
+    my %GccConstants = (); # built-in GCC constants
+    foreach my $Name (keys(%{$Constants{1}}))
+    {
+        if(not defined $Constants{1}{$Name}{"Header"})
+        {
+            $GccConstants{$Name} = $Constants{1}{$Name}{"Value"};
+            delete($Constants{1}{$Name});
+        }
+    }
+    
     printMsg("INFO", "creating library ABI dump ...");
     my %ABI = (
         "TypeInfo" => $TypeInfo{1},
@@ -20123,6 +20766,7 @@
         "SkipHeaders" => $SkipHeadersList{1},
         "Headers" => \%HeadersInfo,
         "Constants" => $Constants{1},
+        "GccConstants" => \%GccConstants,
         "NameSpaces" => $NestedNameSpaces{1},
         "Target" => $OStarget,
         "Arch" => getArch(1),
@@ -20146,9 +20790,10 @@
         $ABI{"BinOnly"} = 1;
     }
     if($ExtraDump)
-    { # --extra-info
-        $ABI{"UndefinedSymbols"} = $UndefinedSymbols{1};
+    { # --extra-dump
         $ABI{"Extra"} = 1;
+        $ABI{"UndefinedSymbols"} = $UndefinedSymbols{1};
+        $ABI{"Needed"} = $Library_Needed{1};
     }
     
     my $ABI_DUMP = "";
@@ -20249,7 +20894,7 @@
                 { # support for old dumps
                     $ABIdump->{"SymbolInfo"} = $ABIdump->{"FuncDescr"};
                 }
-                read_Headers_DumpInfo($ABIdump, 1);
+                read_Source_DumpInfo($ABIdump, 1);
                 read_Libs_DumpInfo($ABIdump, 1);
                 read_Machine_DumpInfo($ABIdump, 1);
                 read_Machine_DumpInfo($ABIdump, 2);
@@ -20326,7 +20971,7 @@
 
 sub isDump($)
 {
-    if(get_filename($_[0])=~/\A(.+)\.(abi|abidump|dump)(\.tar\.gz|\.zip|\.xml|)\Z/) {
+    if(get_filename($_[0])=~/\A(.+)\.(abi|abidump|dump)(\.tar\.gz|\.zip|\.xml|)(\.\w+|)\Z/) {
         return $1;
     }
     return 0;
@@ -20334,7 +20979,7 @@
 
 sub isDump_U($)
 {
-    if(get_filename($_[0])=~/\A(.+)\.(abi|abidump|dump)(\.xml|)\Z/) {
+    if(get_filename($_[0])=~/\A(.+)\.(abi|abidump|dump)(\.xml|)(\.\w+|)\Z/) {
         return $1;
     }
     return 0;
@@ -20391,6 +21036,17 @@
             readDescriptor(2, createDescriptor(2, $Part));
         }
     }
+    
+    if(not $Descriptor{1}{"Version"})
+    { # set to default: X
+        $Descriptor{1}{"Version"} = "X";
+    }
+    
+    if(not $Descriptor{2}{"Version"})
+    { # set to default: Y
+        $Descriptor{2}{"Version"} = "Y";
+    }
+    
     initLogging(1);
     initLogging(2);
     # check consistency
@@ -21108,6 +21764,15 @@
             $SymbolsList{$Interface} = 1;
         }
     }
+    if($SkipSymbolsListPath)
+    {
+        if(not -f $SkipSymbolsListPath) {
+            exitStatus("Access_Error", "can't access file \'$SkipSymbolsListPath\'");
+        }
+        foreach my $Interface (split(/\s*\n\s*/, readFile($SkipSymbolsListPath))) {
+            $SkipSymbolsList{$Interface} = 1;
+        }
+    }
     if($SkipHeadersPath)
     {
         if(not -f $SkipHeadersPath) {