ABI Compliance Checker 1.99.8
diff --git a/abi-compliance-checker.pl b/abi-compliance-checker.pl
index 305ca0b..5d23dea 100755
--- a/abi-compliance-checker.pl
+++ b/abi-compliance-checker.pl
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 ###########################################################################
-# ABI Compliance Checker (ACC) 1.99.7
+# ABI Compliance Checker (ACC) 1.99.8
 # A tool for checking backward compatibility of a C/C++ library API
 #
 # Copyright (C) 2009-2010 The Linux Foundation
@@ -38,7 +38,7 @@
 #
 # COMPATIBILITY
 # =============
-#  ABI Dumper >= 0.97
+#  ABI Dumper >= 0.98
 #
 #
 # This program is free software: you can redistribute it and/or modify
@@ -64,7 +64,7 @@
 use Data::Dumper;
 use Config;
 
-my $TOOL_VERSION = "1.99.7";
+my $TOOL_VERSION = "1.99.8";
 my $ABI_DUMP_VERSION = "3.2";
 my $OLDEST_SUPPORTED_VERSION = "1.18";
 my $XML_REPORT_VERSION = "1.1";
@@ -93,7 +93,7 @@
 $UserLang, $TargetHeadersPath, $BinaryOnly, $SourceOnly, $BinaryReportPath,
 $SourceReportPath, $UseXML, $Browse, $OpenReport, $SortDump, $DumpFormat,
 $ExtraInfo, $ExtraDump, $Force, $Tolerance, $Tolerant, $SkipSymbolsListPath,
-$CheckInfo, $Quick);
+$CheckInfo, $Quick, $AffectLimit, $AllAffected);
 
 my $CmdName = get_filename($0);
 my %OS_LibExt = (
@@ -246,6 +246,7 @@
   "lang=s" => \$UserLang,
   "binary|bin|abi!" => \$BinaryOnly,
   "source|src|api!" => \$SourceOnly,
+  "affected-limit=s" => \$AffectLimit,
 # other options
   "test!" => \$TestTool,
   "test-dump!" => \$TestDump,
@@ -274,7 +275,8 @@
   "tolerance=s" => \$Tolerance,
   "tolerant!" => \$Tolerant,
   "check!" => \$CheckInfo,
-  "quick!" => \$Quick
+  "quick!" => \$Quick,
+  "all-affected!" => \$AllAffected
 ) or ERR_MESSAGE();
 
 sub ERR_MESSAGE()
@@ -637,6 +639,10 @@
       Show \"Source\" compatibility problems only.
       Generate report to:
         compat_reports/LIB_NAME/V1_to_V2/src_compat_report.html
+        
+  -affected-limit LIMIT
+      The maximum number of affected symbols listed under the description
+      of the changed type in the report.
 
 OTHER OPTIONS:
   -test
@@ -1123,6 +1129,7 @@
 my %DEFAULT_STD_ARGS = map {$_=>1} ("_Alloc", "_Compare", "_Traits", "_Rx_traits", "_InIter", "_OutIter");
 
 my $ADD_TMPL_INSTANCES = 1;
+my $EMERGENCY_MODE_48 = 0;
 
 my %ConstantSuffix = (
     "unsigned int"=>"u",
@@ -1593,6 +1600,7 @@
 my %SourceAlternative;
 my %SourceAlternative_B;
 my %SourceReplacement;
+my $CurrentSymbol; # for debugging
 
 # Calling Conventions
 my %UseConv_Real = (
@@ -4287,8 +4295,16 @@
         foreach my $ParamPos (sort {int($a) <=> int($b)} @Params)
         { # checking parameters
             my $PId = $SymbolInfo{$Version}{$InfoId}{"Param"}{$ParamPos}{"type"};
+            my $PName = $SymbolInfo{$Version}{$InfoId}{"Param"}{$ParamPos}{"name"};
             my %PType = get_PureType($PId, $TypeInfo{$Version});
             my $PTName = unmangledFormat($PType{"Name"}, $Version);
+            
+            if($PName eq "this"
+            and $SymbolInfo{$Version}{$InfoId}{"Type"} eq "Method")
+            {
+                next;
+            }
+            
             $PTName=~s/\b(restrict|register)\b//g;
             if($Compiler eq "MSVC") {
                 $PTName=~s/\blong long\b/__int64/;
@@ -4499,16 +4515,16 @@
     if($SymbolInfo{$LibVersion}{$InfoId}{"Constructor"})
     {
         if($MangledNames{$LibVersion}{$Mangled}) {
-            $Mangled=~s/C1E/C2E/;
+            $Mangled=~s/C1([EI])/C2$1/;
         }
     }
     elsif($SymbolInfo{$LibVersion}{$InfoId}{"Destructor"})
     {
         if($MangledNames{$LibVersion}{$Mangled}) {
-            $Mangled=~s/D0E/D1E/;
+            $Mangled=~s/D0([EI])/D1$1/;
         }
         if($MangledNames{$LibVersion}{$Mangled}) {
-            $Mangled=~s/D1E/D2E/;
+            $Mangled=~s/D1([EI])/D2$1/;
         }
     }
     return $Mangled;
@@ -5030,9 +5046,11 @@
     my $InfoId = $_[0];
     # try to mangle symbol
     if((not check_gcc($GCC_PATH, "4") and $SymbolInfo{$Version}{$InfoId}{"Class"})
-    or (check_gcc($GCC_PATH, "4") and not $SymbolInfo{$Version}{$InfoId}{"Class"}))
-    { # 1. GCC 3.x doesn't mangle class methods names in the TU dump (only functions and global data)
-      # 2. GCC 4.x doesn't mangle C++ functions in the TU dump (only class methods) except extern "C" functions
+    or (check_gcc($GCC_PATH, "4") and not $SymbolInfo{$Version}{$InfoId}{"Class"})
+    or $EMERGENCY_MODE_48)
+    { # GCC 3.x doesn't mangle class methods names in the TU dump (only functions and global data)
+      # GCC 4.x doesn't mangle C++ functions in the TU dump (only class methods) except extern "C" functions
+      # GCC 4.8 doesn't mangle anything
         if(not $CheckHeadersOnly)
         {
             if(my $Mangled = $mangled_name_gcc{modelUnmangled($InfoId, "GCC")}) {
@@ -5040,7 +5058,8 @@
             }
         }
         if($CheckHeadersOnly
-        or not $BinaryOnly)
+        or not $BinaryOnly
+        or $EMERGENCY_MODE_48)
         { # 1. --headers-only mode
           # 2. not mangled src-only symbols
             if(my $Mangled = mangle_symbol($InfoId, $Version, "GCC")) {
@@ -5370,7 +5389,7 @@
             }
         }
     }
-    delete($SymbolInfo{$Version}{$InfoId}{"Type"});
+    
     if($SymbolInfo{$Version}{$InfoId}{"MnglName"}=~/\A_ZN(V|)K/) {
         $SymbolInfo{$Version}{$InfoId}{"Const"} = 1;
     }
@@ -5549,7 +5568,10 @@
 {
     my $InfoId = $_[0];
     my $ParamInfoId = getTreeAttr_Args($InfoId);
-    if(getFuncType($InfoId) eq "Method")
+    
+    my $FType = getFuncType($InfoId);
+    
+    if($FType eq "Method")
     { # check type of "this" pointer
         my $ObjectTypeId = getTreeAttr_Type($ParamInfoId);
         if(my $ObjectName = $TypeInfo{$Version}{$ObjectTypeId}{"Name"})
@@ -5568,14 +5590,14 @@
         # skip "this"-parameter
         # $ParamInfoId = getNextElem($ParamInfoId);
     }
-    my ($Pos, $Vtt_Pos) = (0, -1);
+    my ($Pos, $PPos, $Vtt_Pos) = (0, 0, -1);
     while($ParamInfoId)
     { # formal args
         my $ParamTypeId = getTreeAttr_Type($ParamInfoId);
         my $ParamName = getTreeStr(getTreeAttr_Name($ParamInfoId));
         if(not $ParamName)
         { # unnamed
-            $ParamName = "p".($Pos+1);
+            $ParamName = "p".($PPos+1);
         }
         if(defined $MissedTypedef{$Version}{$ParamTypeId})
         {
@@ -5614,15 +5636,15 @@
         if(my $Algn = getAlgn($ParamInfoId)) {
             $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"algn"} = $Algn/$BYTE_SIZE;
         }
-        if(not $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"name"}) {
-            $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"name"} = "p".($Pos+1);
-        }
         if($LibInfo{$Version}{"info"}{$ParamInfoId}=~/spec:\s*register /)
         { # foo(register type arg)
             $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"reg"} = 1;
         }
         $ParamInfoId = getNextElem($ParamInfoId);
         $Pos += 1;
+        if($ParamName ne "this" or $FType ne "Method") {
+            $PPos += 1;
+        }
     }
     if(setFuncArgs($InfoId, $Vtt_Pos)) {
         $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"type"} = "-1";
@@ -5635,7 +5657,11 @@
     my ($InfoId, $Vtt_Pos) = @_;
     my $FuncTypeId = getFuncTypeId($InfoId);
     my $ParamListElemId = getTreeAttr_Prms($FuncTypeId);
-    if(getFuncType($InfoId) eq "Method") {
+    my $FType = getFuncType($InfoId);
+    
+    if($FType eq "Method")
+    {
+        # skip "this"-parameter
         # $ParamListElemId = getNextElem($ParamListElemId);
     }
     if(not $ParamListElemId)
@@ -5643,7 +5669,7 @@
         return 1;
     }
     my $HaveVoid = 0;
-    my $Pos = 0;
+    my ($Pos, $PPos) = (0, 0);
     while($ParamListElemId)
     { # actual params: may differ from formal args
       # formal int*const
@@ -5667,7 +5693,7 @@
                 $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"type"} = $ParamTypeId;
                 if(not $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"name"})
                 { # unnamed
-                    $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"name"} = "p".($Pos+1);
+                    $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"name"} = "p".($PPos+1);
                 }
             }
             elsif(my $OldId = $SymbolInfo{$Version}{$InfoId}{"Param"}{$Pos}{"type"})
