ABI Compliance Checker 1.98.2
diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl
index 48151f2..15637e2 100755
--- a/abi-compliance-checker.pl
+++ b/abi-compliance-checker.pl
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 ###########################################################################
-# ABI Compliance Checker (ACC) 1.98.1
+# ABI Compliance Checker (ACC) 1.98.2
 # A tool for checking backward compatibility of a C/C++ library API
 #
 # Copyright (C) 2009-2010 The Linux Foundation
@@ -55,8 +55,8 @@
 use Data::Dumper;
 use Config;
 
-my $TOOL_VERSION = "1.98.1";
-my $ABI_DUMP_VERSION = "2.17";
+my $TOOL_VERSION = "1.98.2";
+my $ABI_DUMP_VERSION = "2.18";
 my $OLDEST_SUPPORTED_VERSION = "1.18";
 my $XML_REPORT_VERSION = "1.0";
 my $XML_ABI_DUMP_VERSION = "1.1";
@@ -1397,6 +1397,9 @@
 my %MinGWMode = (
   "1"=>0,
   "2"=>0 );
+my %Cpp0xMode = (
+  "1"=>0,
+  "2"=>0 );
 
 # Shared Objects
 my %DyLib_DefaultPath;
@@ -1516,14 +1519,20 @@
     exitStatus("Module_Error", "can't find modules");
 }
 
+my %LoadedModules = ();
+
 sub loadModule($)
 {
     my $Name = $_[0];
+    if(defined $LoadedModules{$Name}) {
+        return;
+    }
     my $Path = $MODULES_DIR."/Internals/$Name.pm";
     if(not -f $Path) {
         exitStatus("Module_Error", "can't access \'$Path\'");
     }
     require $Path;
+    $LoadedModules{$Name} = 1;
 }
 
 sub showPos($)
@@ -1882,7 +1891,6 @@
     foreach my $Path (split(/\s*\n\s*/, parseTag(\$Content, "skip_including")))
     {
         # skip direct including of some headers
-        $SkipHeadersList{$LibVersion}{$Path} = 2;
         my ($CPath, $Type) = classifyPath($Path);
         $SkipHeaders{$LibVersion}{$Type}{$CPath} = 2;
     }
@@ -1950,19 +1958,67 @@
     }
 }
 