@@ -5701,6 +5727,9 @@
             }
         }
         $ParamListElemId = getNextElem($ParamListElemId);
+        if($Pos!=0 or $FType ne "Method") {
+            $PPos += 1;
+        }
         $Pos += 1;
     }
     return ($Pos>=1 and not $HaveVoid);
@@ -6223,6 +6252,7 @@
     $Dir=~s/[\/\\]+\Z//g;
     return if(not $LibVersion or not $Dir or not -d $Dir);
     $Dir = get_abs_path($Dir);
+    
     my $Mode = "All";
     if($WithDeps)
     {
@@ -7509,41 +7539,41 @@
     {
         if($CompleteSignature{$LibVersion}{$Symbol}{"Constructor"})
         {
-            if($Symbol=~/C1E/) {
+            if($Symbol=~/C1[EI]/) {
                 return "[in-charge]";
             }
-            elsif($Symbol=~/C2E/) {
+            elsif($Symbol=~/C2[EI]/) {
                 return "[not-in-charge]";
             }
         }
         elsif($CompleteSignature{$LibVersion}{$Symbol}{"Destructor"})
         {
-            if($Symbol=~/D1E/) {
+            if($Symbol=~/D1[EI]/) {
                 return "[in-charge]";
             }
-            elsif($Symbol=~/D2E/) {
+            elsif($Symbol=~/D2[EI]/) {
                 return "[not-in-charge]";
             }
-            elsif($Symbol=~/D0E/) {
+            elsif($Symbol=~/D0[EI]/) {
                 return "[in-charge-deleting]";
             }
         }
     }
     else
     {
-        if($Symbol=~/C1E/) {
+        if($Symbol=~/C1[EI]/) {
             return "[in-charge]";
         }
-        elsif($Symbol=~/C2E/) {
+        elsif($Symbol=~/C2[EI]/) {
             return "[not-in-charge]";
         }
-        elsif($Symbol=~/D1E/) {
+        elsif($Symbol=~/D1[EI]/) {
             return "[in-charge]";
         }
-        elsif($Symbol=~/D2E/) {
+        elsif($Symbol=~/D2[EI]/) {
             return "[not-in-charge]";
         }
-        elsif($Symbol=~/D0E/) {
+        elsif($Symbol=~/D0[EI]/) {
             return "[in-charge-deleting]";
         }
     }
@@ -7615,10 +7645,12 @@
         }
         if(my $ParamName = $CompleteSignature{$LibVersion}{$Symbol}{"Param"}{$Pos}{"name"})
         {
-            if($ParamName ne "this" or $Symbol!~/\A(_Z|\?)/)
+            if($ParamName eq "this"
+            and $Symbol=~/\A(_Z|\?)/)
             { # do NOT show first hidded "this"-parameter
-                push(@ParamArray, create_member_decl($ParamTypeName, $ParamName));
+                next;
             }
+            push(@ParamArray, create_member_decl($ParamTypeName, $ParamName));
         }
         else {
             push(@ParamArray, $ParamTypeName);
@@ -8079,7 +8111,12 @@
     if($OSgroup eq "macos") {
         $GccCall .= "objective-";
     }
-    if(check_gcc($GCC_PATH, "4"))
+    
+    if($EMERGENCY_MODE_48)
+    { # workaround for GCC 4.8 (C only)
+        $GccCall .= "c++";
+    }
+    elsif(check_gcc($GCC_PATH, "4"))
     { # compile as "C++" header
       # to obtain complete dump using GCC 4.0
         $GccCall .= "c++-header";
@@ -9818,6 +9855,7 @@
         if(not keys(%{$SymbolInfo{$LibVersion}{$InfoId}{"TParam"}})) {
             delete($SymbolInfo{$LibVersion}{$InfoId}{"TParam"});
         }
+        delete($SymbolInfo{$LibVersion}{$InfoId}{"Type"});
     }
     foreach my $Tid (keys(%{$TypeInfo{$LibVersion}}))
     {
@@ -11314,17 +11352,6 @@
     "Safe"=>-1
 );
 
-sub maxSeverity($$)
-{
-    my ($S1, $S2) = @_;
-    if(cmpSeverities($S1, $S2)) {
-        return $S1;
-    }
-    else {
-        return $S2;
-    }
-}
-
 sub cmpSeverities($$)
 {
     my ($S1, $S2) = @_;
@@ -11337,12 +11364,6 @@
     return ($Severity_Val{$S1}>$Severity_Val{$S2});
 }
 
-sub getProblemSeverity($$)
-{
-    my ($Level, $Kind) = @_;
-    return $CompatRules{$Level}{$Kind}{"Severity"};
-}
-
 sub isRecurType($$$)
 {
     foreach (@{$_[2]})
@@ -11495,23 +11516,27 @@
 sub mergeTypes($$$)
 {
     my ($Type1_Id, $Type2_Id, $Level) = @_;
-    return () if(not $Type1_Id or not $Type2_Id);
-    my (%Sub_SubProblems, %SubProblems) = ();
+    return {} if(not $Type1_Id or not $Type2_Id);
+    
     if($Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id})
     { # already merged
-        return %{$Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id}};
+        return $Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id};
     }
+    
     my %Type1 = get_Type($Type1_Id, 1);
     my %Type2 = get_Type($Type2_Id, 2);
     if(not $Type1{"Name"} or not $Type2{"Name"}) {
-        return ();
+        return {};
     }
     
     $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;
     
+    my %SubProblems = ();
+    
     if($Type1_Pure{"Name"} eq $Type2_Pure{"Name"})
     {
         if($Type1_Pure{"Type"}=~/Struct|Union/
@@ -11523,8 +11548,7 @@
                     "Target"=>$Type1_Pure{"Name"},
                     "Type_Name"=>$Type1_Pure{"Name"}  );
                 
-                %{$Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id}} = %SubProblems;
-                return %SubProblems;
+                return ($Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id} = \%SubProblems);
             }
         }
     }
@@ -11535,16 +11559,16 @@
         if(not defined $Type1_Pure{"Memb"} or not defined $Type2_Pure{"Memb"}
         or index($Type1_Pure{"Name"}, "<")==-1 or index($Type2_Pure{"Name"}, "<")==-1)
         { # NOTE: template instances have no size
-            return ();
+            return {};
         }
     }
     if(isRecurType($Type1_Pure{"Tid"}, $Type2_Pure{"Tid"}, \@RecurTypes))
     { # skip recursive declarations
-        return ();
+        return {};
     }
-    return () if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
-    return () if($SkipTypes{1}{$Type1_Pure{"Name"}});
-    return () if($SkipTypes{1}{$Type1{"Name"}});
+    return {} if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
+    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
@@ -11658,8 +11682,7 @@
                     "New_Value"=>lc($Type2_Pure{"Type"})  );
             }
         }
-        %{$Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id}} = %SubProblems;
-        return %SubProblems;
+        return ($Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id} = \%SubProblems);
     }
     pushType($Type1_Pure{"Tid"}, $Type2_Pure{"Tid"}, \@RecurTypes);
     if(($Type1_Pure{"Name"} eq $Type2_Pure{"Name"}
@@ -11692,22 +11715,17 @@
                 "Target"=>$Type1_Pure{"Name"},
                 "Type_Name"=>$Type1_Pure{"Name"},
                 "Old_Size"=>$Type1_Pure{"Size"}*$BYTE_SIZE,
-                "New_Size"=>$Type2_Pure{"Size"}*$BYTE_SIZE,
-                "InitialType_Type"=>$Type1_Pure{"Type"}  );
+                "New_Size"=>$Type2_Pure{"Size"}*$BYTE_SIZE);
         }
     }
     if(defined $Type1_Pure{"BaseType"}
     and defined $Type2_Pure{"BaseType"})
     { # checking base types
-        %Sub_SubProblems = mergeTypes($Type1_Pure{"BaseType"}, $Type2_Pure{"BaseType"}, $Level);
-        foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
+        my $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}}))
-            {
-                foreach my $Attr (keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})) {
-                    $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{$Attr} = $Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{$Attr};
-                }
-                $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{"InitialType_Type"} = $Type1_Pure{"Type"};
+            foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems->{$Sub_SubProblemType}})) {
+                $SubProblems{$Sub_SubProblemType}{$Sub_SubLocation} = $Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation};
             }
         }
     }
@@ -12098,11 +12116,11 @@
                             "Type_Name"=>$Type1_Pure{"Name"});
                     }
                 }
-                %Sub_SubProblems = detectTypeChange($MemberType1_Id, $MemberType2_Id, "Field", $Level);
-                foreach my $ProblemType (keys(%Sub_SubProblems))
+                my %Sub_SubChanges = detectTypeChange($MemberType1_Id, $MemberType2_Id, "Field", $Level);
+                foreach my $ProblemType (keys(%Sub_SubChanges))
                 {
-                    my $Old_Value = $Sub_SubProblems{$ProblemType}{"Old_Value"};
-                    my $New_Value = $Sub_SubProblems{$ProblemType}{"New_Value"};
+                    my $Old_Value = $Sub_SubChanges{$ProblemType}{"Old_Value"};
+                    my $New_Value = $Sub_SubChanges{$ProblemType}{"New_Value"};
                     
                     # quals
                     if($ProblemType eq "Field_Type"
@@ -12112,28 +12130,28 @@
                         if(checkDump(1, "2.6") and checkDump(2, "2.6"))
                         {
                             if(addedQual($Old_Value, $New_Value, "volatile")) {
-                                %{$Sub_SubProblems{"Field_Became_Volatile"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubChanges{"Field_Became_Volatile"}} = %{$Sub_SubChanges{$ProblemType}};
                             }
                             elsif(removedQual($Old_Value, $New_Value, "volatile")) {
-                                %{$Sub_SubProblems{"Field_Became_Non_Volatile"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubChanges{"Field_Became_Non_Volatile"}} = %{$Sub_SubChanges{$ProblemType}};
                             }
                         }
                         if(my $RA = addedQual($Old_Value, $New_Value, "const"))
                         {
                             if($RA==2) {
-                                %{$Sub_SubProblems{"Field_Added_Const"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubChanges{"Field_Added_Const"}} = %{$Sub_SubChanges{$ProblemType}};
                             }
                             else {
-                                %{$Sub_SubProblems{"Field_Became_Const"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubChanges{"Field_Became_Const"}} = %{$Sub_SubChanges{$ProblemType}};
                             }
                         }
                         elsif(my $RR = removedQual($Old_Value, $New_Value, "const"))
                         {
                             if($RR==2) {
-                                %{$Sub_SubProblems{"Field_Removed_Const"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubChanges{"Field_Removed_Const"}} = %{$Sub_SubChanges{$ProblemType}};
                             }
                             else {
-                                %{$Sub_SubProblems{"Field_Became_Non_Const"}} = %{$Sub_SubProblems{$ProblemType}};
+                                %{$Sub_SubChanges{"Field_Became_Non_Const"}} = %{$Sub_SubChanges{$ProblemType}};
                             }
                         }
                     }
@@ -12141,21 +12159,21 @@
                 
                 if($Level eq "Source")
                 {
-                    foreach my $ProblemType (keys(%Sub_SubProblems))
+                    foreach my $ProblemType (keys(%Sub_SubChanges))
                     {
-                        my $Old_Value = $Sub_SubProblems{$ProblemType}{"Old_Value"};
-                        my $New_Value = $Sub_SubProblems{$ProblemType}{"New_Value"};
+                        my $Old_Value = $Sub_SubChanges{$ProblemType}{"Old_Value"};
+                        my $New_Value = $Sub_SubChanges{$ProblemType}{"New_Value"};
                         
                         if($ProblemType eq "Field_Type")
                         {
                             if(cmpBTypes($Old_Value, $New_Value, 1, 2)) {
-                                delete($Sub_SubProblems{$ProblemType});
+                                delete($Sub_SubChanges{$ProblemType});
                             }
                         }
                     }
                 }
                 
-                foreach my $ProblemType (keys(%Sub_SubProblems))
+                foreach my $ProblemType (keys(%Sub_SubChanges))
                 {
                     my $ProblemType_Init = $ProblemType;
                     if($ProblemType eq "Field_Type_And_Size")
@@ -12194,9 +12212,9 @@
                         "Target"=>$Member_Name,
                         "Type_Name"=>$Type1_Pure{"Name"});
                     
-                    foreach my $Attr (keys(%{$Sub_SubProblems{$ProblemType_Init}}))
+                    foreach my $Attr (keys(%{$Sub_SubChanges{$ProblemType_Init}}))
                     { # other properties
-                        $SubProblems{$ProblemType}{$Member_Name}{$Attr} = $Sub_SubProblems{$ProblemType_Init}{$Attr};
+                        $SubProblems{$ProblemType}{$Member_Name}{$Attr} = $Sub_SubChanges{$ProblemType_Init}{$Attr};
                     }
                 }
                 if(not isPublic(\%Type1_Pure, $Member_Pos))
@@ -12204,22 +12222,33 @@
                     next;
                 }
                 if($MemberType1_Id and $MemberType2_Id)
-                {# checking member type changes (replace)
-                    %Sub_SubProblems = mergeTypes($MemberType1_Id, $MemberType2_Id, $Level);
-                    foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
+                { # checking member type changes
+                    my $Sub_SubProblems = mergeTypes($MemberType1_Id, $MemberType2_Id, $Level);
+                    
+                    my %DupProblems = ();
+                    
+                    foreach my $Sub_SubProblemType (keys(%{$Sub_SubProblems}))
                     {
-                        foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
+                        foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems->{$Sub_SubProblemType}}))
                         {
-                            my $NewLocation = ($Sub_SubLocation)?$Member_Name."->".$Sub_SubLocation:$Member_Name;
-                            $SubProblems{$Sub_SubProblemType}{$NewLocation}{"IsInTypeInternals"}=1;
-                            foreach my $Attr (keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})) {
-                                $SubProblems{$Sub_SubProblemType}{$NewLocation}{$Attr} = $Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{$Attr};
+                            if(not defined $AllAffected)
+                            {
+                                if(defined $DupProblems{$Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation}}) {
+                                    next;
+                                }
                             }
-                            if($Sub_SubLocation!~/\-\>/) {
-                                $SubProblems{$Sub_SubProblemType}{$NewLocation}{"Start_Type_Name"} = $MemberType1_Name;
+                            
+                            my $NewLocation = ($Sub_SubLocation)?$Member_Name."->".$Sub_SubLocation:$Member_Name;
+                            $SubProblems{$Sub_SubProblemType}{$NewLocation} = $Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation};
+                            
+                            if(not defined $AllAffected)
+                            {
+                                $DupProblems{$Sub_SubProblems->{$Sub_SubProblemType}{$Sub_SubLocation}} = 1;
                             }
                         }
                     }
+                    
+                    %DupProblems = ();
                 }
             }
         }
@@ -12291,9 +12320,9 @@
             }
         }
     }
-    %{$Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id}} = %SubProblems;
+    
     pop(@RecurTypes);
-    return %SubProblems;
+    return ($Cache{"mergeTypes"}{$Level}{$Type1_Id}{$Type2_Id} = \%SubProblems);
 }
 
 sub isUnnamed($) {
@@ -13024,7 +13053,7 @@
                 and $CompleteSignature{1}{$Symbol}{"Const"})
                 {
                     my $Cid = $CompleteSignature{1}{$Symbol}{"Class"};
-                    %{$CompatProblems{$Level}{$Symbol}{"Removed_Const_Overload"}{$tr_name{$Symbol}}}=(
+                    %{$CompatProblems{$Level}{$Symbol}{"Removed_Const_Overload"}{"this"}}=(
                         "Type_Name"=>$TypeInfo{1}{$Cid}{"Name"},
                         "Target"=>get_Signature($Alt, 1));
                 }
@@ -13181,7 +13210,7 @@
 {
     my $Level = $_[0];
     my %SubProblems = ();
-
+    
     mergeBases($Level);
     
     my %AddedOverloads = ();
@@ -13331,18 +13360,18 @@
                 my $NewSym = $AddedOverloads{$Prefix}{$Overloads[0]};
                 if($CompleteSignature{1}{$Symbol}{"Constructor"})
                 {
-                    if($Symbol=~/(C1E|C2E)/)
+                    if($Symbol=~/(C[1-2][EI])/)
                     {
                         my $CtorType = $1;
-                        $NewSym=~s/(C1E|C2E)/$CtorType/g;
+                        $NewSym=~s/(C[1-2][EI])/$CtorType/g;
                     }
                 }
                 elsif($CompleteSignature{1}{$Symbol}{"Destructor"})
                 {
-                    if($Symbol=~/(D0E|D1E|D2E)/)
+                    if($Symbol=~/(D[0-2][EI])/)
                     {
                         my $DtorType = $1;
-                        $NewSym=~s/(D0E|D1E|D2E)/$DtorType/g;
+                        $NewSym=~s/(D[0-2][EI])/$DtorType/g;
                     }
                 }
                 my $NS1 = $CompleteSignature{1}{$Symbol}{"NameSpace"};
@@ -13401,6 +13430,8 @@
     }
     foreach my $Symbol (sort keys(%{$CompleteSignature{1}}))
     { # checking symbols
+        $CurrentSymbol = $Symbol;
+        
         my ($SN, $SS, $SV) = separate_symbol($Symbol);
         if($Level eq "Source")
         { # remove symbol version
@@ -13629,7 +13660,7 @@
                         }
                         %{$CompatProblems{$Level}{$Symbol}{$ProblemType}{showPos($ParamPos)." Parameter"}}=(
                             "Target"=>$PName,
-                            "Param_Pos"=>$ParamPos,
+                            "Param_Pos"=>adjustParamPos($ParamPos, $Symbol, 2),
                             "Param_Type"=>$PType2_Name,
                             "New_Signature"=>get_Signature($Symbol, 2)  );
                     }
@@ -13645,7 +13676,7 @@
                             {
                                 %{$CompatProblems{$Level}{$Symbol}{"Renamed_Parameter"}{showPos($ParamPos)." Parameter"}}=(
                                     "Target"=>$PName_Old,
-                                    "Param_Pos"=>$ParamPos,
+                                    "Param_Pos"=>adjustParamPos($ParamPos, $Symbol, 2),
                                     "Param_Type"=>$PType2_Name,
                                     "Old_Value"=>$PName_Old,
                                     "New_Value"=>$PName,
@@ -13660,7 +13691,7 @@
                             }
                             %{$CompatProblems{$Level}{$Symbol}{$ProblemType}{showPos($ParamPos)." Parameter"}}=(
                                 "Target"=>$PName,
-                                "Param_Pos"=>$ParamPos,
+                                "Param_Pos"=>adjustParamPos($ParamPos, $Symbol, 2),
                                 "Param_Type"=>$PType2_Name,
                                 "New_Signature"=>get_Signature($Symbol, 2)  );
                         }
@@ -13711,7 +13742,7 @@
                         }
                         %{$CompatProblems{$Level}{$Symbol}{$ProblemType}{showPos($ParamPos)." Parameter"}}=(
                             "Target"=>$PName,
-                            "Param_Pos"=>$ParamPos,
+                            "Param_Pos"=>adjustParamPos($ParamPos, $Symbol, 2),
                             "Param_Type"=>$PType1_Name,
                             "New_Signature"=>get_Signature($Symbol, 2)  );
                     }