-sub parseTag($$)
+sub parseTag(@)
 {
-    my ($CodeRef, $Tag) = @_;
-    return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
-    if(${$CodeRef}=~s/\<\Q$Tag\E\>((.|\n)+?)\<\/\Q$Tag\E\>//)
+    my $CodeRef = shift(@_);
+    my $Tag = shift(@_);
+    if(not $Tag or not $CodeRef) {
+        return undef;
+    }
+    my $Sp = 0;
+    if(@_) {
+        $Sp = shift(@_);
+    }
+    my $Start = index(${$CodeRef}, "<$Tag>");
+    if($Start!=-1)
     {
-        my $Content = $1;
-        $Content=~s/(\A\s+|\s+\Z)//g;
+        my $End = index(${$CodeRef}, "</$Tag>");
+        if($End!=-1)
+        {
+            my $TS = length($Tag)+3;
+            my $Content = substr(${$CodeRef}, $Start, $End-$Start+$TS, "");
+            substr($Content, 0, $TS-1, ""); # cut start tag
+            substr($Content, -$TS, $TS, ""); # cut end tag
+            if(not $Sp)
+            {
+                $Content=~s/\A\s+//g;
+                $Content=~s/\s+\Z//g;
+            }
+            if(substr($Content, 0, 1) ne "<") {
+                $Content = xmlSpecChars_R($Content);
+            }
+            return $Content;
+        }
+    }
+    return undef;
+}
+
+sub parseTag_E($$$)
+{
+    my ($CodeRef, $Tag, $Info) = @_;
+    if(not $Tag or not $CodeRef
+    or not $Info) {
+        return undef;
+    }
+    if(${$CodeRef}=~s/\<\Q$Tag\E(\s+([^<>]+)|)\>((.|\n)*?)\<\/\Q$Tag\E\>//)
+    {
+        my ($Ext, $Content) = ($2, $3);
+        $Content=~s/\A\s+//g;
+        $Content=~s/\s+\Z//g;
+        if($Ext)
+        {
+            while($Ext=~s/(\w+)\=\"([^\"]*)\"//)
+            {
+                my ($K, $V) = ($1, $2);
+                $Info->{$K} = xmlSpecChars_R($V);
+            }
+        }
+        if(substr($Content, 0, 1) ne "<") {
+            $Content = xmlSpecChars_R($Content);
+        }
         return $Content;
     }
-    else {
-        return "";
-    }
+    return undef;
 }
 
 sub addTag(@)
@@ -2036,8 +2092,8 @@
     setTemplateParams_All();
     getTypeInfo_All();
     simplifyNames();
-    getSymbolInfo_All();
     getVarInfo_All();
+    getSymbolInfo_All();
     
     # clean memory
     %LibInfo = ();
@@ -2257,12 +2313,12 @@
     }
     
     # add "..." type
-    $TypeInfo{$Version}{-1} = {
+    $TypeInfo{$Version}{"-1"} = {
         "Name" => "...",
         "Type" => "Intrinsic",
-        "Tid" => -1
+        "Tid" => "-1"
     };
-    $TName_Tid{$Version}{"..."} = -1;
+    $TName_Tid{$Version}{"..."} = "-1";
     
     if(not check_gcc($GCC_PATH, "4.5"))
     { # support for GCC < 4.5
@@ -2816,8 +2872,15 @@
     if($_[0] and my $Info = $LibInfo{$Version}{"info"}{$_[0]})
     {
         if($Info=~/strg[ ]*: (.+) lngt:[ ]*(\d+)/)
-        { # string length is N-1 because of the null terminator
-            return substr($1, 0, $2-1);
+        { 
+            if($LibInfo{$Version}{"info_type"}{$_[0]} eq "string_cst")
+            { # string length is N-1 because of the null terminator
+                return substr($1, 0, $2-1);
+            }
+            else
+            { # identifier_node
+                return substr($1, 0, $2);
+            }
         }
     }
     return "";
@@ -2835,8 +2898,10 @@
     my %TypeAttr = ("Size"=>$WORD_SIZE{$Version}, "Type"=>$Type, "Tid"=>$TypeId);
     if($Type eq "MethodPtr")
     { # size of "method pointer" may be greater than WORD size
-        if(my $Size = getSize($TypeId)) {
-            $TypeAttr{"Size"} = $Size/$BYTE_SIZE;
+        if(my $Size = getSize($TypeId))
+        {
+            $Size/=$BYTE_SIZE;
+            $TypeAttr{"Size"} = "$Size";
         }
     }
     # Return
@@ -2885,7 +2950,7 @@
         if($MemInfo=~/prms[ ]*:[ ]*@(\d+) /)
         {
             my $PTypeInfoId = $1;
-            my $Pos = 0;
+            my ($Pos, $PPos) = (0, 0);
             while($PTypeInfoId)
             {
                 my $PTypeInfo = $LibInfo{$Version}{"info"}{$PTypeInfoId};
@@ -2902,7 +2967,7 @@
                     }
                     if($Pos!=0 or $Type ne "MethodPtr")
                     {
-                        $TypeAttr{"Param"}{$Pos}{"type"} = $PTypeId;
+                        $TypeAttr{"Param"}{$PPos++}{"type"} = $PTypeId;
                         push(@ParamTypeName, $ParamAttr{"Name"});
                     }
                     if($PTypeInfoId = getNextElem($PTypeInfoId)) {
@@ -3209,7 +3274,7 @@
 sub getVarInfo($)
 {
     my $InfoId = $_[0];
-    if(my $NSid = getNameSpaceId($InfoId))
+    if(my $NSid = getTreeAttr_Scpe($InfoId))
     {
         my $NSInfoType = $LibInfo{$Version}{"info_type"}{$NSid};
         if($NSInfoType and $NSInfoType eq "function_decl") {
@@ -3369,7 +3434,7 @@
     if(isAnon($TypeAttr{"Name"}))
     {
         my $NameSpaceId = $TypeId;
-        while(my $NSId = getNameSpaceId(getTypeDeclId($NameSpaceId)))
+        while(my $NSId = getTreeAttr_Scpe(getTypeDeclId($NameSpaceId)))
         { # searching for a first not anon scope
             if($NSId eq $NameSpaceId) {
                 last;
@@ -3387,7 +3452,7 @@
     }
     else
     {
-        if(my $NameSpaceId = getNameSpaceId($TypeInfoId))
+        if(my $NameSpaceId = getTreeAttr_Scpe($TypeInfoId))
         {
             if($NameSpaceId ne $TypeId) {
                 $TypeAttr{"NameSpace"} = getNameSpace($TypeInfoId);
@@ -3464,8 +3529,10 @@
             }
         }
     }
-    if(my $Size = getSize($TypeId)) {
-        $TypeAttr{"Size"} = $Size/$BYTE_SIZE;
+    if(my $Size = getSize($TypeId))
+    {
+        $Size = $Size/$BYTE_SIZE;
+        $TypeAttr{"Size"} = "$Size";
     }
     if($TypeAttr{"Type"} eq "Struct"
     and detect_lang($TypeId))
@@ -3556,12 +3623,13 @@
             {
                 $TypeAttr->{"Base"}{$ClassId}{"access"} = "private";
             }
-            $TypeAttr->{"Base"}{$ClassId}{"pos"} = $Pos++;
+            $TypeAttr->{"Base"}{$ClassId}{"pos"} = "$Pos";
             if($BaseInfo=~/virt/)
             { # virtual base
                 $TypeAttr->{"Base"}{$ClassId}{"virtual"} = 1;
             }
             $Class_SubClasses{$Version}{$ClassId}{$TypeId}=1;
+            $Pos+=1;
         }
     }
     return 0;
@@ -4281,6 +4349,12 @@
             elsif($InfoType eq "string_cst") {
                 return getNodeStrCst($InfoId);
             }
+            elsif($InfoType eq "var_decl")
+            {
+                if(my $Name = getNodeStrCst(getTreeAttr_Mngl($InfoId))) {
+                    return $Name;
+                }
+            }
         }
     }
     return undef;
@@ -4673,15 +4747,15 @@
                 $TypeMembInfoId = getNextElem($TypeMembInfoId);
                 next;
             }
-            my $StructMembName = getStructMembName($TypeMembInfoId);
-            if($StructMembName=~/_vptr\./)
+            my $StructMembName = getTreeStr(getTreeAttr_Name($TypeMembInfoId));
+            if(index($StructMembName, "_vptr.")!=-1)
             { # virtual tables
                 $TypeMembInfoId = getNextElem($TypeMembInfoId);
                 next;
             }
             if(not $StructMembName)
             { # unnamed fields
-                if($TypeAttr->{"Name"}!~/_type_info_pseudo/)
+                if(index($TypeAttr->{"Name"}, "_type_info_pseudo")==-1)
                 {
                     my $UnnamedTid = getTreeAttr_Type($TypeMembInfoId);
                     my $UnnamedTName = getNameByInfo(getTypeDeclId($UnnamedTid));
@@ -4800,7 +4874,7 @@
         $Pos += 1;
     }
     if(setFuncArgs($InfoId, $Vtt_Pos)) {
-        $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"type"} = -1;
+        $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"type"} = "-1";
     }
     return 0;
 }
@@ -4845,8 +4919,12 @@
         }
         if(my $PurpId = getTreeAttr_Purp($ParamListElemId))
         { # default arguments
-            if(my $PurpType = $LibInfo{$Version}{"info_type"}{$PurpId}) {
-                $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"default"} = getInitVal($PurpId, $ParamTypeId);
+            if(my $PurpType = $LibInfo{$Version}{"info_type"}{$PurpId})
+            {
+                my $Val = getInitVal($PurpId, $ParamTypeId);
+                if(defined $Val) {
+                    $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"default"} = $Val;
+                }
             }
         }
         $ParamListElemId = getNextElem($ParamListElemId);
@@ -5191,28 +5269,6 @@
     return "";
 }
 
-sub getNameSpaceId($)
-{
-    if($_[0] and my $Info = $LibInfo{$Version}{"info"}{$_[0]})
-    {
-        if($Info=~/scpe[ ]*:[ ]*\@(\d+)/) {
-            return $1;
-        }
-    }
-    return "";
-}
-
-sub getStructMembName($)
-{
-    if($_[0] and my $Info = $LibInfo{$Version}{"info"}{$_[0]})
-    {
-        if($Info=~/name[ ]*:[ ]*\@(\d+)/) {
-            return getTreeStr($1);
-        }
-    }
-    return "";
-}
-
 sub getEnumMembVal($)
 {
     if($_[0] and my $Info = $LibInfo{$Version}{"info"}{$_[0]})
@@ -7025,7 +7081,8 @@
     "itimerspec",
     "_pthread_cleanup_buffer",
     "fd_set",
-    "siginfo"
+    "siginfo",
+    "mallinfo"
 );
 
 sub getCompileCmd($$$)
@@ -7055,7 +7112,8 @@
     }
     # allow extra qualifications
     # and other nonconformant code
-    $GccCall .= " -fpermissive -w";
+    $GccCall .= " -fpermissive";
+    $GccCall .= " -w";
     if($NoStdInc)
     {
         $GccCall .= " -nostdinc";
@@ -7073,11 +7131,9 @@
     return $GccCall;
 }
 
-sub getDump()
+sub detectPreamble($$)
 {
-    if(not $GCC_PATH) {
-        exitStatus("Error", "internal error - GCC path is not set");
-    }
+    my ($Content, $LibVersion) = @_;
     my %HeaderElems = (
         # Types
         "stdio.h" => ["FILE", "va_list"],
@@ -7103,6 +7159,35 @@
             $AutoPreamble{$Elem}=$_;
         }
     }
+    my %Types = ();
+    while($Content=~s/error\:\s*(field\s*|)\W+(.+?)\W+//)
+    { # error: 'FILE' has not been declared
+        $Types{$2}=1;
+    }
+    if(keys(%Types))
+    {
+        my %AddHeaders = ();
+        foreach my $Type (keys(%Types))
+        {
+            if(my $Header = $AutoPreamble{$Type})
+            {
+                if(my $Path = identifyHeader($Header, $LibVersion)) {
+                    $AddHeaders{path_format($Path, $OSgroup)}=$Type;
+                }
+            }
+        }
+        if(keys(%AddHeaders)) {
+            return %AddHeaders;
+        }
+    }
+    return ();
+}
+
+sub getDump()
+{
+    if(not $GCC_PATH) {
+        exitStatus("Error", "internal error - GCC path is not set");
+    }
     my $TmpHeaderPath = $TMP_DIR."/dump".$Version.".h";
     my $MHeaderPath = $TmpHeaderPath;
     open(TMP_HEADER, ">", $TmpHeaderPath) || die ("can't open file \'$TmpHeaderPath\': $!\n");
@@ -7347,61 +7432,61 @@
     system($SyntaxTreeCmd." >\"$TMP_DIR/tu_errors\" 2>&1");
     if($?)
     { # failed to compile, but the TU dump still can be created
-        my $Errors = readFile($TMP_DIR."/tu_errors");
-        if($Errors=~/c99_/)
-        { # disable c99 mode
-            $C99Mode{$Version}=-1;
-            printMsg("INFO", "Disabling C99 compatibility mode");
-            resetLogging($Version);
-            $TMP_DIR = tempdir(CLEANUP=>1);
-            return getDump();
-        }
-        elsif($AutoPreambleMode{$Version}!=-1
-        and my $TErrors = $Errors)
-        {
-            my %Types = ();
-            while($TErrors=~s/error\:\s*(field\s*|)\W+(.+?)\W+//)
-            { # error: 'FILE' has not been declared
-                $Types{$2}=1;
-            }
-            my %AddHeaders = ();
-            foreach my $Type (keys(%Types))
-            {
-                if(my $Header = $AutoPreamble{$Type}) {
-                    $AddHeaders{path_format($Header, $OSgroup)}=$Type;
-                }
-            }
-            if(my @Headers = sort {$b cmp $a} keys(%AddHeaders))
-            { # sys/types.h should be the first
-                foreach my $Num (0 .. $#Headers)
-                {
-                    my $Name = $Headers[$Num];
-                    if(my $Path = identifyHeader($Name, $Version))
-                    { # add automatic preamble headers
-                        if(defined $Include_Preamble{$Version}{$Path})
-                        { # already added
-                            next;
-                        }
-                        $Include_Preamble{$Version}{$Path}{"Position"} = keys(%{$Include_Preamble{$Version}});
-                        my $Type = $AddHeaders{$Name};
-                        printMsg("INFO", "Add \'$Name\' preamble header for \'$Type\'");
-                    }
-                }
-                $AutoPreambleMode{$Version}=-1;
+        if(my $Errors = readFile($TMP_DIR."/tu_errors"))
+        { # try to recompile
+          # FIXME: handle other errors and try to recompile
+            if($C99Mode{$Version}==1
+            and $Errors=~/c99_/)
+            { # disable c99 mode and try again
+                $C99Mode{$Version}=-1;
+                printMsg("INFO", "Disabling C99 compatibility mode");
                 resetLogging($Version);
                 $TMP_DIR = tempdir(CLEANUP=>1);
                 return getDump();
             }
+            elsif($AutoPreambleMode{$Version}!=-1
+            and my %AddHeaders = detectPreamble($Errors, $Version))
+            { # add auto preamble headers and try again
+                $AutoPreambleMode{$Version}=-1;
+                my @Headers = sort {$b cmp $a} keys(%AddHeaders); # sys/types.h should be the first
+                foreach my $Num (0 .. $#Headers)
+                {
+                    my $Path = $Headers[$Num];
+                    if(defined $Include_Preamble{$Version}{$Path})
+                    { # already added
+                        next;
+                    }
+                    $Include_Preamble{$Version}{$Path}{"Position"} = keys(%{$Include_Preamble{$Version}});
+                    my $Type = $AddHeaders{$Path};
+                    printMsg("INFO", "Add \'".get_filename($Path)."\' preamble header for \'$Type\'");
+                }
+                resetLogging($Version);
+                $TMP_DIR = tempdir(CLEANUP=>1);
+                return getDump();
+            }
+            elsif($Cpp0xMode{$Version}!=-1
+            and ($Errors=~/\Q-std=c++0x\E/
+            or $Errors=~/is not a class or namespace/))
+            { # c++0x: enum class
+                $Cpp0xMode{$Version}=-1;
+                printMsg("INFO", "Enabling c++0x mode");
+                resetLogging($Version);
+                $TMP_DIR = tempdir(CLEANUP=>1);
+                $CompilerOptions{$Version} .= " -std=c++0x";
+                return getDump();
+            }
+            elsif($MinGWMode{$Version}==1)
+            { # disable MinGW mode and try again
+                $MinGWMode{$Version}=-1;
+                resetLogging($Version);
+                $TMP_DIR = tempdir(CLEANUP=>1);
+                return getDump();
+            }
+            writeLog($Version, $Errors);
         }
-        elsif($MinGWMode{$Version}!=-1)
-        {
-            $MinGWMode{$Version}=-1;
-            resetLogging($Version);
-            $TMP_DIR = tempdir(CLEANUP=>1);
-            return getDump();
+        else {
+            writeLog($Version, "$!: $?\n");
         }
-        # FIXME: handle other errors and try to recompile
-        writeLog($Version, $Errors);
         printMsg("ERROR", "some errors occurred when compiling headers");
         printErrorLog($Version);
         $COMPILE_ERRORS = $ERROR_CODE{"Compile_Error"};
@@ -7848,10 +7933,11 @@
             my %Type = get_PureType($TypeId, $LibVersion);
             if($Type{"Type"} eq "Array")
             {
-                if($Type{"Size"})
+                if(my $Size = $Type{"Size"})
                 { # array[N]
                     my %Base = get_OneStep_BaseType($Type{"Tid"}, $LibVersion);
-                    $TypeInfo{$LibVersion}{$TypeId}{"Size"} = $Type{"Size"}*$Base{"Size"};
+                    $Size *= $Base{"Size"};
+                    $TypeInfo{$LibVersion}{$TypeId}{"Size"} = "$Size";
                 }
                 else
                 { # array[] is a pointer
@@ -7960,12 +8046,6 @@
         my $ClassID = $SymbolInfo{$LibVersion}{$InfoId}{"Class"};
         my $Return = $SymbolInfo{$LibVersion}{$InfoId}{"Return"};
         
-        if(not $MnglName)
-        { # ABI dumps have no mangled names for C-functions
-            $MnglName = $ShortName;
-            $SymbolInfo{$LibVersion}{$InfoId}{"MnglName"} = $MnglName;
-        }
-        
         my $SRemangle = 0;
         if(not checkDump(1, "2.12")
         or not checkDump(2, "2.12"))
@@ -8324,7 +8404,8 @@
         }
         elsif($Level eq "Source")
         { # checked
-            if($SInfo->{"PureVirt"} or $SInfo->{"Data"} or $SInfo->{"InLine"})
+            if($SInfo->{"PureVirt"} or $SInfo->{"Data"} or $SInfo->{"InLine"}
+            or isInLineInst($Symbol, $SInfo, $LibVersion))
             { # skip LOCAL symbols
                 if($Target) {
                     return 1;
@@ -8366,15 +8447,22 @@
         if(not keys(%{$SymbolInfo{$LibVersion}{$InfoId}{"Param"}})) {
             delete($SymbolInfo{$LibVersion}{$InfoId}{"Param"});
         }
+        if(not keys(%{$SymbolInfo{$LibVersion}{$InfoId}{"TParam"}})) {
+            delete($SymbolInfo{$LibVersion}{$InfoId}{"TParam"});
+        }
     }
     foreach my $Tid (keys(%{$TypeInfo{$LibVersion}}))
     {
+        delete($TypeInfo{$LibVersion}{$Tid}{"Tid"});
         foreach my $Attr ("Header", "Line", "Size", "NameSpace")
         {
             if(not $TypeInfo{$LibVersion}{$Tid}{$Attr}) {
                 delete($TypeInfo{$LibVersion}{$Tid}{$Attr});
             }
         }
+        if(not keys(%{$TypeInfo{$LibVersion}{$Tid}{"TParam"}})) {
+            delete($TypeInfo{$LibVersion}{$Tid}{"TParam"});
+        }
     }
 }
 
@@ -10863,9 +10951,13 @@
     return ($Symbol=~/\A(_ZGV|_ZTI|_ZTS|_ZTT|_ZTV|_ZTC|_ZThn|_ZTv0_n)/);
 }
 
-sub isTemplateInstance($$)
+sub isInLineInst($$$) {
+    return (isTemplateInstance(@_) and not isTemplateSpec(@_));
+}
+
+sub isTemplateInstance($$$)
 {
-    my ($Symbol, $LibVersion) = @_;
+    my ($Symbol, $SInfo, $LibVersion) = @_;
     if($CheckObjectsOnly)
     {
         if($Symbol!~/\A(_Z|\?)/) {
@@ -10878,7 +10970,8 @@
             }
             if(my $ShortName = substr($Signature, 0, find_center($Signature, "(")))
             {
-                if($ShortName=~/<.+>/) {
+                if(index($ShortName,"<")!=-1
+                and index($ShortName,">")!=-1) {
                     return 1;
                 }
             }
@@ -10886,7 +10979,7 @@
     }
     else
     {
-        if(my $ClassId = $CompleteSignature{$LibVersion}{$Symbol}{"Class"})
+        if(my $ClassId = $SInfo->{"Class"})
         {
             if(my $ClassName = $TypeInfo{$LibVersion}{$ClassId}{"Name"})
             {
@@ -10895,9 +10988,10 @@
                 }
             }
         }
-        if(my $ShortName = $CompleteSignature{$LibVersion}{$Symbol}{"ShortName"})
+        if(my $ShortName = $SInfo->{"ShortName"})
         {
-            if($ShortName=~/<.+>/) {
+            if(index($ShortName,"<")!=-1
+            and index($ShortName,">")!=-1) {
                 return 1;
             }
         }
@@ -10905,16 +10999,16 @@
     return 0;
 }
 
-sub isTemplateSpec($$)
+sub isTemplateSpec($$$)
 {
-    my ($Symbol, $LibVersion) = @_;
-    if(my $ClassId = $CompleteSignature{$LibVersion}{$Symbol}{"Class"})
+    my ($Symbol, $SInfo, $LibVersion) = @_;
+    if(my $ClassId = $SInfo->{"Class"})
     {
         if($TypeInfo{$LibVersion}{$ClassId}{"Spec"})
         { # class specialization
             return 1;
         }
-        elsif($CompleteSignature{$LibVersion}{$Symbol}{"Spec"})
+        elsif($SInfo->{"Spec"})
         { # method specialization
             return 1;
         }
@@ -10994,14 +11088,14 @@
         {
             if($CheckObjectsOnly)
             {
-                if(isTemplateInstance($Symbol, $LibVersion)) {
+                if(isTemplateInstance($Symbol, $CompleteSignature{$LibVersion}{$Symbol}, $LibVersion)) {
                     return 0;
                 }
             }
             else
             {
                 if($CompleteSignature{$LibVersion}{$Symbol}{"InLine"}
-                or (isTemplateInstance($Symbol, $LibVersion) and not isTemplateSpec($Symbol, $LibVersion)))
+                or isInLineInst($Symbol, $CompleteSignature{$LibVersion}{$Symbol}, $LibVersion))
                 {
                     if($ClassId and $CompleteSignature{$LibVersion}{$Symbol}{"Virt"})
                     { # inline virtual methods
@@ -12364,7 +12458,13 @@
     my ($Value, $TypeId, $LibVersion) = @_;
     my %PureType = get_PureType($TypeId, $LibVersion);
     my $TName = uncover_typedefs($PureType{"Name"}, $LibVersion);
-    if($TName=~/\A(char(| const)\*|std::(string|basic_string<char>)(|&))\Z/)
+    if(substr($Value, 0, 2) eq "_Z")
+    {
+        if(my $Unmangled = $tr_name{$Value}) {
+            return $Unmangled;
+        }
+    }
+    elsif($TName=~/\A(char(| const)\*|std::(string|basic_string<char>)(|&))\Z/)
     { # strings
         return "\"$Value\"";
     }
@@ -12432,6 +12532,14 @@
                 }
             }
         }
+        if(not checkDump(1, "2.18")
+        and checkDump(2, "2.18"))
+        { # support for old ABI dumps
+            if(not defined $Value_Old
+            and substr($Value_New, 0, 2) eq "_Z") {
+                $Value_Old = $Value_New;
+            }
+        }
         if(defined $Value_Old)
         {
             $Value_Old = showVal($Value_Old, $PType1_Id, 1);
@@ -13200,6 +13308,23 @@
     return $Str;
 }
 
+sub xmlSpecChars_R($)
+{
+    my $Str = $_[0];
+    if(not $Str) {
+        return $Str;
+    }
+    
+    $Str=~s/&amp;/&/g;
+    $Str=~s/&lt;/</g;
+    $Str=~s/&gt;/>/g;
+    
+    $Str=~s/&quot;/"/g;
+    $Str=~s/&#39;/'/g;
+    
+    return $Str;
+}
+
 sub black_name($)
 {
     my $Name = $_[0];
@@ -16914,7 +17039,7 @@
             $WSize = "4";
         }
     }
-    if(not int($WSize)) {
+    if(not $WSize) {
         exitStatus("Error", "can't check WORD size");
     }
     return ($Cache{"detectWordSize"} = $WSize);
@@ -16960,30 +17085,36 @@
         exitStatus("Invalid_Dump", "specified ABI dump \'$Path\' is not valid, try to recreate it");
     }
     
-    my $Line = readLineNum($FilePath, 1);
-    if($Line=~/xml/) {
-        exitStatus("Invalid_Dump", "reading of XML-format ABI dumps is not implemented yet");
-    }
+    my $ABI = {};
     
-    open(DUMP, $FilePath);
-    local $/ = undef;
-    my $Content = <DUMP>;
-    close(DUMP);
-    
-    if(get_dirname($FilePath) eq $TMP_DIR."/unpack")
-    { # remove temp file
-        unlink($FilePath);
+    my $Line = readLineNum($FilePath, 0);
+    if($Line=~/xml/)
+    { # XML format
+        loadModule("XmlDump");
+        $ABI = readXmlDump($FilePath);
     }
-    if($Content!~/};\s*\Z/) {
-        exitStatus("Invalid_Dump", "specified ABI dump \'$Path\' is not valid, try to recreate it");
-    }
-    my $LibraryABI = eval($Content);
-    if(not $LibraryABI) {
-        exitStatus("Error", "internal error - eval() procedure seem to not working correctly, try to remove 'use strict' and try again");
+    else
+    { # Perl Data::Dumper format (default)
+        open(DUMP, $FilePath);
+        local $/ = undef;
+        my $Content = <DUMP>;
+        close(DUMP);
+        
+        if(get_dirname($FilePath) eq $TMP_DIR."/unpack")
+        { # remove temp file
+            unlink($FilePath);
+        }
+        if($Content!~/};\s*\Z/) {
+            exitStatus("Invalid_Dump", "specified ABI dump \'$Path\' is not valid, try to recreate it");
+        }
+        $ABI = eval($Content);
+        if(not $ABI) {
+            exitStatus("Error", "internal error - eval() procedure seem to not working correctly, try to remove 'use strict' and try again");
+        }
     }
     # new dumps (>=1.22) have a personal versioning
-    my $DumpVersion = $LibraryABI->{"ABI_DUMP_VERSION"};
-    my $ToolVersion = $LibraryABI->{"ABI_COMPLIANCE_CHECKER_VERSION"};
+    my $DumpVersion = $ABI->{"ABI_DUMP_VERSION"};
+    my $ToolVersion = $ABI->{"ABI_COMPLIANCE_CHECKER_VERSION"};
     if(not $DumpVersion)
     { # old dumps (<=1.21.6) have been marked by the tool version
         $DumpVersion = $ToolVersion;
@@ -16993,21 +17124,21 @@
     { # should be compatible with dumps of the same major version
         if(cmpVersions($DumpVersion, $ABI_DUMP_VERSION)>0)
         { # Don't know how to parse future dump formats
-            exitStatus("Dump_Version", "incompatible version $DumpVersion of specified ABI dump (newer than $ABI_DUMP_VERSION)");
+            exitStatus("Dump_Version", "incompatible version \'$DumpVersion\' of specified ABI dump (newer than $ABI_DUMP_VERSION)");
         }
-        elsif(cmpVersions($DumpVersion, $TOOL_VERSION)>0 and not $LibraryABI->{"ABI_DUMP_VERSION"})
+        elsif(cmpVersions($DumpVersion, $TOOL_VERSION)>0 and not $ABI->{"ABI_DUMP_VERSION"})
         { # Don't know how to parse future dump formats
-            exitStatus("Dump_Version", "incompatible version $DumpVersion of specified ABI dump (newer than $TOOL_VERSION)");
+            exitStatus("Dump_Version", "incompatible version \'$DumpVersion\' of specified ABI dump (newer than $TOOL_VERSION)");
         }
         if($UseOldDumps)
         {
             if(cmpVersions($DumpVersion, $OLDEST_SUPPORTED_VERSION)<0) {
-                exitStatus("Dump_Version", "incompatible version $DumpVersion of specified ABI dump (older than $OLDEST_SUPPORTED_VERSION)");
+                exitStatus("Dump_Version", "incompatible version \'$DumpVersion\' of specified ABI dump (older than $OLDEST_SUPPORTED_VERSION)");
             }
         }
         else
         {
-            my $Msg = "incompatible version $DumpVersion of specified ABI dump (allowed only ".majorVersion($ABI_DUMP_VERSION).".0<=V<=$ABI_DUMP_VERSION)";
+            my $Msg = "incompatible version \'$DumpVersion\' of specified ABI dump (allowed only ".majorVersion($ABI_DUMP_VERSION).".0<=V<=$ABI_DUMP_VERSION)";
             if(cmpVersions($DumpVersion, $OLDEST_SUPPORTED_VERSION)>=0) {
                 $Msg .= "\nUse -old-dumps option to use old-version dumps ($OLDEST_SUPPORTED_VERSION<=V<".majorVersion($ABI_DUMP_VERSION).".0)";
             }
@@ -17018,7 +17149,7 @@
     { # old ABI dumps
         $UsedDump{$LibVersion}{"BinOnly"} = 1;
     }
-    elsif($LibraryABI->{"BinOnly"})
+    elsif($ABI->{"BinOnly"})
     { # ABI dump created with --binary option
         $UsedDump{$LibVersion}{"BinOnly"} = 1;
     }
@@ -17026,25 +17157,25 @@
     { # default
         $UsedDump{$LibVersion}{"SrcBin"} = 1;
     }
-    if(defined $LibraryABI->{"Mode"}
-    and $LibraryABI->{"Mode"} eq "Extended")
+    if(defined $ABI->{"Mode"}
+    and $ABI->{"Mode"} eq "Extended")
     { # --ext option
         $ExtendedCheck = 1;
     }
-    if(my $Lang = $LibraryABI->{"Language"})
+    if(my $Lang = $ABI->{"Language"})
     {
         $UsedDump{$LibVersion}{"L"} = $Lang;
         setLanguage($LibVersion, $Lang);
     }
     if(checkDump($LibVersion, "2.15")) {
-        $TypeInfo{$LibVersion} = $LibraryABI->{"TypeInfo"};
+        $TypeInfo{$LibVersion} = $ABI->{"TypeInfo"};
     }
     else
     { # support for old ABI dumps
-        my $TInfo = $LibraryABI->{"TypeInfo"};
+        my $TInfo = $ABI->{"TypeInfo"};
         if(not $TInfo)
         { # support for older ABI dumps
-            $TInfo = $LibraryABI->{"TypeDescr"};
+            $TInfo = $ABI->{"TypeDescr"};
         }
         my %Tid_TDid = ();
         foreach my $TDid (keys(%{$TInfo}))
@@ -17100,11 +17231,11 @@
             delete($TypeInfo{$LibVersion}{$Tid}{"TDid"});
         }
     }
-    read_Machine_DumpInfo($LibraryABI, $LibVersion);
-    $SymbolInfo{$LibVersion} = $LibraryABI->{"SymbolInfo"};
+    read_Machine_DumpInfo($ABI, $LibVersion);
+    $SymbolInfo{$LibVersion} = $ABI->{"SymbolInfo"};
     if(not $SymbolInfo{$LibVersion})
     { # support for old dumps
-        $SymbolInfo{$LibVersion} = $LibraryABI->{"FuncDescr"};
+        $SymbolInfo{$LibVersion} = $ABI->{"FuncDescr"};
     }
     if(not keys(%{$SymbolInfo{$LibVersion}}))
     { # validation of old-version dumps
@@ -17112,19 +17243,19 @@
             exitStatus("Invalid_Dump", "the input dump d$LibVersion is invalid");
         }
     }
-    $Library_Symbol{$LibVersion} = $LibraryABI->{"Symbols"};
+    $Library_Symbol{$LibVersion} = $ABI->{"Symbols"};
     if(not $Library_Symbol{$LibVersion})
     { # support for old dumps
-        $Library_Symbol{$LibVersion} = $LibraryABI->{"Interfaces"};
+        $Library_Symbol{$LibVersion} = $ABI->{"Interfaces"};
     }
     if(checkDump($LibVersion, "2.15")) {
-        $DepLibrary_Symbol{$LibVersion} = $LibraryABI->{"DepSymbols"};
+        $DepLibrary_Symbol{$LibVersion} = $ABI->{"DepSymbols"};
     }
     else
     { # support for old ABI dumps
-        my $DepSymbols = $LibraryABI->{"DepSymbols"};
+        my $DepSymbols = $ABI->{"DepSymbols"};
         if(not $DepSymbols) {
-            $DepSymbols = $LibraryABI->{"DepInterfaces"};
+            $DepSymbols = $ABI->{"DepInterfaces"};
         }
         if(not $DepSymbols)
         { # Cannot reconstruct DepSymbols. This may result in false
@@ -17136,32 +17267,32 @@
             $DepSymbol_Library{$LibVersion}{$Symbol} = 1;
         }
     }
-    $SymVer{$LibVersion} = $LibraryABI->{"SymbolVersion"};
-    $Descriptor{$LibVersion}{"Version"} = $LibraryABI->{"LibraryVersion"};
-    $SkipTypes{$LibVersion} = $LibraryABI->{"SkipTypes"};
+    $SymVer{$LibVersion} = $ABI->{"SymbolVersion"};
+    $Descriptor{$LibVersion}{"Version"} = $ABI->{"LibraryVersion"};
+    $SkipTypes{$LibVersion} = $ABI->{"SkipTypes"};
     if(not $SkipTypes{$LibVersion})
     { # support for old dumps
-        $SkipTypes{$LibVersion} = $LibraryABI->{"OpaqueTypes"};
+        $SkipTypes{$LibVersion} = $ABI->{"OpaqueTypes"};
     }
-    $SkipSymbols{$LibVersion} = $LibraryABI->{"SkipSymbols"};
+    $SkipSymbols{$LibVersion} = $ABI->{"SkipSymbols"};
     if(not $SkipSymbols{$LibVersion})
     { # support for old dumps
-        $SkipSymbols{$LibVersion} = $LibraryABI->{"SkipInterfaces"};
+        $SkipSymbols{$LibVersion} = $ABI->{"SkipInterfaces"};
     }
     if(not $SkipSymbols{$LibVersion})
     { # support for old dumps
-        $SkipSymbols{$LibVersion} = $LibraryABI->{"InternalInterfaces"};
+        $SkipSymbols{$LibVersion} = $ABI->{"InternalInterfaces"};
     }
-    $SkipNameSpaces{$LibVersion} = $LibraryABI->{"SkipNameSpaces"};
-    $TargetHeaders{$LibVersion} = $LibraryABI->{"TargetHeaders"};
-    foreach my $Path (keys(%{$LibraryABI->{"SkipHeaders"}}))
+    $SkipNameSpaces{$LibVersion} = $ABI->{"SkipNameSpaces"};
+    $TargetHeaders{$LibVersion} = $ABI->{"TargetHeaders"};
+    foreach my $Path (keys(%{$ABI->{"SkipHeaders"}}))
     {
-        $SkipHeadersList{$LibVersion}{$Path} = $LibraryABI->{"SkipHeaders"}{$Path};
+        $SkipHeadersList{$LibVersion}{$Path} = $ABI->{"SkipHeaders"}{$Path};
         my ($CPath, $Type) = classifyPath($Path);
-        $SkipHeaders{$LibVersion}{$Type}{$CPath} = $LibraryABI->{"SkipHeaders"}{$Path};
+        $SkipHeaders{$LibVersion}{$Type}{$CPath} = $ABI->{"SkipHeaders"}{$Path};
     }
-    read_Headers_DumpInfo($LibraryABI, $LibVersion);
-    read_Libs_DumpInfo($LibraryABI, $LibVersion);
+    read_Headers_DumpInfo($ABI, $LibVersion);
+    read_Libs_DumpInfo($ABI, $LibVersion);
     if(not checkDump($LibVersion, "2.10.1")
     or not $TargetHeaders{$LibVersion})
     { # support for old ABI dumps: added target headers
@@ -17169,8 +17300,8 @@
             $TargetHeaders{$LibVersion}{get_filename($_)}=1;
         }
     }
-    $Constants{$LibVersion} = $LibraryABI->{"Constants"};
-    $NestedNameSpaces{$LibVersion} = $LibraryABI->{"NameSpaces"};
+    $Constants{$LibVersion} = $ABI->{"Constants"};
+    $NestedNameSpaces{$LibVersion} = $ABI->{"NameSpaces"};
     if(not $NestedNameSpaces{$LibVersion})
     { # support for old dumps
       # Cannot reconstruct NameSpaces. This may affect design
@@ -17181,7 +17312,7 @@
     # needed to adopt HTML report
     if(not $DumpSystem)
     { # to use in createSymbolsList(...)
-        $OStarget = $LibraryABI->{"Target"};
+        $OStarget = $ABI->{"Target"};
     }
     # recreate environment
     foreach my $Lib_Name (keys(%{$Library_Symbol{$LibVersion}}))
@@ -17217,6 +17348,10 @@
                 push(@VFunc, $MnglName);
             }
         }
+        else
+        { # ABI dumps have no mangled names for C-functions
+            $SymbolInfo{$LibVersion}{$InfoId}{"MnglName"} = $SymbolInfo{$LibVersion}{$InfoId}{"ShortName"};
+        }
     }
     translateSymbols(@VFunc, $LibVersion);
     translateSymbols(keys(%{$Symbol_Library{$LibVersion}}), $LibVersion);
@@ -17238,6 +17373,9 @@
             }
             delete($TypeInfo{$LibVersion}{$TypeId}{"BaseClass"});
         }
+        if(not defined $TypeInfo{$LibVersion}{$TypeId}{"Tid"}) {
+            $TypeInfo{$LibVersion}{$TypeId}{"Tid"} = $TypeId;
+        }
         my %TInfo = %{$TypeInfo{$LibVersion}{$TypeId}};
         if(defined $TInfo{"Base"})
         {
@@ -17245,6 +17383,21 @@
                 $Class_SubClasses{$LibVersion}{$_}{$TypeId}=1;
             }
         }
+        if($TInfo{"Type"} eq "MethodPtr")
+        {
+            if(defined $TInfo{"Param"})
+            { # support for old ABI dumps <= 1.17
+                if(not defined $TInfo{"Param"}{"0"})
+                {
+                    my $Max = keys(%{$TInfo{"Param"}});
+                    foreach my $Pos (1 .. $Max) {
+                        $TInfo{"Param"}{$Pos-1} = $TInfo{"Param"}{$Pos};
+                    }
+                    delete($TInfo{"Param"}{$Max});
+                    %{$TypeInfo{$LibVersion}{$TypeId}} = %TInfo;
+                }
+            }
+        }
         if($TInfo{"Type"} eq "Typedef" and defined $TInfo{"BaseType"})
         {
             if(my $BTid = $TInfo{"BaseType"}{"Tid"})
@@ -17296,16 +17449,16 @@
 
 sub read_Machine_DumpInfo($$)
 {
-    my ($LibraryABI, $LibVersion) = @_;
-    if($LibraryABI->{"Arch"}) {
-        $CPU_ARCH{$LibVersion} = $LibraryABI->{"Arch"};
+    my ($ABI, $LibVersion) = @_;
+    if($ABI->{"Arch"}) {
+        $CPU_ARCH{$LibVersion} = $ABI->{"Arch"};
     }
-    if($LibraryABI->{"WordSize"}) {
-        $WORD_SIZE{$LibVersion} = $LibraryABI->{"WordSize"};
+    if($ABI->{"WordSize"}) {
+        $WORD_SIZE{$LibVersion} = $ABI->{"WordSize"};
     }
     else
     { # support for old dumps
-        $WORD_SIZE{$LibVersion} = $LibraryABI->{"SizeOfPointer"};
+        $WORD_SIZE{$LibVersion} = $ABI->{"SizeOfPointer"};
     }
     if(not $WORD_SIZE{$LibVersion})
     { # support for old dumps (<1.23)
@@ -17333,14 +17486,14 @@
             }
         }
     }
-    if($LibraryABI->{"GccVersion"}) {
-        $GCC_VERSION{$LibVersion} = $LibraryABI->{"GccVersion"};
+    if($ABI->{"GccVersion"}) {
+        $GCC_VERSION{$LibVersion} = $ABI->{"GccVersion"};
     }
 }
 
 sub read_Libs_DumpInfo($$)
 {
-    my ($LibraryABI, $LibVersion) = @_;
+    my ($ABI, $LibVersion) = @_;
     if(keys(%{$Library_Symbol{$LibVersion}})
     and not $DumpAPI) {
         $Descriptor{$LibVersion}{"Libs"} = "OK";
@@ -17349,19 +17502,20 @@
 
 sub read_Headers_DumpInfo($$)
 {
-    my ($LibraryABI, $LibVersion) = @_;
-    if(keys(%{$LibraryABI->{"Headers"}})
+    my ($ABI, $LibVersion) = @_;
+    if(keys(%{$ABI->{"Headers"}})
     and not $DumpAPI) {
         $Descriptor{$LibVersion}{"Headers"} = "OK";
     }
-    foreach my $Identity (keys(%{$LibraryABI->{"Headers"}}))
+    foreach my $Identity (sort {$ABI->{"Headers"}{$a}<=>$ABI->{"Headers"}{$b}} keys(%{$ABI->{"Headers"}}))
     { # headers info is stored in the old dumps in the different way
         if($UseOldDumps
-        and my $Name = $LibraryABI->{"Headers"}{$Identity}{"Name"})
+        and my $Name = $ABI->{"Headers"}{$Identity}{"Name"})
         { # support for old dumps: headers info corrected in 1.22
             $Identity = $Name;
         }
         $Registered_Headers{$LibVersion}{$Identity}{"Identity"} = $Identity;
+        $Registered_Headers{$LibVersion}{$Identity}{"Pos"} = $ABI->{"Headers"}{$Identity};
     }
 }
 
@@ -17701,6 +17855,22 @@
         if(not $CrossGcc) {
             $GCC_PATH = get_CmdPath("gcc");
         }
+        if(not $GCC_PATH)
+        { # try to find gcc-X.Y
+            foreach my $Path (sort {$b=~/\/usr\/bin/ cmp $a=~/\/usr\/bin/}
+            keys(%{$SystemPaths{"bin"}}))
+            {
+                if(my @GCCs = cmd_find($Path, "", ".*/gcc-[0-9.]*", 1))
+                { # select the latest version
+                    @GCCs = sort {$b cmp $a} @GCCs;
+                    if(check_gcc($GCCs[0], "3"))
+                    {
+                        $GCC_PATH = $GCCs[0];
+                        last;
+                    }
+                }
+            }
+        }
         if(not $GCC_PATH) {
             exitStatus("Not_Found", "can't find GCC>=3.0 in PATH");
         }
@@ -18576,19 +18746,24 @@
     }
     initLogging(1);
     detect_default_paths("inc|lib|bin|gcc"); # complete analysis
-    if(not $CheckHeadersOnly) {
-        readLibs(1);
+    if(not $Descriptor{1}{"Dump"})
+    {
+        if(not $CheckHeadersOnly) {
+            readLibs(1);
+        }
+        if($CheckHeadersOnly) {
+            setLanguage(1, "C++");
+        }
+        if(not $CheckObjectsOnly) {
+            searchForHeaders(1);
+        }
+        $WORD_SIZE{1} = detectWordSize();
     }
-    if($CheckHeadersOnly) {
-        setLanguage(1, "C++");
-    }
-    if(not $CheckObjectsOnly) {
-        searchForHeaders(1);
-    }
-    $WORD_SIZE{1} = detectWordSize();
-    if($Descriptor{1}{"Headers"}
-    and not $Descriptor{1}{"Dump"}) {
-        readHeaders(1);
+    if(not $Descriptor{1}{"Dump"})
+    {
+        if($Descriptor{1}{"Headers"}) {
+            readHeaders(1);
+        }
     }
     cleanDump(1);
     if(not keys(%{$SymbolInfo{1}}))
@@ -18609,7 +18784,7 @@
         $HeadersInfo{$Registered_Headers{1}{$HPath}{"Identity"}} = $Registered_Headers{1}{$HPath}{"Pos"};
     }
     printMsg("INFO", "creating library ABI dump ...");
-    my %LibraryABI = (
+    my %ABI = (
         "TypeInfo" => $TypeInfo{1},
         "SymbolInfo" => $SymbolInfo{1},
         "Symbols" => $Library_Symbol{1},
@@ -18633,29 +18808,29 @@
         "ABI_COMPLIANCE_CHECKER_VERSION" => $TOOL_VERSION
     );
     if(diffSets($TargetHeaders{1}, \%HeadersInfo)) {
-        $LibraryABI{"TargetHeaders"} = $TargetHeaders{1};
+        $ABI{"TargetHeaders"} = $TargetHeaders{1};
     }
     if($UseXML) {
-        $LibraryABI{"XML_ABI_DUMP_VERSION"} = $XML_ABI_DUMP_VERSION;
+        $ABI{"XML_ABI_DUMP_VERSION"} = $XML_ABI_DUMP_VERSION;
     }
     if($ExtendedCheck)
     { # --ext option
-        $LibraryABI{"Mode"} = "Extended";
+        $ABI{"Mode"} = "Extended";
     }
     if($BinaryOnly)
     { # --binary
-        $LibraryABI{"BinOnly"} = 1;
+        $ABI{"BinOnly"} = 1;
     }
     
     my $ABI_DUMP = "";
     if($UseXML)
     {
         loadModule("XmlDump");
-        $ABI_DUMP = createXmlDump(\%LibraryABI);
+        $ABI_DUMP = createXmlDump(\%ABI);
     }
     else
     { # default
-        $ABI_DUMP = Dumper(\%LibraryABI);
+        $ABI_DUMP = Dumper(\%ABI);
     }
     if($StdOut)
     { # --stdout option
@@ -18714,6 +18889,13 @@
         my $FilePath2 = unpackDump($Descriptor{2}{"Path"});
         if($FilePath1 and $FilePath2)
         {
+            my $Line = readLineNum($FilePath1, 0);
+            if($Line=~/xml/)
+            { # XML format
+                # is not supported yet
+                return;
+            }
+            
             local $/ = undef;
             
             open(DUMP1, $FilePath1);
@@ -18972,6 +19154,9 @@
             if($SortDump) {
                 @PARAMS = (@PARAMS, "-sort");
             }
+            if($DumpFormat and $DumpFormat ne "perl") {
+                @PARAMS = (@PARAMS, "-dump-format", $DumpFormat);
+            }
             if($Debug)
             {
                 @PARAMS = (@PARAMS, "-debug");
@@ -19021,6 +19206,9 @@
             if($SortDump) {
                 @PARAMS = (@PARAMS, "-sort");
             }
+            if($DumpFormat and $DumpFormat ne "perl") {
+                @PARAMS = (@PARAMS, "-dump-format", $DumpFormat);
+            }
             if($Debug)
             {
                 @PARAMS = (@PARAMS, "-debug");
@@ -19355,7 +19543,7 @@
         }
     }
     else
-    { # default: HTML
+    { # default: Perl Data::Dumper
         $DumpFormat = "perl";
     }
     if($Quiet and $LogMode!~/a|n/)
@@ -19437,7 +19625,7 @@
         detect_default_paths("bin|gcc"); # to compile libs
         loadModule("RegTests");
         testTool($TestDump, $Debug, $Quiet, $ExtendedCheck, $LogMode,
-        $ReportFormat, $LIB_EXT, $GCC_PATH, $Browse, $OpenReport, $SortDump);
+        $ReportFormat, $DumpFormat, $LIB_EXT, $GCC_PATH, $Browse, $OpenReport, $SortDump);
         exit(0);
     }
     if($DumpSystem)