@@ -13727,7 +13758,7 @@
                             {
                                 %{$CompatProblems{$Level}{$Symbol}{"Renamed_Parameter"}{showPos($ParamPos)." Parameter"}}=(
                                     "Target"=>$PName,
-                                    "Param_Pos"=>$ParamPos,
+                                    "Param_Pos"=>adjustParamPos($ParamPos, $Symbol, 2),
                                     "Param_Type"=>$PType1_Name,
                                     "Old_Value"=>$PName,
                                     "New_Value"=>$PName_New,
@@ -13742,7 +13773,7 @@
                             }
                             %{$CompatProblems{$Level}{$Symbol}{$ProblemType}{showPos($ParamPos)." Parameter"}}=(
                                 "Target"=>$PName,
-                                "Param_Pos"=>$ParamPos,
+                                "Param_Pos"=>adjustParamPos($ParamPos, $Symbol, 2),
                                 "Param_Type"=>$PType1_Name,
                                 "New_Signature"=>get_Signature($Symbol, 2)  );
                         }
@@ -13753,12 +13784,12 @@
         # checking return type
         my $ReturnType1_Id = $CompleteSignature{1}{$Symbol}{"Return"};
         my $ReturnType2_Id = $CompleteSignature{2}{$PSymbol}{"Return"};
-        %SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return", $Level);
+        my %RC_SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return", $Level);
         
-        foreach my $SubProblemType (keys(%SubProblems))
+        foreach my $SubProblemType (keys(%RC_SubProblems))
         {
-            my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
-            my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
+            my $New_Value = $RC_SubProblems{$SubProblemType}{"New_Value"};
+            my $Old_Value = $RC_SubProblems{$SubProblemType}{"Old_Value"};
             my %ProblemTypes = ();
             
             if($CompleteSignature{1}{$Symbol}{"Data"})
@@ -13920,13 +13951,15 @@
             
             foreach my $ProblemType (keys(%ProblemTypes))
             { # additional
-                @{$CompatProblems{$Level}{$Symbol}{$ProblemType}{"retval"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
+                $CompatProblems{$Level}{$Symbol}{$ProblemType}{"retval"} = $RC_SubProblems{$SubProblemType};
             }
         }
         if($ReturnType1_Id and $ReturnType2_Id)
         {
             @RecurTypes = ();
-            %SubProblems = mergeTypes($ReturnType1_Id, $ReturnType2_Id, $Level);
+            my $Sub_SubProblems = mergeTypes($ReturnType1_Id, $ReturnType2_Id, $Level);
+            
+            my $AddProblems = {};
             
             if($CompleteSignature{1}{$Symbol}{"Data"})
             {
@@ -13934,17 +13967,17 @@
                 {
                     if(get_PLevel($ReturnType1_Id, 1)==0)
                     {
-                        foreach my $SubProblemType (keys(%SubProblems))
+                        foreach my $SubProblemType (keys(%{$Sub_SubProblems}))
                         { # add "Global_Data_Size" problem
-                            my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
-                            my $Old_Value = $SubProblems{$SubProblemType}{"Old_Value"};
+                            my $New_Value = $Sub_SubProblems->{$SubProblemType}{"New_Value"};
+                            my $Old_Value = $Sub_SubProblems->{$SubProblemType}{"Old_Value"};
                             if($SubProblemType eq "DataType_Size")
                             { # add a new problem
-                                %{$SubProblems{"Global_Data_Size"}} = %{$SubProblems{$SubProblemType}};
+                                $AddProblems->{"Global_Data_Size"} = $Sub_SubProblems->{$SubProblemType};
                             }
                         }
                     }
-                    if(not defined $SubProblems{"Global_Data_Size"})
+                    if(not defined $AddProblems->{"Global_Data_Size"})
                     {
                         if(defined $GlobalDataObject{1}{$Symbol}
                         and defined $GlobalDataObject{2}{$Symbol})
@@ -13953,25 +13986,30 @@
                             my $New_Size = $GlobalDataObject{2}{$Symbol};
                             if($Old_Size!=$New_Size)
                             {
-                                %{$SubProblems{"Global_Data_Size"}{"retval"}} = (
+                                $AddProblems->{"Global_Data_Size"}{"retval"} = {
                                     "Old_Size"=>$Old_Size*$BYTE_SIZE,
-                                    "New_Size"=>$New_Size*$BYTE_SIZE );
+                                    "New_Size"=>$New_Size*$BYTE_SIZE };
                             }
                         }
                     }
                 }
             }
-            foreach my $SubProblemType (keys(%SubProblems))
+            
+            foreach my $SubProblemType (keys(%{$AddProblems}))
             {
-                foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
+                foreach my $SubLocation (keys(%{$AddProblems->{$SubProblemType}}))
                 {
                     my $NewLocation = ($SubLocation)?"retval->".$SubLocation:"retval";
-                    %{$CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation}}=(
-                        "Return_Type_Name"=>$TypeInfo{1}{$ReturnType1_Id}{"Name"} );
-                    @{$CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
-                    if($SubLocation!~/\-\>/) {
-                        $CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = $TypeInfo{1}{$ReturnType1_Id}{"Name"};
-                    }
+                    $CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation} = $AddProblems->{$SubProblemType}{$SubLocation};
+                }
+            }
+            
+            foreach my $SubProblemType (keys(%{$Sub_SubProblems}))
+            {
+                foreach my $SubLocation (keys(%{$Sub_SubProblems->{$SubProblemType}}))
+                {
+                    my $NewLocation = ($SubLocation)?"retval->".$SubLocation:"retval";
+                    $CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation} = $Sub_SubProblems->{$SubProblemType}{$SubLocation};
                 }
             }
         }
@@ -13987,18 +14025,13 @@
             if($ThisPtr1_Id and $ThisPtr2_Id)
             {
                 @RecurTypes = ();
-                %SubProblems = mergeTypes($ThisPtr1_Id, $ThisPtr2_Id, $Level);
-                foreach my $SubProblemType (keys(%SubProblems))
+                my $Sub_SubProblems = mergeTypes($ThisPtr1_Id, $ThisPtr2_Id, $Level);
+                foreach my $SubProblemType (keys(%{$Sub_SubProblems}))
                 {
-                    foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
+                    foreach my $SubLocation (keys(%{$Sub_SubProblems->{$SubProblemType}}))
                     {
                         my $NewLocation = ($SubLocation)?"this->".$SubLocation:"this";
-                        %{$CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation}}=(
-                            "Object_Type_Name"=>$TypeInfo{1}{$ObjTId1}{"Name"} );
-                        @{$CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
-                        if($SubLocation!~/\-\>/) {
-                            $CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = $TypeInfo{1}{$ObjTId1}{"Name"};
-                        }
+                        $CompatProblems{$Level}{$Symbol}{$SubProblemType}{$NewLocation} = $Sub_SubProblems->{$SubProblemType}{$SubLocation};
                     }
                 }
             }
@@ -14186,7 +14219,7 @@
         return;
     }
     
-    if(index($Symbol, "_Z")==0) 
+    if($Symbol=~/\A(_Z|\?)/) 
     { # do not merge "this" 
         if($PName1 eq "this" or $PName2 eq "this") { 
             return; 
@@ -14208,14 +14241,14 @@
             {
                 %{$CompatProblems{$Level}{$Symbol}{"Parameter_Became_Non_Register"}{$Parameter_Location}}=(
                     "Target"=>$PName1,
-                    "Param_Pos"=>$ParamPos1  );
+                    "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1)  );
             }
             elsif(not $CompleteSignature{1}{$Symbol}{"Param"}{$ParamPos1}{"reg"}
             and $CompleteSignature{2}{$PSymbol}{"Param"}{$ParamPos2}{"reg"})
             {
                 %{$CompatProblems{$Level}{$Symbol}{"Parameter_Became_Register"}{$Parameter_Location}}=(
                     "Target"=>$PName1,
-                    "Param_Pos"=>$ParamPos1  );
+                    "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1)  );
             }
         }
         
@@ -14232,7 +14265,7 @@
                     {
                         %{$CompatProblems{$Level}{$Symbol}{"Parameter_Changed_Register"}{$Parameter_Location}}=(
                             "Target"=>$PName1,
-                            "Param_Pos"=>$ParamPos1,
+                            "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                             "Old_Value"=>$Old_Regs,
                             "New_Value"=>$New_Regs  );
                     }
@@ -14241,14 +14274,14 @@
                 {
                     %{$CompatProblems{$Level}{$Symbol}{"Parameter_From_Register"}{$Parameter_Location}}=(
                         "Target"=>$PName1,
-                        "Param_Pos"=>$ParamPos1,
+                        "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                         "Old_Value"=>$Old_Regs  );
                 }
                 elsif(not $Old_Regs and $New_Regs)
                 {
                     %{$CompatProblems{$Level}{$Symbol}{"Parameter_To_Register"}{$Parameter_Location}}=(
                         "Target"=>$PName1,
-                        "Param_Pos"=>$ParamPos1,
+                        "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                         "New_Value"=>$New_Regs  );
                 }
                 if((my $Old_Offset = $CompleteSignature{1}{$Symbol}{"Param"}{$ParamPos1}{"offset"}) ne ""
@@ -14256,11 +14289,20 @@
                 {
                     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  );
+                        my $Start1 = $CompleteSignature{1}{$Symbol}{"Param"}{0}{"offset"};
+                        my $Start2 = $CompleteSignature{2}{$Symbol}{"Param"}{0}{"offset"};
+                        
+                        $Old_Offset = $Old_Offset - $Start1;
+                        $New_Offset = $New_Offset - $Start2;
+                        
+                        if($Old_Offset ne $New_Offset)
+                        {
+                            %{$CompatProblems{$Level}{$Symbol}{"Parameter_Changed_Offset"}{$Parameter_Location}}=(
+                                "Target"=>$PName1,
+                                "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
+                                "Old_Value"=>$Old_Offset,
+                                "New_Value"=>$New_Offset  );
+                        }
                     }
                 }
             }
@@ -14304,7 +14346,7 @@
                 { # FIXME: how to distinguish "0" and 0 (NULL)
                     %{$CompatProblems{$Level}{$Symbol}{"Parameter_Default_Value_Changed"}{$Parameter_Location}}=(
                         "Target"=>$PName1,
-                        "Param_Pos"=>$ParamPos1,
+                        "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                         "Old_Value"=>$Value_Old,
                         "New_Value"=>$Value_New  );
                 }
@@ -14313,7 +14355,7 @@
             {
                 %{$CompatProblems{$Level}{$Symbol}{"Parameter_Default_Value_Removed"}{$Parameter_Location}}=(
                     "Target"=>$PName1,
-                    "Param_Pos"=>$ParamPos1,
+                    "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                     "Old_Value"=>$Value_Old  );
             }
         }
@@ -14322,7 +14364,7 @@
             $Value_New = showVal($Value_New, $PType2_Id, 2);
             %{$CompatProblems{$Level}{$Symbol}{"Parameter_Default_Value_Added"}{$Parameter_Location}}=(
                 "Target"=>$PName1,
-                "Param_Pos"=>$ParamPos1,
+                "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                 "New_Value"=>$Value_New  );
         }
     }
@@ -14335,7 +14377,7 @@
         { # except unnamed "..." value list (Id=-1)
             %{$CompatProblems{$Level}{$Symbol}{"Renamed_Parameter"}{showPos($ParamPos1)." Parameter"}}=(
                 "Target"=>$PName1,
-                "Param_Pos"=>$ParamPos1,
+                "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
                 "Param_Type"=>$TypeInfo{1}{$PType1_Id}{"Name"},
                 "Old_Value"=>$PName1,
                 "New_Value"=>$PName2,
@@ -14345,6 +14387,7 @@
     
     # checking type change (replace)
     my %SubProblems = detectTypeChange($PType1_Id, $PType2_Id, "Parameter", $Level);
+    
     foreach my $SubProblemType (keys(%SubProblems))
     { # add new problems, remove false alarms
         my $New_Value = $SubProblems{$SubProblemType}{"New_Value"};
@@ -14482,35 +14525,29 @@
         }
         %{$CompatProblems{$Level}{$Symbol}{$NewProblemType}{$Parameter_Location}}=(
             "Target"=>$PName1,
-            "Param_Pos"=>$ParamPos1,
+            "Param_Pos"=>adjustParamPos($ParamPos1, $Symbol, 1),
             "New_Signature"=>get_Signature($Symbol, 2) );
         @{$CompatProblems{$Level}{$Symbol}{$NewProblemType}{$Parameter_Location}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
     }
+    
     @RecurTypes = ();
+    
     # checking type definition changes
-    my %SubProblems_Merge = mergeTypes($PType1_Id, $PType2_Id, $Level);
-    foreach my $SubProblemType (keys(%SubProblems_Merge))
+    my $Sub_SubProblems = mergeTypes($PType1_Id, $PType2_Id, $Level);
+    foreach my $SubProblemType (keys(%{$Sub_SubProblems}))
     {
-        foreach my $SubLocation (keys(%{$SubProblems_Merge{$SubProblemType}}))
+        foreach my $SubLocation (keys(%{$Sub_SubProblems->{$SubProblemType}}))
         {
             my $NewProblemType = $SubProblemType;
             if($SubProblemType eq "DataType_Size")
             {
-                my $InitialType_Type = $SubProblems_Merge{$SubProblemType}{$SubLocation}{"InitialType_Type"};
-                if($InitialType_Type!~/\A(Pointer|Ref)\Z/ and $SubLocation!~/\-\>/)
+                if($Type1{"Type"}!~/\A(Pointer|Ref)\Z/ and $SubLocation!~/\-\>/)
                 { # stack has been affected
                     $NewProblemType = "DataType_Size_And_Stack";
                 }
             }
             my $NewLocation = ($SubLocation)?$Parameter_Location."->".$SubLocation:$Parameter_Location;
-            %{$CompatProblems{$Level}{$Symbol}{$NewProblemType}{$NewLocation}}=(
-                "Param_Type"=>$TypeInfo{1}{$PType1_Id}{"Name"},
-                "Param_Pos"=>$ParamPos1,
-                "Param_Name"=>$PName1  );
-            @{$CompatProblems{$Level}{$Symbol}{$NewProblemType}{$NewLocation}}{keys(%{$SubProblems_Merge{$SubProblemType}{$SubLocation}})} = values %{$SubProblems_Merge{$SubProblemType}{$SubLocation}};
-            if($SubLocation!~/\-\>/) {
-                $CompatProblems{$Level}{$Symbol}{$NewProblemType}{$NewLocation}{"Start_Type_Name"} = $TypeInfo{1}{$PType1_Id}{"Name"};
-            }
+            $CompatProblems{$Level}{$Symbol}{$NewProblemType}{$NewLocation} = $Sub_SubProblems->{$SubProblemType}{$SubLocation};
         }
     }
 }
@@ -14766,8 +14803,7 @@
                     "Old_Value"=>$Type1_Base{"Name"},
                     "New_Value"=>$Type2_Base{"Name"},
                     "Old_Size"=>$Type1_Base{"Size"}*$BYTE_SIZE,
-                    "New_Size"=>$Type2_Base{"Size"}*$BYTE_SIZE,
-                    "InitialType_Type"=>$Type1_Pure{"Type"});
+                    "New_Size"=>$Type2_Base{"Size"}*$BYTE_SIZE);
             }
             else
             {
@@ -14777,8 +14813,7 @@
                         "Old_Value"=>$Type1_Base{"Name"},
                         "New_Value"=>$Type2_Base{"Name"},
                         "Old_Size"=>$Type1_Base{"Size"}*$BYTE_SIZE,
-                        "New_Size"=>$Type2_Base{"Size"}*$BYTE_SIZE,
-                        "InitialType_Type"=>$Type1_Pure{"Type"});
+                        "New_Size"=>$Type2_Base{"Size"}*$BYTE_SIZE);
                 }
                 elsif(tNameLock($Type1_Base{"Tid"}, $Type2_Base{"Tid"}))
                 {
@@ -14786,8 +14821,7 @@
                         "Old_Value"=>$Type1_Base{"Name"},
                         "New_Value"=>$Type2_Base{"Name"},
                         "Old_Size"=>$Type1_Base{"Size"}*$BYTE_SIZE,
-                        "New_Size"=>$Type2_Base{"Size"}*$BYTE_SIZE,
-                        "InitialType_Type"=>$Type1_Pure{"Type"});
+                        "New_Size"=>$Type2_Base{"Size"}*$BYTE_SIZE);
                 }
             }
         }
@@ -14801,16 +14835,14 @@
             {
                 %{$LocalProblems{"Return_Type_From_Void"}}=(
                     "New_Value"=>$Type2{"Name"},
-                    "New_Size"=>$Type2{"Size"}*$BYTE_SIZE,
-                    "InitialType_Type"=>$Type1_Pure{"Type"});
+                    "New_Size"=>$Type2{"Size"}*$BYTE_SIZE);
             }
             elsif($Prefix eq "Return"
             and $Type2_Pure{"Name"} eq "void")
             {
                 %{$LocalProblems{"Return_Type_Became_Void"}}=(
                     "Old_Value"=>$Type1{"Name"},
-                    "Old_Size"=>$Type1{"Size"}*$BYTE_SIZE,
-                    "InitialType_Type"=>$Type1_Pure{"Type"});
+                    "Old_Size"=>$Type1{"Size"}*$BYTE_SIZE);
             }
             else
             {
@@ -14822,8 +14854,7 @@
                         "Old_Value"=>$Type1{"Name"},
                         "New_Value"=>$Type2{"Name"},
                         "Old_Size"=>$Type1{"Size"}*$BYTE_SIZE,
-                        "New_Size"=>$Type2{"Size"}*$BYTE_SIZE,
-                        "InitialType_Type"=>$Type1_Pure{"Type"});
+                        "New_Size"=>$Type2{"Size"}*$BYTE_SIZE);
                 }
                 else
                 {
@@ -14833,8 +14864,7 @@
                             "Old_Value"=>$Type1{"Name"},
                             "New_Value"=>$Type2{"Name"},
                             "Old_Size"=>$Type1{"Size"}*$BYTE_SIZE,
-                            "New_Size"=>$Type2{"Size"}*$BYTE_SIZE,
-                            "InitialType_Type"=>$Type1_Pure{"Type"});
+                            "New_Size"=>$Type2{"Size"}*$BYTE_SIZE);
                     }
                     elsif(tNameLock($Type1_Id, $Type2_Id))
                     { # FIXME: correct this condition
@@ -14842,8 +14872,7 @@
                             "Old_Value"=>$Type1{"Name"},
                             "New_Value"=>$Type2{"Name"},
                             "Old_Size"=>$Type1{"Size"}*$BYTE_SIZE,
-                            "New_Size"=>$Type2{"Size"}*$BYTE_SIZE,
-                            "InitialType_Type"=>$Type1_Pure{"Type"});
+                            "New_Size"=>$Type2{"Size"}*$BYTE_SIZE);
                     }
                 }
             }
@@ -15581,7 +15610,7 @@
             foreach my $Location (keys(%{$TypeChanges->{$Type_Name}{$Kind}}))
             {
                 my $Target = $TypeChanges->{$Type_Name}{$Kind}{$Location}{"Target"};
-                my $Priority = getProblemSeverity($Level, $Kind);
+                my $Priority = $CompatRules{$Level}{$Kind}{"Severity"};
                 next if($Priority ne $TargetPriority);
                 if($Kinds_Target{$Kind}{$Target}) {
                     next;
@@ -15646,7 +15675,7 @@
             {
                 foreach my $Location (sort keys(%{$CompatProblems{$Level}{$Interface}{$Kind}}))
                 {
-                    my $Priority = getProblemSeverity($Level, $Kind);
+                    my $Priority = $CompatRules{$Level}{$Kind}{"Severity"};
                     if($Kind eq "Added_Symbol") {
                         $Added += 1;
                     }
@@ -15685,21 +15714,43 @@
         {
             if($CompatRules{$Level}{$Kind}{"Kind"} eq "Types")
             {
-                foreach my $Location (sort {cmp_locations($b, $a)} sort keys(%{$CompatProblems{$Level}{$Interface}{$Kind}}))
+                foreach my $Location (sort {cmpLocations($b, $a)} sort keys(%{$CompatProblems{$Level}{$Interface}{$Kind}}))
                 {
                     my $Type_Name = $CompatProblems{$Level}{$Interface}{$Kind}{$Location}{"Type_Name"};
                     my $Target = $CompatProblems{$Level}{$Interface}{$Kind}{$Location}{"Target"};
-                    my $Priority = getProblemSeverity($Level, $Kind);
-                    if(cmpSeverities($Type_MaxSeverity{$Level}{$Type_Name}{$Kind}{$Target}, $Priority))
+                    my $Priority = $CompatRules{$Level}{$Kind}{"Severity"};
+                    my $MaxSeverity = $Type_MaxSeverity{$Level}{$Type_Name}{$Kind}{$Target};
+                    
+                    if($MaxSeverity and $Severity_Val{$MaxSeverity}>$Severity_Val{$Priority})
                     { # select a problem with the highest priority
                         next;
                     }
+                    
                     if(($Priority ne "Low" or $StrictCompat)
-                    and $Priority ne "Safe") {
-                        $TotalAffected{$Level}{$Interface} = maxSeverity($TotalAffected{$Level}{$Interface}, $Priority);
+                    and $Priority ne "Safe")
+                    {
+                        if(defined $TotalAffected{$Level}{$Interface})
+                        {
+                            if($Severity_Val{$Priority}>$Severity_Val{$TotalAffected{$Level}{$Interface}}) {
+                                $TotalAffected{$Level}{$Interface} = $Priority;
+                            }
+                        }
+                        else {
+                            $TotalAffected{$Level}{$Interface} = $Priority;
+                        }
                     }
-                    %{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Level}{$Interface}{$Kind}{$Location}};
-                    $Type_MaxSeverity{$Level}{$Type_Name}{$Kind}{$Target} = maxSeverity($Type_MaxSeverity{$Level}{$Type_Name}{$Kind}{$Target}, $Priority);
+                    
+                    $TypeChanges{$Type_Name}{$Kind}{$Location} = $CompatProblems{$Level}{$Interface}{$Kind}{$Location};
+                    
+                    if($MaxSeverity)
+                    {
+                        if($Severity_Val{$Priority}>$Severity_Val{$MaxSeverity}) {
+                            $Type_MaxSeverity{$Level}{$Type_Name}{$Kind}{$Target} = $Priority;
+                        }
+                    }
+                    else {
+                        $Type_MaxSeverity{$Level}{$Type_Name}{$Kind}{$Target} = $Priority;
+                    }
                 }
             }
         }
@@ -15710,6 +15761,8 @@
     $T_Problems_Low = get_TypeProblems_Count(\%TypeChanges, "Low", $Level);
     $T_Other = get_TypeProblems_Count(\%TypeChanges, "Safe", $Level);
     
+    %TypeChanges = (); # free memory
+    
     if($CheckObjectsOnly)
     { # only removed exported symbols
         $RESULT{$Level}{"Affected"} = $Removed*100/keys(%{$Symbol_Library{1}});
@@ -15756,7 +15809,7 @@
     {
         foreach my $Kind (keys(%{$CompatProblems_Constants{$Level}{$Constant}}))
         {
-            my $Severity = getProblemSeverity($Level, $Kind);
+            my $Severity = $CompatRules{$Level}{$Kind}{"Severity"};
             if($Severity eq "Safe")
             {
                 $C_Other+=1;
@@ -16189,7 +16242,7 @@
             if(not defined $CompatRules{$Level}{$Kind}) {
                 next;
             }
-            if($TargetSeverity ne getProblemSeverity($Level, $Kind)) {
+            if($TargetSeverity ne $CompatRules{$Level}{$Kind}{"Severity"}) {
                 next;
             }
             $ReportMap{$Header}{$Constant}{$Kind} = 1;
@@ -16685,7 +16738,7 @@
                 %{$SymbolChanges{$Symbol}{$Kind}} = %{$CompatProblems{$Level}{$Symbol}{$Kind}};
                 foreach my $Location (sort keys(%{$SymbolChanges{$Symbol}{$Kind}}))
                 {
-                    my $Priority = getProblemSeverity($Level, $Kind);
+                    my $Priority = $CompatRules{$Level}{$Kind}{"Severity"};
                     if($Priority ne $TargetSeverity) {
                         delete($SymbolChanges{$Symbol}{$Kind}{$Location});
                     }
@@ -16719,6 +16772,7 @@
                         {
                             my %Problem = %{$SymbolChanges{$Symbol}{$Kind}{$Location}};
                             $Problem{"Param_Pos"} = showPos($Problem{"Param_Pos"});
+                            
                             $INTERFACE_PROBLEMS .= "        <problem id=\"$Kind\">\n";
                             my $Change = $CompatRules{$Level}{$Kind}{"Change"};
                             $INTERFACE_PROBLEMS .= "          <change".getXmlParams($Change, \%Problem).">$Change</change>\n";
@@ -16830,11 +16884,11 @@
         {
             if($CompatRules{$Level}{$Kind}{"Kind"} eq "Types")
             {
-                foreach my $Location (sort {cmp_locations($b, $a)} sort keys(%{$CompatProblems{$Level}{$Interface}{$Kind}}))
+                foreach my $Location (sort {cmpLocations($b, $a)} sort keys(%{$CompatProblems{$Level}{$Interface}{$Kind}}))
                 {
                     my $TypeName = $CompatProblems{$Level}{$Interface}{$Kind}{$Location}{"Type_Name"};
                     my $Target = $CompatProblems{$Level}{$Interface}{$Kind}{$Location}{"Target"};
-                    my $Severity = getProblemSeverity($Level, $Kind);
+                    my $Severity = $CompatRules{$Level}{$Kind}{"Severity"};
                     if($Severity eq "Safe"
                     and $TargetSeverity ne "Safe") {
                         next;
@@ -16855,9 +16909,9 @@
         my %Kinds_Target = ();
         foreach my $Kind (sort keys(%{$TypeChanges{$TypeName}}))
         {
-            foreach my $Location (sort {cmp_locations($b, $a)} sort keys(%{$TypeChanges{$TypeName}{$Kind}}))
+            foreach my $Location (sort {cmpLocations($b, $a)} sort keys(%{$TypeChanges{$TypeName}{$Kind}}))
             {
-                my $Severity = getProblemSeverity($Level, $Kind);
+                my $Severity = $CompatRules{$Level}{$Kind}{"Severity"};
                 if($Severity ne $TargetSeverity)
                 { # other priority
                     delete($TypeChanges{$TypeName}{$Kind}{$Location});
@@ -16893,7 +16947,7 @@
                 $TYPE_PROBLEMS .= "    <type name=\"".xmlSpecChars($TypeName)."\">\n";
                 foreach my $Kind (sort {$b=~/Size/ <=> $a=~/Size/} sort keys(%{$TypeChanges{$TypeName}}))
                 {
-                    foreach my $Location (sort {cmp_locations($b, $a)} sort keys(%{$TypeChanges{$TypeName}{$Kind}}))
+                    foreach my $Location (sort {cmpLocations($b, $a)} sort keys(%{$TypeChanges{$TypeName}{$Kind}}))
                     {
                         my %Problem = %{$TypeChanges{$TypeName}{$Kind}{$Location}};
                         $TYPE_PROBLEMS .= "      <problem id=\"$Kind\">\n";
@@ -16935,7 +16989,7 @@
                     my $TYPE_REPORT = "";
                     foreach my $Kind (sort {$b=~/Size/ <=> $a=~/Size/} sort keys(%{$TypeChanges{$TypeName}}))
                     {
-                        foreach my $Location (sort {cmp_locations($b, $a)} sort keys(%{$TypeChanges{$TypeName}{$Kind}}))
+                        foreach my $Location (sort {cmpLocations($b, $a)} sort keys(%{$TypeChanges{$TypeName}{$Kind}}))
                         {
                             my %Problem = %{$TypeChanges{$TypeName}{$Kind}{$Location}};
                             if(my $Change = applyMacroses($Level, $Kind, $CompatRules{$Level}{$Kind}{"Change"}, \%Problem))
@@ -17111,13 +17165,65 @@
     return $VEntry;
 }
 
+sub adjustParamPos($$$)
+{
+    my ($Pos, $Symbol, $LibVersion) = @_;
+    if(defined $CompleteSignature{$LibVersion}{$Symbol})
+    {
+        if(not $CompleteSignature{$LibVersion}{$Symbol}{"Static"}
+        and $CompleteSignature{$LibVersion}{$Symbol}{"Class"})
+        {
+            return $Pos-1;
+        }
+        
+        return $Pos;
+    }
+    
+    return undef;
+}
+
+sub getParamPos($$$)
+{
+    my ($Name, $Symbol, $LibVersion) = @_;
+    
+    if(defined $CompleteSignature{$LibVersion}{$Symbol}
+    and defined $CompleteSignature{$LibVersion}{$Symbol}{"Param"})
+    {
+        my $Info = $CompleteSignature{$LibVersion}{$Symbol};
+        foreach (keys(%{$Info->{"Param"}}))
+        {
+            if($Info->{"Param"}{$_}{"name"} eq $Name)
+            {
+                return $_;
+            }
+        }
+    }
+    
+    return undef;
+}
+
+sub getParamName($)
+{
+    my $Loc = $_[0];
+    $Loc=~s/\->.*//g;
+    return $Loc;
+}
+
 sub getAffectedSymbols($$$$)
 {
     my ($Level, $Target_TypeName, $Kinds_Locations, $Syms) = @_;
     my $LIMIT = 1000;
-    if($#{$Syms}>=10000)
-    { # reduce size of the report
-        $LIMIT = 10;
+    
+    if(defined $AffectLimit)
+    {
+        $LIMIT = $AffectLimit;
+    }
+    else
+    {
+        if($#{$Syms}>=10000)
+        { # reduce size of the report
+            $LIMIT = 10;
+        }
     }
     my %SProblems = ();
     foreach my $Symbol (@{$Syms})
@@ -17125,7 +17231,7 @@
         if(keys(%SProblems)>$LIMIT) {
             last;
         }
-        if(($Symbol=~/C2E|D2E|D0E/))
+        if(($Symbol=~/(C2|D2|D0)[EI]/))
         { # duplicated problems for C2 constructors, D2 and D0 destructors
             next;
         }
@@ -17153,9 +17259,10 @@
                 my $Type_Name = $CompatProblems{$Level}{$Symbol}{$Kind}{$Location}{"Type_Name"};
                 next if($Type_Name ne $Target_TypeName);
                 
-                my $Position = $CompatProblems{$Level}{$Symbol}{$Kind}{$Location}{"Param_Pos"};
-                my $Param_Name = $CompatProblems{$Level}{$Symbol}{$Kind}{$Location}{"Param_Name"};
-                my $Severity = getProblemSeverity($Level, $Kind);
+                my $PName = getParamName($Location);
+                my $PPos = adjustParamPos(getParamPos($PName, $Symbol, 1), $Symbol, 1);
+                
+                my $Severity = $CompatRules{$Level}{$Kind}{"Severity"};
                 my $Path_Length = 0;
                 my $ProblemLocation = $Location;
                 if($Type_Name) {
@@ -17165,17 +17272,17 @@
                     $Path_Length += 1;
                 }
                 if($MinPath_Length==-1 or ($Path_Length<=$MinPath_Length and $Severity_Val{$Severity}>$Severity_Max)
-                or (cmp_locations($ProblemLocation, $ProblemLocation_Last) and $Severity_Val{$Severity}==$Severity_Max))
+                or (cmpLocations($ProblemLocation, $ProblemLocation_Last) and $Severity_Val{$Severity}==$Severity_Max))
                 {
                     $MinPath_Length = $Path_Length;
                     $Severity_Max = $Severity_Val{$Severity};
                     $ProblemLocation_Last = $ProblemLocation;
                     %{$SProblems{$Symbol}} = (
-                        "Descr"=>getAffectDescription($Level, $Symbol, $Kind, $Location),
+                        "Descr"=>getAffectDesc($Level, $Symbol, $Kind, $Location),
                         "Severity_Max"=>$Severity_Max,
                         "Signature"=>$Signature,
-                        "Position"=>$Position,
-                        "Param_Name"=>$Param_Name,
+                        "Position"=>$PPos,
+                        "Param_Name"=>$PName,
                         "Location"=>$Location
                     );
                 }
@@ -17236,37 +17343,46 @@
     return $Affected;
 }
 
-sub cmp_locations($$)
+sub cmpLocations($$)
 {
     my ($L1, $L2) = @_;
-    if($L2=~/\b(retval|this)\b/
-    and $L1!~/\b(retval|this)\b/ and $L1!~/\-\>/) {
-        return 1;
-    }
-    if($L2=~/\b(retval|this)\b/ and $L2=~/\-\>/
-    and $L1!~/\b(retval|this)\b/ and $L1=~/\-\>/) {
-        return 1;
+    if($L2=~/\A(retval|this)\b/
+    and $L1!~/\A(retval|this)\b/)
+    {
+        if($L1!~/\-\>/) {
+            return 1;
+        }
+        elsif($L2=~/\-\>/) {
+            return 1;
+        }
     }
     return 0;
 }
 
-sub getAffectDescription($$$$)
+sub getAffectDesc($$$$)
 {
     my ($Level, $Symbol, $Kind, $Location) = @_;
+    
     my %Problem = %{$CompatProblems{$Level}{$Symbol}{$Kind}{$Location}};
-    my $PPos = showPos($Problem{"Param_Pos"});
+    
+    my $Location_I = $Location;
+    $Location=~s/\A(.*)\-\>(.+?)\Z/$1/; # without the latest affected field
+    
     my @Sentence = ();
-    $Location=~s/\A(.*)\-\>.+?\Z/$1/;
+    
     if($Kind eq "Overridden_Virtual_Method"
     or $Kind eq "Overridden_Virtual_Method_B") {
         push(@Sentence, "The method '".$Problem{"New_Value"}."' will be called instead of this method.");
     }
     elsif($CompatRules{$Level}{$Kind}{"Kind"} eq "Types")
     {
+        my %SymInfo = %{$CompleteSignature{1}{$Symbol}};
+        
         if($Location eq "this" or $Kind=~/(\A|_)Virtual(_|\Z)/)
         {
-            my $METHOD_TYPE = $CompleteSignature{1}{$Symbol}{"Constructor"}?"constructor":"method";
-            my $ClassName = $TypeInfo{1}{$CompleteSignature{1}{$Symbol}{"Class"}}{"Name"};
+            my $METHOD_TYPE = $SymInfo{"Constructor"}?"constructor":"method";
+            my $ClassName = $TypeInfo{1}{$SymInfo{"Class"}}{"Name"};
+            
             if($ClassName eq $Problem{"Type_Name"}) {
                 push(@Sentence, "This $METHOD_TYPE is from \'".$Problem{"Type_Name"}."\' class.");
             }
@@ -17276,63 +17392,81 @@
         }
         else
         {
+            my $TypeID = undef;
+            
             if($Location=~/retval/)
             { # return value
-                if($Location=~/\-\>/) {
+                if(index($Location, "->")!=-1) {
                     push(@Sentence, "Field \'".$Location."\' in return value");
                 }
                 else {
                     push(@Sentence, "Return value");
                 }
-                if(my $Init = $Problem{"InitialType_Type"})
-                {
-                    if($Init eq "Pointer") {
-                        push(@Sentence, "(pointer)");
-                    }
-                    elsif($Init eq "Ref") {
-                        push(@Sentence, "(reference)");
-                    }
-                }
+                
+                $TypeID = $SymInfo{"Return"};
             }
             elsif($Location=~/this/)
             { # "this" pointer
-                if($Location=~/\-\>/) {
+                if(index($Location, "->")!=-1) {
                     push(@Sentence, "Field \'".$Location."\' in the object of this method");
                 }
                 else {
                     push(@Sentence, "\'this\' pointer");
                 }
+                
+                $TypeID = $SymInfo{"Class"};
             }
             else
             { # parameters
-                if($Location=~/\-\>/) {
-                    push(@Sentence, "Field \'".$Location."\' in $PPos parameter");
+            
+                my $PName = getParamName($Location);
+                my $PPos = getParamPos($PName, $Symbol, 1);
+            
+                if(index($Location, "->")!=-1) {
+                    push(@Sentence, "Field \'".$Location."\' in ".showPos(adjustParamPos($PPos, $Symbol, 1))." parameter");
                 }
                 else {
-                    push(@Sentence, "$PPos parameter");
+                    push(@Sentence, showPos(adjustParamPos($PPos, $Symbol, 1))." parameter");
                 }
-                if($Problem{"Param_Name"}) {
-                    push(@Sentence, "\'".$Problem{"Param_Name"}."\'");
+                if($PName) {
+                    push(@Sentence, "\'".$PName."\'");
                 }
-                if(my $Init = $Problem{"InitialType_Type"})
+                
+                $TypeID = $SymInfo{"Param"}{$PPos}{"type"};
+            }
+            
+            if($Location!~/this/)
+            {
+                if(my %PureType = get_PureType($TypeID, $TypeInfo{1}))
                 {
-                    if($Init eq "Pointer") {
+                    if($PureType{"Type"} eq "Pointer") {
                         push(@Sentence, "(pointer)");
                     }
-                    elsif($Init eq "Ref") {
+                    elsif($PureType{"Type"} eq "Ref") {
                         push(@Sentence, "(reference)");
                     }
                 }
             }
+            
             if($Location eq "this") {
                 push(@Sentence, "has base type \'".$Problem{"Type_Name"}."\'.");
             }
-            elsif(defined $Problem{"Start_Type_Name"}
-            and $Problem{"Start_Type_Name"} eq $Problem{"Type_Name"}) {
-                push(@Sentence, "has type \'".$Problem{"Type_Name"}."\'.");
-            }
-            else {
-                push(@Sentence, "has base type \'".$Problem{"Type_Name"}."\'.");
+            else
+            {
+                my $Location_T = $Location;
+                $Location_T=~s/\A\w+(\->|\Z)//; # location in type
+                
+                my $TypeID_Problem = $TypeID;
+                if($Location_T) {
+                    $TypeID_Problem = getFieldType($Location_T, $TypeID, 1);
+                }
+                
+                if($TypeInfo{1}{$TypeID_Problem}{"Name"} eq $Problem{"Type_Name"}) {
+                    push(@Sentence, "has type \'".$Problem{"Type_Name"}."\'.");
+                }
+                else {
+                    push(@Sentence, "has base type \'".$Problem{"Type_Name"}."\'.");
+                }
             }
         }
     }
@@ -17342,6 +17476,29 @@
     return join(" ", @Sentence);
 }
 
+sub getFieldType($$$)
+{
+    my ($Location, $TypeId, $LibVersion) = @_;
+    
+    my @Fields = split("->", $Location);
+    
+    foreach my $Name (@Fields)
+    {
+        my %Info = get_BaseType($TypeId, $LibVersion);
+        
+        foreach my $Pos (keys(%{$Info{"Memb"}}))
+        {
+            if($Info{"Memb"}{$Pos}{"name"} eq $Name)
+            {
+                $TypeId = $Info{"Memb"}{$Pos}{"type"};
+                last;
+            }
+        }
+    }
+    
+    return $TypeId;
+}
+
 sub get_XmlSign($$)
 {
     my ($Symbol, $LibVersion) = @_;
@@ -18658,7 +18815,7 @@
         if(not $ReadelfCmd) {
             exitStatus("Not_Found", "can't find \"readelf\"");
         }
-        open(APP, "$ReadelfCmd -WhlSsdA \"$Path\" 2>\"$TMP_DIR/null\" |");
+        open(APP, "$ReadelfCmd -Ws \"$Path\" 2>\"$TMP_DIR/null\" |");
         my $symtab = undef; # indicates that we are processing 'symtab' section of 'readelf' output
         while(<APP>)
         {
@@ -19003,6 +19160,7 @@
             }
         }
         close(LIB);
+        
         if($Deps)
         {
             if($LIB_TYPE eq "dynamic")
@@ -19026,16 +19184,16 @@
         if(not $ReadelfCmd) {
             exitStatus("Not_Found", "can't find \"readelf\"");
         }
-        $ReadelfCmd .= " -WhlSsdA \"$Lib_Path\" 2>\"$TMP_DIR/null\"";
+        my $Cmd = $ReadelfCmd." -Ws \"$Lib_Path\" 2>\"$TMP_DIR/null\"";
         if($DebugPath)
         { # debug mode
           # write to file
-            system($ReadelfCmd." >\"$DebugPath\"");
+            system($Cmd." >\"$DebugPath\"");
             open(LIB, $DebugPath);
         }
         else
         { # write to pipe
-            open(LIB, $ReadelfCmd." |");
+            open(LIB, $Cmd." |");
         }
         my $symtab = undef; # indicates that we are processing 'symtab' section of 'readelf' output
         while(<LIB>)
@@ -19116,19 +19274,25 @@
                     }
                 }
             }
-            elsif($LIB_TYPE eq "dynamic")
-            { # dynamic library specifics
-                if($Deps)
-                {
-                    if(/NEEDED.+\[([^\[\]]+)\]/)
-                    { # dependencies:
-                      # 0x00000001 (NEEDED) Shared library: [libc.so.6]
-                        $NeededLib{$1} = 1;
-                    }
-                }
-            }
         }
         close(LIB);
+        
+        if($Deps and $LIB_TYPE eq "dynamic")
+        { # dynamic library specifics
+            $Cmd = $ReadelfCmd." -Wd \"$Lib_Path\" 2>\"$TMP_DIR/null\"";
+            open(LIB, $Cmd." |");
+            
+            while(<LIB>)
+            {
+                if(/NEEDED.+\[([^\[\]]+)\]/)
+                { # dependencies:
+                  # 0x00000001 (NEEDED) Shared library: [libc.so.6]
+                    $NeededLib{$1} = 1;
+                }
+            }
+            
+            close(LIB);
+        }
     }
     if($Vers)
     {
@@ -19449,7 +19613,8 @@
     if(my $Kind = $SkipHeaders{$LibVersion}{"Name"}{$Name}) {
         return $Kind;
     }
-    foreach my $D (keys(%{$SkipHeaders{$LibVersion}{"Path"}}))
+    foreach my $D (sort {$SkipHeaders{$LibVersion}{"Path"}{$a} cmp $SkipHeaders{$LibVersion}{"Path"}{$b}}
+    keys(%{$SkipHeaders{$LibVersion}{"Path"}}))
     {
         if(index($Path, $D)!=-1)
         {
@@ -19458,7 +19623,8 @@
             }
         }
     }
-    foreach my $P (keys(%{$SkipHeaders{$LibVersion}{"Pattern"}}))
+    foreach my $P (sort {$SkipHeaders{$LibVersion}{"Pattern"}{$a} cmp $SkipHeaders{$LibVersion}{"Pattern"}{$b}}
+    keys(%{$SkipHeaders{$LibVersion}{"Pattern"}}))
     {
         if(my $Kind = $SkipHeaders{$LibVersion}{"Pattern"}{$P})
         {
@@ -20637,6 +20803,7 @@
         if(not $GCC_PATH) {
             exitStatus("Not_Found", "can't find GCC>=3.0 in PATH");
         }
+        
         if(not $CheckObjectsOnly_Opt)
         {
             if(my $GCC_Ver = get_dumpversion($GCC_PATH))
@@ -20648,6 +20815,13 @@
                     $OStarget = "symbian";
                     $LIB_EXT = $OS_LibExt{$LIB_TYPE}{$OStarget};
                 }
+                
+                # check GCC version
+                if($GCC_Ver=~/\A4\.8(|\.0|\.1)\Z/)
+                { # bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=57850
+                    printMsg("WARNING", "Not working properly with GCC $GCC_Ver. Please update or downgrade GCC or use a local installation by --gcc-path=PATH option.");
+                    $EMERGENCY_MODE_48 = 1;
+                }
             }
             else {
                 exitStatus("Error", "something is going wrong with the GCC compiler");
@@ -22261,6 +22435,9 @@
             mergeConstants($Level);
         }
     }
+    
+    $Cache{"mergeTypes"} = (); # free memory
+    
     if($CheckHeadersOnly
     or $Level eq "Source")
     { # added/removed in headers