2
###########################################################################
3
# ABI-compliance-checker v1.13, lightweight tool for statically checking
4
# backward binary compatibility of shared C/C++ libraries in Linux.
5
# Copyright (C) The Linux Foundation
6
# Copyright (C) Institute for System Programming, RAS
7
# Author: Andrey Ponomarenko
9
# This program is free software: you can redistribute it and/or modify
10
# it under the terms of the GNU General Public License as published by
11
# the Free Software Foundation, either version 2 of the License, or
12
# (at your option) any later version.
14
# This program is distributed in the hope that it will be useful,
15
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
# GNU General Public License for more details.
19
# You should have received a copy of the GNU General Public License
20
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
###########################################################################
23
Getopt::Long::Configure ("posix_default", "no_ignore_case");
26
my $ABI_COMPLIANCE_CHECKER_VERSION = "1.13";
27
my ($Help, $ShowVersion, %Descriptor, $TargetLibraryName, $HeaderCheckingMode_Separately, $GenerateDescriptor, $TestSystem, $DumpInfo_DescriptorPath, $CheckHeadersOnly, $InterfacesListPath, $AppPath, $ShowExpendTime);
29
my $CmdName = get_FileName($0);
30
GetOptions("h|help!" => \$Help,
31
"v|version!" => \$ShowVersion,
33
"l|library=s" => \$TargetLibraryName,
34
"d1|descriptor1=s" => \$Descriptor{1}{"Path"},
35
"d2|descriptor2=s" => \$Descriptor{2}{"Path"},
37
"app|application=s" => \$AppPath,
38
"symbols_list|int_list=s" => \$InterfacesListPath,
39
"dump_abi|dump_info=s" => \$DumpInfo_DescriptorPath,
40
"headers_only!" => \$CheckHeadersOnly,
42
"d|descriptor_template!" => \$GenerateDescriptor,
43
"separately!" => \$HeaderCheckingMode_Separately,
44
"test!" => \$TestSystem,
45
"time!" => \$ShowExpendTime
53
$CmdName - check ABI compatibility of shared C/C++ library versions
56
Lightweight tool for statically checking backward binary compatibility of shared C/C++ libraries
57
in Linux. It checks header files along with shared objects in two library versions and searches
58
for ABI changes that may lead to incompatibility. Breakage of the binary compatibility may result
59
in crashing or incorrect behavior of applications built with an old version of a library when
60
it is running with a new one.
62
ABI Compliance Checker was intended for library developers that are interested in ensuring
63
backward binary compatibility. Also it can be used for checking forward binary compatibility
64
and checking applications portability to the new library version.
66
This tool is free software: you can redistribute it and/or modify it under the terms of the GNU GPL.
72
$CmdName -l <library_name> -d1 <1st_version_descriptor> -d2 <2nd_version_descriptor>
82
Library name (without version).
83
It affects only on the path and the title of the report.
85
-d1|-descriptor1 <path>
86
Path to descriptor of 1st library version.
88
-d2|-descriptor2 <path>
89
Path to descriptor of 2nd library version.
92
-app|-application <path>
93
This option allow to specify the application that should be tested for portability
94
to the new library version.
96
-dump_abi|-dump_info <descriptor_path>
97
Dump library ABI information using specified descriptor.
98
This command will create '<library>_<ver1>.abi.tar.gz' file in the directory 'abi_dumps/<library>/'.
99
You can transfer it anywhere and pass instead of library descriptor.
102
Check header files without shared objects. It is easy to run, but may provide
103
a low quality ABI compliance report with false positives and without
104
detecting of added/withdrawn interfaces.
106
-symbols_list|-int_list <path>
107
This option allow to specify a file with a list of interfaces (mangled names in C++)
108
that should be checked, other library interfaces will not be checked.
111
-d|-descriptor_template
112
Create library descriptor template 'library-descriptor.xml' in the current directory.
115
Check headers individually. This mode requires more time for checking ABI compliance,
116
but possible compiler errors in one header can't affect others.
119
Run internal tests (create two binary-incompatible versions of an artificial library
120
and run ABI-Compliance-Checker on it).
128
/usr/local/atk/atk-1.28.0/include/
132
/usr/local/atk/atk-1.28.0/lib/libatk-1.0.so
136
/usr/include/glib-2.0/
137
/usr/lib/glib-2.0/include/
141
Report bugs to <abi-compliance-checker\@linuxtesting.org>
142
For more information, please see: http://ispras.linux-foundation.org/index.php/ABI_compliance_checker
147
my $Descriptor_Template = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
150
<!-- Template for the library version descriptor -->
157
<!-- Version of the library -->
161
<!-- The list of paths to header files and/or
162
directories with header files, one per line -->
166
<!-- The list of paths to shared objects and/or
167
directories with shared objects, one per line -->
175
<!-- The list of paths to be searched for header files
176
needed for compiling of library headers, one per line -->
180
<!-- Additional gcc options, one per line -->
184
<!-- The list of opaque types, one per line -->
188
<!-- The list of functions (mangled/symbol names in C++)
189
that should be skipped while testing, one per line -->
193
<!-- The list of header files that should be included before other headers, one per line.
194
For example, it is a tree.h for libxml2 and ft2build.h for freetype2 -->
199
my %Operator_Indication = (
214
"lshiftassign" => "<<=",
215
"rshiftassign" => ">>=",
228
"delete" => " delete",
229
"vecnew" => " new[]",
230
"vecdelete" => " delete[]",
234
"plusassign" => "+=",
237
"minusassign" => "-=",
241
"multassign" => "*=",
257
elsif(int($Number)==1)
261
elsif(int($Number)==2)
265
elsif(int($Number)==3)
279
my $MAX_COMMAND_LINE_ARGUMENTS = 4096;
283
my %HeaderCompileError;
297
my %TemplateInstance_Func;
298
my %TemplateInstance;
302
my %Typedef_BaseName;
315
my %InternalInterfaces;
317
my %InterfacesList_App;
318
my %CheckedInterfaces;
322
my %Include_Preamble;
324
my %HeaderName_Destinations;
325
my %Header_Dependency;
328
my %SoLib_DefaultPath;
331
my %CompleteSignature;
333
my %Interface_Library;
334
my %Library_Interface;
342
#Problem descriptions
344
my %ConstantProblems;
348
my $ContentSpanStart = "<span class=\"section\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
349
my $ContentSpanEnd = "</span>\n";
350
my $ContentDivStart = "<div id=\"CONTENT_ID\" style=\"display:none;\">\n";
351
my $ContentDivEnd = "</div>\n";
352
my $Content_Counter = 0;
354
sub readDescriptor($)
356
my $LibVersion = $_[0];
357
if(not -e $Descriptor{$LibVersion}{"Path"})
361
my $Descriptor_File = readFile($Descriptor{$LibVersion}{"Path"});
362
$Descriptor_File =~ s/\/\*(.|\n)+?\*\///g;
363
$Descriptor_File =~ s/<\!--(.|\n)+?-->//g;
364
if(not $Descriptor_File)
366
print "ERROR: descriptor d$LibVersion is empty\n";
369
$Descriptor{$LibVersion}{"Version"} = parseTag(\$Descriptor_File, "version");
370
if(not $Descriptor{$LibVersion}{"Version"})
372
print "ERROR: version in the descriptor d$LibVersion was not specified (section <version>)\n\n";
375
$Descriptor{$LibVersion}{"Headers"} = parseTag(\$Descriptor_File, "headers");
376
if(not $Descriptor{$LibVersion}{"Headers"})
378
print "ERROR: header files in the descriptor d$LibVersion were not specified (section <headers>)\n";
381
if(not $CheckHeadersOnly)
383
$Descriptor{$LibVersion}{"Libs"} = parseTag(\$Descriptor_File, "libs");
384
if(not $Descriptor{$LibVersion}{"Libs"})
386
print "ERROR: shared objects in the descriptor d$LibVersion were not specified (section <libs>)\n";
390
$Descriptor{$LibVersion}{"Include_Paths"} = parseTag(\$Descriptor_File, "include_paths");
391
$Descriptor{$LibVersion}{"Gcc_Options"} = parseTag(\$Descriptor_File, "gcc_options");
392
foreach my $Option (split("\n", $Descriptor{$LibVersion}{"Gcc_Options"}))
394
$Option =~ s/\A\s+|\s+\Z//g;
395
next if(not $Option);
396
$CompilerOptions{$LibVersion} .= " ".$Option;
398
$Descriptor{$LibVersion}{"Opaque_Types"} = parseTag(\$Descriptor_File, "opaque_types");
399
foreach my $Type_Name (split("\n", $Descriptor{$LibVersion}{"Opaque_Types"}))
401
$Type_Name =~ s/\A\s+|\s+\Z//g;
402
next if(not $Type_Name);
403
$OpaqueTypes{$LibVersion}{$Type_Name} = 1;
405
$Descriptor{$LibVersion}{"Skip_interfaces"} = parseTag(\$Descriptor_File, "skip_interfaces");
406
foreach my $Interface_Name (split("\n", $Descriptor{$LibVersion}{"Skip_interfaces"}))
408
$Interface_Name =~ s/\A\s+|\s+\Z//g;
409
next if(not $Interface_Name);
410
$InternalInterfaces{$LibVersion}{$Interface_Name} = 1;
412
$Descriptor{$LibVersion}{"Include_Preamble"} = parseTag(\$Descriptor_File, "include_preamble");
414
foreach my $Header_Name (split("\n", $Descriptor{$LibVersion}{"Include_Preamble"}))
416
$Header_Name =~ s/\A\s+|\s+\Z//g;
417
next if(not $Header_Name);
418
$Include_Preamble{$LibVersion}{$Header_Name}{"Position"} = $Position;
421
my $Descriptors_Dir = "descriptors_storage/$TargetLibraryName";
422
system("mkdir", "-p", $Descriptors_Dir);
423
my $Descriptor_Name = $TargetLibraryName."_".$Descriptor{$LibVersion}{"Version"}.".desc";
424
if($Descriptor{$LibVersion}{"Path"} ne $Descriptors_Dir."/".$Descriptor_Name)
426
system("cp", "-f", $Descriptor{$LibVersion}{"Path"}, $Descriptors_Dir."/".$Descriptor_Name);
428
$ERR_PATH{$LibVersion} = "header_compile_errors/$TargetLibraryName/".$Descriptor{$LibVersion}{"Version"};
433
my ($CodeRef, $Tag) = @_;
434
return "" if(not $CodeRef or not ${$CodeRef} or not $Tag);
435
if(${$CodeRef} =~ s/\<$Tag\>((.|\n)+?)\<\/$Tag\>//)
438
$Content=~s/(\A\s+|\s+\Z)//g;
457
"identifier_node"=>1,
470
"template_type_parm"=>1,
480
my $InfoPath = $_[0];
481
return if(not $InfoPath or not -f $InfoPath);
482
my $InfoPath_New = $InfoPath.".1";
483
#my $Keywords = join("\\|", keys(%check_node));#|grep "$Keywords"
484
system("sed ':a;N;\$!ba;s/\\n[^\@]//g' ".esc($InfoPath)."|sed 's/ [ ]\\+/ /g' > ".esc($InfoPath_New));
485
system("rm", "-fr", $InfoPath);
487
open(INFO, $InfoPath_New) || die ("can't open file '\$InfoPath_New\': $!\n");
491
if(/\A@([0-9]+)[ ]+([a-zA-Z_]+)[ ]+(.*)\Z/)
493
next if(not $check_node{$2});
494
$LibInfo{$Version}{$1}{"info_type"}=$2;
495
$LibInfo{$Version}{$1}{"info"}=$3;
499
system("rm", "-fr", $InfoPath_New);
501
setTemplateParams_All();
506
%TemplateInstance = ();
509
sub setTemplateParams_All()
511
foreach (keys(%{$LibInfo{$Version}}))
513
if($LibInfo{$Version}{$_}{"info_type"} eq "template_decl")
515
setTemplateParams($_);
520
sub setTemplateParams($)
522
my $TypeInfoId = $_[0];
523
my $Info = $LibInfo{$Version}{$TypeInfoId}{"info"};
524
if($Info =~ /(inst|spcs)[ ]*:[ ]*@([0-9]+) /)
526
my $TmplInst_InfoId = $2;
527
setTemplateInstParams($TmplInst_InfoId);
528
my $TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
529
while($TmplInst_Info =~ /chan[ ]*:[ ]*@([0-9]+) /)
531
$TmplInst_InfoId = $1;
532
$TmplInst_Info = $LibInfo{$Version}{$TmplInst_InfoId}{"info"};
533
setTemplateInstParams($TmplInst_InfoId);
538
sub setTemplateInstParams($)
540
my $TmplInst_Id = $_[0];
541
my $Info = $LibInfo{$Version}{$TmplInst_Id}{"info"};
542
my ($Params_InfoId, $ElemId) = ();
543
if($Info =~ /purp[ ]*:[ ]*@([0-9]+) /)
547
if($Info =~ /valu[ ]*:[ ]*@([0-9]+) /)
551
if($Params_InfoId and $ElemId)
553
my $Params_Info = $LibInfo{$Version}{$Params_InfoId}{"info"};
554
while($Params_Info =~ s/ ([0-9]+)[ ]*:[ ]*@([0-9]+) //)
556
my ($Param_Pos, $Param_TypeId) = ($1, $2);
557
return if($LibInfo{$Version}{$Param_TypeId}{"info_type"} eq "template_type_parm");
558
if($LibInfo{$ElemId}{"info_type"} eq "function_decl")
560
$TemplateInstance_Func{$Version}{$ElemId}{$Param_Pos} = $Param_TypeId;
564
$TemplateInstance{$Version}{getTypeDeclId($ElemId)}{$ElemId}{$Param_Pos} = $Param_TypeId;
572
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
573
if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+)/)
585
my $Ptd = pointTo($_[0]);
588
if(($LibInfo{$Version}{$_[0]}{"info"} =~ m/unql[ ]*:/) and not ($LibInfo{$Version}{$_[0]}{"info"} =~ m/qual[ ]*:/))
592
elsif(($LibInfo{$Version}{$_[0]}{"info_type"} eq "pointer_type") and ($LibInfo{$Version}{$Ptd}{"info_type"} eq "function_type" or $LibInfo{$Version}{$Ptd}{"info_type"} eq "method_type"))
609
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
610
if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+)/)
620
sub getTypeDescr_All()
622
foreach (sort {int($a)<=>int($b)} keys(%{$LibInfo{$Version}}))
624
if($LibInfo{$Version}{$_}{"info_type"}=~/_type\Z/ and $LibInfo{$Version}{$_}{"info_type"}!~/function_type|method_type/)
626
getTypeDescr(getTypeDeclId($_), $_);
629
$TypeDescr{$Version}{""}{-1}{"Name"} = "...";
630
$TypeDescr{$Version}{""}{-1}{"Type"} = "Intrinsic";
631
$TypeDescr{$Version}{""}{-1}{"Tid"} = -1;
636
my ($TypeDeclId, $TypeId) = @_;
637
$Tid_TDid{$Version}{$TypeId} = $TypeDeclId;
638
%{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTypeAttr($TypeDeclId, $TypeId);
639
if(not $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
641
delete($TypeDescr{$Version}{$TypeDeclId}{$TypeId});
644
if(not $TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}})
646
$TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
652
my ($TypeDeclId, $TypeId) = @_;
653
my ($BaseTypeSpec, %TypeAttr) = ();
654
if($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"})
656
return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
658
$TypeAttr{"Tid"} = $TypeId;
659
$TypeAttr{"TDid"} = $TypeDeclId;
660
$TypeAttr{"Type"} = getTypeType($TypeDeclId, $TypeId);
661
if($TypeAttr{"Type"} eq "Unknown")
665
elsif($TypeAttr{"Type"} eq "FuncPtr")
667
%{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getFuncPtrAttr(pointTo($TypeId), $TypeDeclId, $TypeId);
668
$TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
669
return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
671
elsif($TypeAttr{"Type"} eq "Array")
673
($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
674
my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
675
my $ArrayElemNum = getSize($TypeId)/8;
676
$ArrayElemNum = $ArrayElemNum/$BaseTypeAttr{"Size"} if($BaseTypeAttr{"Size"});
677
$TypeAttr{"Size"} = $ArrayElemNum;
680
$TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[".$ArrayElemNum."]";
684
$TypeAttr{"Name"} = $BaseTypeAttr{"Name"}."[]";
686
$TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
687
$TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
688
$TypeAttr{"Header"} = $BaseTypeAttr{"Header"};
689
%{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
690
$TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
693
elsif($TypeAttr{"Type"} =~ /Intrinsic|Union|Struct|Enum|Class/)
695
if($TemplateInstance{$Version}{$TypeDeclId}{$TypeId})
697
my @Template_Params = ();
698
foreach my $Param_Pos (sort {int($a)<=>int($b)} keys(%{$TemplateInstance{$Version}{$TypeDeclId}{$TypeId}}))
700
my $Type_Id = $TemplateInstance{$Version}{$TypeDeclId}{$TypeId}{$Param_Pos};
701
my $Param = get_TemplateParam($Type_Id);
706
@Template_Params = (@Template_Params, $Param);
708
%{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
709
$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}."< ".join(", ", @Template_Params)." >";
710
$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"} = correctName($TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"});
711
$TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
712
return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
716
%{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = getTrivialTypeAttr($TypeDeclId, $TypeId);
717
return %{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}};
722
($TypeAttr{"BaseType"}{"Tid"}, $TypeAttr{"BaseType"}{"TDid"}, $BaseTypeSpec) = selectBaseType($TypeDeclId, $TypeId);
723
my %BaseTypeAttr = getTypeAttr($TypeAttr{"BaseType"}{"TDid"}, $TypeAttr{"BaseType"}{"Tid"});
724
if($BaseTypeSpec and $BaseTypeAttr{"Name"})
726
if(($TypeAttr{"Type"} eq "Pointer") and $BaseTypeAttr{"Name"}=~/\([\*]+\)/)
728
$TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
729
$TypeAttr{"Name"} =~ s/\(([*]+)\)/($1*)/g;
733
$TypeAttr{"Name"} = $BaseTypeAttr{"Name"}." ".$BaseTypeSpec;
736
elsif($BaseTypeAttr{"Name"})
738
$TypeAttr{"Name"} = $BaseTypeAttr{"Name"};
740
if($TypeAttr{"Type"} eq "Typedef")
742
$TypeAttr{"Name"} = getNameByInfo($TypeDeclId);
743
$TypeAttr{"NameSpace"} = getNameSpace($TypeDeclId);
744
if($TypeAttr{"NameSpace"})
746
$TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
748
($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeDeclId);
749
if($TypeAttr{"NameSpace"}=~/\Astd(::|\Z)/ and $BaseTypeAttr{"NameSpace"}=~/\Astd(::|\Z)/)
751
$StdCxxTypedef{$Version}{$BaseTypeAttr{"Name"}} = $TypeAttr{"Name"};
753
$Typedef_BaseName{$Version}{$TypeAttr{"Name"}} = $BaseTypeAttr{"Name"};
755
if(not $TypeAttr{"Size"})
757
if($TypeAttr{"Type"} eq "Pointer")
759
$TypeAttr{"Size"} = $POINTER_SIZE;
763
$TypeAttr{"Size"} = $BaseTypeAttr{"Size"};
766
$TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
767
$TypeAttr{"Library"} = $BaseTypeAttr{"Library"};
768
$TypeAttr{"Header"} = $BaseTypeAttr{"Header"} if(not $TypeAttr{"Header"});
769
%{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}} = %TypeAttr;
770
$TName_Tid{$Version}{$TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"Name"}} = $TypeId;
775
sub get_TemplateParam($)
778
if(getNodeType($Type_Id) eq "integer_cst")
780
return getNodeIntCst($Type_Id);
782
elsif(getNodeType($Type_Id) eq "string_cst")
784
return getNodeStrCst($Type_Id);
788
my $Type_DId = getTypeDeclId($Type_Id);
789
my %ParamAttr = getTypeAttr($Type_DId, $Type_Id);
790
if(not $ParamAttr{"Name"})
794
if($ParamAttr{"Name"}=~/\>/)
796
if($StdCxxTypedef{$Version}{$ParamAttr{"Name"}})
798
return $StdCxxTypedef{$Version}{$ParamAttr{"Name"}};
800
elsif(my $Covered = cover_stdcxx_typedef($ParamAttr{"Name"}))
806
return $ParamAttr{"Name"};
811
return $ParamAttr{"Name"};
816
sub cover_stdcxx_typedef($)
818
my $TypeName = $_[0];
819
my $TypeName_Covered = $TypeName;
820
while($TypeName=~s/>[ ]*(const|volatile|restrict| |\*|\&)\Z/>/g){};
821
if(my $Cover = $StdCxxTypedef{$Version}{$TypeName})
823
$TypeName = esc_l($TypeName);
824
$TypeName_Covered=~s/$TypeName/$Cover /g;
826
return correctName($TypeName_Covered);
831
return $LibInfo{$Version}{$_[0]}{"info_type"};
837
my $CstTypeId = getTreeAttr($CstId, "type");
838
if($EnumMembName_Id{$Version}{$CstId})
840
return $EnumMembName_Id{$Version}{$CstId};
842
elsif($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*([^ ]+) /)
846
if(getNodeType($CstTypeId) eq "boolean_type")
857
if(getNodeType($CstTypeId) eq "boolean_type")
879
if($LibInfo{$Version}{$_[0]}{"info"} =~ /low[ ]*:[ ]*(.+)[ ]+lngt/)
892
$String=~s/([()*])/\\$1/g;
896
sub getFuncPtrAttr($$$)
898
my ($FuncTypeId, $TypeDeclId, $TypeId) = @_;
899
my $FuncInfo = $LibInfo{$Version}{$FuncTypeId}{"info"};
900
my $FuncInfo_Type = $LibInfo{$Version}{$FuncTypeId}{"info_type"};
901
my $FuncPtrCorrectName = "";
902
my %TypeAttr = ("Size"=>$POINTER_SIZE, "Type"=>"FuncPtr", "TDid"=>$TypeDeclId, "Tid"=>$TypeId);
904
if($FuncInfo =~ /retn[ ]*:[ ]*\@([0-9]+) /)
906
my $ReturnTypeId = $1;
907
my %ReturnAttr = getTypeAttr(getTypeDeclId($ReturnTypeId), $ReturnTypeId);
908
$FuncPtrCorrectName .= $ReturnAttr{"Name"};
909
$TypeAttr{"Return"} = $ReturnTypeId;
911
if($FuncInfo =~ /prms[ ]*:[ ]*@([0-9]+) /)
913
my $ParamTypeInfoId = $1;
915
while($ParamTypeInfoId)
917
my $ParamTypeInfo = $LibInfo{$Version}{$ParamTypeInfoId}{"info"};
918
last if($ParamTypeInfo !~ /valu[ ]*:[ ]*@([0-9]+) /);
919
my $ParamTypeId = $1;
920
my %ParamAttr = getTypeAttr(getTypeDeclId($ParamTypeId), $ParamTypeId);
921
last if($ParamAttr{"Name"} eq "void");
922
$TypeAttr{"Memb"}{$Position}{"type"} = $ParamTypeId;
923
push(@ParamTypeName, $ParamAttr{"Name"});
924
last if($ParamTypeInfo !~ /chan[ ]*:[ ]*@([0-9]+) /);
925
$ParamTypeInfoId = $1;
929
if($FuncInfo_Type eq "function_type")
931
$FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
933
elsif($FuncInfo_Type eq "method_type")
935
if($FuncInfo =~ /clas[ ]*:[ ]*@([0-9]+) /)
938
my $ClassName = $TypeDescr{$Version}{getTypeDeclId($ClassId)}{$ClassId}{"Name"};
941
$FuncPtrCorrectName .= " ($ClassName\:\:*) (".join(", ", @ParamTypeName).")";
945
$FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
950
$FuncPtrCorrectName .= " (*) (".join(", ", @ParamTypeName).")";
953
$TypeAttr{"Name"} = correctName($FuncPtrCorrectName);
959
my $Info = $LibInfo{$Version}{$_[0]}{"info"};
960
if($Info =~ /name[ ]*:[ ]*@([0-9]+) /)
962
return getNameByInfo($1);
966
if($LibInfo{$Version}{$_[0]}{"info_type"} eq "integer_type")
968
if($LibInfo{$Version}{$_[0]}{"info"} =~ /unsigned/)
970
return "unsigned int";
984
sub selectBaseType($$)
986
my ($TypeDeclId, $TypeId) = @_;
987
my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
989
my $Type_Type = getTypeType($TypeDeclId, $TypeId);
991
if(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
993
return ($1, getTypeDeclId($1), "const");
995
elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
997
return ($1, getTypeDeclId($1), "restrict");
999
elsif(($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v /) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
1001
return ($1, getTypeDeclId($1), "volatile");
1003
elsif((not ($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:/)) and ($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@([0-9]+) /))
1005
return ($1, getTypeDeclId($1), "");
1007
elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "reference_type")
1009
if($TypeInfo =~ /refd[ ]*:[ ]*@([0-9]+) /)
1011
return ($1, getTypeDeclId($1), "&");
1018
elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "array_type")
1020
if($TypeInfo =~ /elts[ ]*:[ ]*@([0-9]+) /)
1022
return ($1, getTypeDeclId($1), "");
1029
elsif($LibInfo{$Version}{$TypeId}{"info_type"} eq "pointer_type")
1031
if($TypeInfo =~ /ptd[ ]*:[ ]*@([0-9]+) /)
1033
return ($1, getTypeDeclId($1), "*");
1046
sub getFuncDescr_All()
1048
foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
1050
if($LibInfo{$Version}{$_}{"info_type"} eq "function_decl")
1057
sub getVarDescr_All()
1059
foreach (sort {int($b)<=>int($a)} keys(%{$LibInfo{$Version}}))
1061
if($LibInfo{$Version}{$_}{"info_type"} eq "var_decl")
1070
my $FuncInfoId = $_[0];
1071
if($LibInfo{$Version}{getNameSpaceId($FuncInfoId)}{"info_type"} eq "function_decl")
1075
($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
1076
if((not $FuncDescr{$Version}{$FuncInfoId}{"Header"}) or ($FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/))
1078
delete($FuncDescr{$Version}{$FuncInfoId});
1081
$FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getNameByInfo($FuncInfoId);
1082
$FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
1083
if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
1085
delete($FuncDescr{$Version}{$FuncInfoId});
1088
if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"})
1090
$FuncDescr{$Version}{$FuncInfoId}{"Name"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1091
$FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1093
if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
1095
delete $FuncDescr{$Version}{$FuncInfoId};
1098
$FuncDescr{$Version}{$FuncInfoId}{"Return"} = getTypeId($FuncInfoId);
1099
delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
1100
$FuncDescr{$Version}{$FuncInfoId}{"Data"} = 1;
1101
set_Class_And_Namespace($FuncInfoId);
1102
setFuncAccess($FuncInfoId);
1103
if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_ZTV/)
1105
delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
1107
if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\A_Z/)
1109
delete($FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
1113
sub getTrivialTypeAttr($$)
1115
my ($TypeInfoId, $TypeId) = @_;
1117
return if(getTypeTypeByTypeId($TypeId)!~/Intrinsic|Union|Struct|Enum/);
1118
setTypeAccess($TypeId, \%TypeAttr);
1119
($TypeAttr{"Header"}, $TypeAttr{"Line"}) = getLocation($TypeInfoId);
1120
if(($TypeAttr{"Header"} eq "<built-in>") or ($TypeAttr{"Header"} eq "<internal>"))
1122
delete($TypeAttr{"Header"});
1124
$TypeAttr{"Name"} = getNameByInfo($TypeInfoId);
1125
$TypeAttr{"Name"} = getTypeName($TypeId) if(not $TypeAttr{"Name"});
1126
my $NameSpaceId = getNameSpaceId($TypeInfoId);
1127
if($NameSpaceId ne $TypeId)
1129
$TypeAttr{"NameSpace"} = getNameSpace($TypeInfoId);
1131
if($TypeAttr{"NameSpace"} and isNotAnon($TypeAttr{"Name"}))
1133
$TypeAttr{"Name"} = $TypeAttr{"NameSpace"}."::".$TypeAttr{"Name"};
1135
$TypeAttr{"Name"} = correctName($TypeAttr{"Name"});
1136
if(isAnon($TypeAttr{"Name"}))
1138
$TypeAttr{"Name"} = "anon-";
1139
$TypeAttr{"Name"} .= $TypeAttr{"Header"}."-".$TypeAttr{"Line"};
1141
$TypeAttr{"Size"} = getSize($TypeId)/8;
1142
$TypeAttr{"Type"} = getTypeType($TypeInfoId, $TypeId);
1143
if($TypeAttr{"Type"} eq "Struct" and has_methods($TypeId))
1145
$TypeAttr{"Type"} = "Class";
1147
if(($TypeAttr{"Type"} eq "Struct") or ($TypeAttr{"Type"} eq "Class"))
1149
setBaseClasses($TypeInfoId, $TypeId, \%TypeAttr);
1151
setTypeMemb($TypeInfoId, $TypeId, \%TypeAttr);
1152
$TypeAttr{"Tid"} = $TypeId;
1153
$TypeAttr{"TDid"} = $TypeInfoId;
1154
$Tid_TDid{$Version}{$TypeId} = $TypeInfoId;
1155
if(not $TName_Tid{$Version}{$TypeAttr{"Name"}})
1157
$TName_Tid{$Version}{$TypeAttr{"Name"}} = $TypeId;
1165
my $Info = $LibInfo{$Version}{$TypeId}{"info"};
1166
return ($Info=~/(fncs)[ ]*:[ ]*@([0-9]+) /);
1169
sub setBaseClasses($$$)
1171
my ($TypeInfoId, $TypeId, $TypeAttr) = @_;
1172
my $Info = $LibInfo{$Version}{$TypeId}{"info"};
1173
if($Info =~ /binf[ ]*:[ ]*@([0-9]+) /)
1175
$Info = $LibInfo{$Version}{$1}{"info"};
1176
while($Info =~ /accs[ ]*:[ ]*([a-z]+) /)
1178
last if($Info !~ s/accs[ ]*:[ ]*([a-z]+) //);
1180
last if($Info !~ s/binf[ ]*:[ ]*@([0-9]+) //);
1182
my $ClassId = getBinfClassId($BInfoId);
1183
if($Access eq "pub")
1185
$TypeAttr->{"BaseClass"}{$ClassId} = "public";
1187
elsif($Access eq "prot")
1189
$TypeAttr->{"BaseClass"}{$ClassId} = "protected";
1191
elsif($Access eq "priv")
1193
$TypeAttr->{"BaseClass"}{$ClassId} = "private";
1197
$TypeAttr->{"BaseClass"}{$ClassId} = "private";
1203
sub getBinfClassId($)
1205
my $Info = $LibInfo{$Version}{$_[0]}{"info"};
1206
$Info =~ /type[ ]*:[ ]*@([0-9]+) /;
1210
sub get_func_signature($)
1212
my $FuncInfoId = $_[0];
1213
my $PureSignature = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1214
my @ParamTypes = ();
1215
foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$FuncDescr{$Version}{$FuncInfoId}{"Param"}}))
1216
{#checking parameters
1217
my $ParamType_Id = $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$ParamPos}{"type"};
1218
my $ParamType_Name = uncover_typedefs($TypeDescr{$Version}{getTypeDeclId($ParamType_Id)}{$ParamType_Id}{"Name"});
1219
@ParamTypes = (@ParamTypes, $ParamType_Name);
1221
$PureSignature = $PureSignature."(".join(", ", @ParamTypes).")";
1222
$PureSignature = delete_keywords($PureSignature);
1223
return correctName($PureSignature);
1226
sub delete_keywords($)
1228
my $TypeName = $_[0];
1229
$TypeName =~ s/(\W|\A)(enum |struct |union |class )/$1/g;
1233
sub uncover_typedefs($)
1235
my $TypeName = $_[0];
1236
return "" if(not $TypeName);
1237
return $Cache{"uncover_typedefs"}{$Version}{$TypeName} if(defined $Cache{"uncover_typedefs"}{$Version}{$TypeName});
1238
my ($TypeName_New, $TypeName_Pre) = (correctName($TypeName), "");
1239
while($TypeName_New ne $TypeName_Pre)
1241
$TypeName_Pre = $TypeName_New;
1242
my $TypeName_Copy = $TypeName_New;
1244
while($TypeName_Copy=~s/(\W|\A)([a-z_][\w:]*)(\W|\Z)//io)
1247
next if(not $Word or $Word=~/\A(true|false|const|int|long|void|short|float|unsigned|char|double|class|struct|union|enum)\Z/);
1250
foreach my $Word (keys(%Words))
1252
my $BaseType_Name = $Typedef_BaseName{$Version}{$Word};
1253
next if($TypeName_New=~/(\W|\A)(struct $Word|union $Word|enum $Word)(\W|\Z)/);
1254
next if(not $BaseType_Name);
1255
if($BaseType_Name=~/\([*]+\)/)
1257
$TypeName_New =~ /$Word(.*)\Z/;
1258
my $Type_Suffix = $1;
1259
$TypeName_New = $BaseType_Name;
1260
if($TypeName_New =~ s/\(([*]+)\)/($1 $Type_Suffix)/)
1262
$TypeName_New = correctName($TypeName_New);
1267
if($TypeName_New =~ s/(\W|\A)$Word(\W|\Z)/$1$BaseType_Name$2/g)
1269
$TypeName_New = correctName($TypeName_New);
1274
$Cache{"uncover_typedefs"}{$Version}{$TypeName} = $TypeName_New;
1275
return $TypeName_New;
1280
my $FuncInfoId = $_[0];
1281
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
1282
return 0 if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
1283
my $FuncMnglNameInfoId = $1;
1284
return ($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} =~ /\*[ ]*INTERNAL[ ]*\*/);
1287
sub set_Class_And_Namespace($)
1289
my $FuncInfoId = $_[0];
1290
my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1291
if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
1293
my $NameSpaceInfoId = $1;
1294
if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
1296
my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
1297
if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
1299
my $NameSpaceId = $1;
1300
my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
1301
if($NameSpaceIdentifier =~ /strg[ ]*:[ ]*(.*)[ ]+lngt/)
1304
$NameSpace =~ s/[ ]+\Z//g;
1305
$FuncDescr{$Version}{$FuncInfoId}{"NameSpace"} = $NameSpace;
1309
elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
1311
$FuncDescr{$Version}{$FuncInfoId}{"Class"} = $NameSpaceInfoId;
1318
my $FuncInfoId = $_[0];
1319
return if(isInternal($FuncInfoId));
1320
($FuncDescr{$Version}{$FuncInfoId}{"Header"}, $FuncDescr{$Version}{$FuncInfoId}{"Line"}) = getLocation($FuncInfoId);
1321
if(not $FuncDescr{$Version}{$FuncInfoId}{"Header"} or $FuncDescr{$Version}{$FuncInfoId}{"Header"}=~/\<built\-in\>|\<internal\>/)
1323
delete($FuncDescr{$Version}{$FuncInfoId});
1326
setFuncAccess($FuncInfoId);
1327
setFuncKind($FuncInfoId);
1328
if($FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"})
1330
delete($FuncDescr{$Version}{$FuncInfoId});
1333
$FuncDescr{$Version}{$FuncInfoId}{"Type"} = getFuncType($FuncInfoId);
1334
$FuncDescr{$Version}{$FuncInfoId}{"Return"} = getFuncReturn($FuncInfoId);
1335
delete($FuncDescr{$Version}{$FuncInfoId}{"Return"}) if(not $FuncDescr{$Version}{$FuncInfoId}{"Return"});
1336
$FuncDescr{$Version}{$FuncInfoId}{"ShortName"} = getFuncShortName(getFuncOrig($FuncInfoId));
1337
if($FuncDescr{$Version}{$FuncInfoId}{"ShortName"} =~ /\._/)
1339
delete($FuncDescr{$Version}{$FuncInfoId});
1342
if(defined $TemplateInstance_Func{$Version}{$FuncInfoId})
1344
my @TmplParams = ();
1345
foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$TemplateInstance_Func{$Version}{$FuncInfoId}}))
1347
my $Param = get_TemplateParam($TemplateInstance_Func{$Version}{$FuncInfoId}{$ParamPos});
1350
delete($FuncDescr{$Version}{$FuncInfoId});
1353
push(@TmplParams, $Param);
1355
$FuncDescr{$Version}{$FuncInfoId}{"ShortName"} .= "<".join(", ", @TmplParams).">";
1357
setFuncParams($FuncInfoId);
1358
$FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = getFuncMnglName($FuncInfoId);
1359
if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and $FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
1361
delete($FuncDescr{$Version}{$FuncInfoId});
1365
if((is_in_library($FuncDescr{$Version}{$FuncInfoId}{"ShortName"}, $Version) or $CheckHeadersOnly) and not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and ($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function"))
1367
$FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
1369
set_Class_And_Namespace($FuncInfoId);
1370
if(not $FuncDescr{$Version}{$FuncInfoId}{"MnglName"} and not $FuncDescr{$Version}{$FuncInfoId}{"Class"})
1371
{#this section only for c++ functions without class that have not been mangled in the tree
1372
$FuncDescr{$Version}{$FuncInfoId}{"MnglName"} = $mangled_name{get_func_signature($FuncInfoId)};
1374
if(not is_in_library($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}, $Version) and not $CheckHeadersOnly)
1376
delete($FuncDescr{$Version}{$FuncInfoId});
1379
if($FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
1381
delete($FuncDescr{$Version}{$FuncInfoId}{"Return"});
1383
my $FuncBody = getFuncBody($FuncInfoId);
1384
if($FuncBody eq "defined")
1386
$FuncDescr{$Version}{$FuncInfoId}{"InLine"} = 1;
1388
if($CheckHeadersOnly and $FuncDescr{$Version}{$FuncInfoId}{"InLine"})
1390
delete($FuncDescr{$Version}{$FuncInfoId});
1393
if(($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Method") or $FuncDescr{$Version}{$FuncInfoId}{"Constructor"} or $FuncDescr{$Version}{$FuncInfoId}{"Destructor"})
1395
if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"}!~/\A_Z/)
1397
delete($FuncDescr{$Version}{$FuncInfoId});
1401
if(getFuncSpec($FuncInfoId) eq "Virt")
1403
$FuncDescr{$Version}{$FuncInfoId}{"Virt"} = 1;
1405
if(getFuncSpec($FuncInfoId) eq "PureVirt")
1406
{#pure virtual methods
1407
$FuncDescr{$Version}{$FuncInfoId}{"PureVirt"} = 1;
1409
if($FuncDescr{$Version}{$FuncInfoId}{"MnglName"} =~ /\A_Z/ and $FuncDescr{$Version}{$FuncInfoId}{"Class"})
1411
if($FuncDescr{$Version}{$FuncInfoId}{"Type"} eq "Function")
1413
$FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
1416
if(getFuncLink($FuncInfoId) eq "Static")
1418
$FuncDescr{$Version}{$FuncInfoId}{"Static"} = 1;
1420
delete($FuncDescr{$Version}{$FuncInfoId}{"Type"});
1425
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
1426
if($FuncInfo =~ /body[ ]*:[ ]*undefined(\ |\Z)/i)
1430
elsif($FuncInfo =~ /body[ ]*:[ ]*@([0-9]+)(\ |\Z)/i)
1440
sub getTypeShortName($)
1442
my $TypeName = $_[0];
1443
$TypeName =~ s/\<.*\>//g;
1444
$TypeName =~ s/.*\:\://g;
1450
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
1451
if($TypeInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
1463
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
1464
if($TypeInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
1476
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
1477
if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
1489
my ($TypeDeclId, $TypeId, $TypeAttr) = @_;
1490
my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
1492
my $TypeType = $TypeAttr->{"Type"};
1494
my $BasePosition = 0;
1497
if($TypeType eq "Enum")
1499
$TypeMembInfoId = getEnumMembInfoId($TypeId);
1500
while($TypeMembInfoId)
1502
$TypeAttr->{"Memb"}{$Position}{"value"} = getEnumMembVal($TypeMembInfoId);
1503
my $MembName = getEnumMembName($TypeMembInfoId);
1504
$TypeAttr->{"Memb"}{$Position}{"name"} = getEnumMembName($TypeMembInfoId);
1505
$EnumMembName_Id{$Version}{getTreeAttr($TypeMembInfoId, "valu")} = ($TypeAttr->{"NameSpace"})?$TypeAttr->{"NameSpace"}."::".$MembName:$MembName;
1506
$TypeMembInfoId = getNextMembInfoId($TypeMembInfoId);
1510
elsif(($TypeType eq "Struct") or ($TypeType eq "Class") or ($TypeType eq "Union"))
1512
$TypeMembInfoId = getStructMembInfoId($TypeId);
1513
while($TypeMembInfoId)
1515
if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} ne "field_decl")
1517
$TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
1520
$StructMembName = getStructMembName($TypeMembInfoId);
1521
if($StructMembName =~ /_vptr\./)
1523
$TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
1526
if(not $StructMembName)
1528
#$TypeAttr->{"Base"}{$BasePosition}{"type"} = getStructMembType($TypeMembInfoId);
1529
#$TypeAttr->{"Base"}{$BasePosition}{"access"} = getStructMembAccess($TypeMembInfoId);
1531
$TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
1534
$TypeAttr->{"Memb"}{$Position}{"type"} = getStructMembType($TypeMembInfoId);
1535
$TypeAttr->{"Memb"}{$Position}{"name"} = $StructMembName;
1536
$TypeAttr->{"Memb"}{$Position}{"access"} = getStructMembAccess($TypeMembInfoId);
1537
$TypeAttr->{"Memb"}{$Position}{"bitfield"} = getStructMembBitFieldSize($TypeMembInfoId);
1539
$TypeMembInfoId = getNextStructMembInfoId($TypeMembInfoId);
1545
sub setFuncParams($)
1547
my $FuncInfoId = $_[0];
1548
my $ParamInfoId = getFuncParamInfoId($FuncInfoId);
1549
my $FunctionType = getFuncType($FuncInfoId);
1550
if($FunctionType eq "Method")
1552
$ParamInfoId = getNextElem($ParamInfoId);
1557
my $ParamTypeId = getFuncParamType($ParamInfoId);
1558
last if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void");
1559
if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Type"} eq "Restrict")
1560
{#delete restrict spec
1561
$ParamTypeId = getRestrictBase($ParamTypeId);
1563
$FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = $ParamTypeId;
1564
$FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = getFuncParamName($ParamInfoId);
1565
if(not $FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"})
1567
$FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"name"} = "p".($Position+1);
1569
$ParamInfoId = getNextElem($ParamInfoId);
1572
if(detect_nolimit_args($FuncInfoId))
1574
$FuncDescr{$Version}{$FuncInfoId}{"Param"}{$Position}{"type"} = -1;
1578
sub detect_nolimit_args($)
1580
my $FuncInfoId = $_[0];
1581
my $FuncTypeId = getFuncTypeId($FuncInfoId);
1582
my $ParamListElemId = getFuncParamTreeListId($FuncTypeId);
1585
while($ParamListElemId)
1587
my $ParamTypeId = getTreeAttr($ParamListElemId, "valu");
1588
if($TypeDescr{$Version}{getTypeDeclId($ParamTypeId)}{$ParamTypeId}{"Name"} eq "void")
1593
$ParamListElemId = getNextElem($ParamListElemId);
1596
return ($Position>=1 and not $HaveVoid);
1599
sub getFuncParamTreeListId($)
1601
my $FuncTypeId = $_[0];
1602
if($LibInfo{$Version}{$FuncTypeId}{"info"} =~ /prms[ ]*:[ ]*@([0-9]+) /)
1614
my ($Id, $Attr) = @_;
1615
if($LibInfo{$Version}{$Id}{"info"} =~ /$Attr[ ]*:[ ]*@([0-9]+) /)
1625
sub getRestrictBase($)
1628
my $TypeDeclId = getTypeDeclId($TypeId);
1629
my $BaseTypeId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"Tid"};
1630
my $BaseTypeDeclId = $TypeDescr{$Version}{$TypeDeclId}{$TypeId}{"BaseType"}{"TDid"};
1634
sub setFuncAccess($)
1636
my $FuncInfoId = $_[0];
1637
if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
1640
if($Access eq "prot")
1642
$FuncDescr{$Version}{$FuncInfoId}{"Protected"} = 1;
1644
elsif($Access eq "priv")
1646
$FuncDescr{$Version}{$FuncInfoId}{"Private"} = 1;
1651
sub setTypeAccess($$)
1653
my ($TypeId, $TypeAttr) = @_;
1654
my $TypeInfo = $LibInfo{$Version}{$TypeId}{"info"};
1655
if($TypeInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
1658
if($Access eq "prot")
1660
$TypeAttr->{"Protected"} = 1;
1662
elsif($Access eq "priv")
1664
$TypeAttr->{"Private"} = 1;
1671
my $FuncInfoId = $_[0];
1672
if($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /pseudo tmpl/)
1674
$FuncDescr{$Version}{$FuncInfoId}{"PseudoTemplate"} = 1;
1676
elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*constructor /)
1678
$FuncDescr{$Version}{$FuncInfoId}{"Constructor"} = 1;
1680
elsif($LibInfo{$Version}{$FuncInfoId}{"info"} =~ /note[ ]*:[ ]*destructor /)
1682
$FuncDescr{$Version}{$FuncInfoId}{"Destructor"} = 1;
1688
my $FuncInfoId = $_[0];
1689
my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1690
if($FuncInfo =~ m/spec[ ]*:[ ]*pure /)
1694
elsif($FuncInfo =~ m/spec[ ]*:[ ]*virt /)
1700
if($FuncInfo =~ /spec[ ]*:[ ]*([a-zA-Z]+) /)
1713
my $FuncInfoId = $_[0];
1714
my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1715
if($FuncInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
1727
my $FuncInfoId = $_[0];
1728
my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1729
if($FuncInfo =~ /link[ ]*:[ ]*static /)
1735
if($FuncInfo =~ /link[ ]*:[ ]*([a-zA-Z]+) /)
1748
my $FuncInfoId = $_[0];
1749
my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1750
if($FuncInfo =~ /chan[ ]*:[ ]*@([0-9]+) /)
1760
sub getFuncParamInfoId($)
1762
my $FuncInfoId = $_[0];
1763
my $FuncInfo = $LibInfo{$Version}{$FuncInfoId}{"info"};
1764
if($FuncInfo =~ /args[ ]*:[ ]*@([0-9]+) /)
1774
sub getFuncParamType($)
1776
my $ParamInfoId = $_[0];
1777
my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
1778
if($ParamInfo =~ /type[ ]*:[ ]*@([0-9]+) /)
1788
sub getFuncParamName($)
1790
my $ParamInfoId = $_[0];
1791
my $ParamInfo = $LibInfo{$Version}{$ParamInfoId}{"info"};
1792
return "" if($ParamInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
1793
my $NameInfoId = $1;
1794
return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1795
my $FuncParamName = $1;
1796
$FuncParamName =~ s/[ ]+\Z//g;
1797
return $FuncParamName;
1800
sub getEnumMembInfoId($)
1802
my $TypeInfoId = $_[0];
1803
my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1804
if($TypeInfo =~ /csts[ ]*:[ ]*@([0-9]+) /)
1814
sub getStructMembInfoId($)
1816
my $TypeInfoId = $_[0];
1817
my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1818
if($TypeInfo =~ /flds[ ]*:[ ]*@([0-9]+) /)
1830
my $TypeInfoId = $_[0];
1831
my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1832
return "" if($TypeInfo !~ /scpe[ ]*:[ ]*@([0-9]+) /);
1833
my $NameSpaceInfoId = $1;
1834
if($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "namespace_decl")
1836
my $NameSpaceInfo = $LibInfo{$Version}{$NameSpaceInfoId}{"info"};
1837
if($NameSpaceInfo =~ /name[ ]*:[ ]*@([0-9]+) /)
1839
my $NameSpaceId = $1;
1840
my $NameSpaceIdentifier = $LibInfo{$Version}{$NameSpaceId}{"info"};
1841
return "" if($NameSpaceIdentifier !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1843
$NameSpace =~ s/[ ]+\Z//g;
1844
my $BaseNameSpace = getNameSpace($NameSpaceInfoId);
1845
$NameSpace = $BaseNameSpace."::".$NameSpace if($BaseNameSpace);
1853
elsif($LibInfo{$Version}{$NameSpaceInfoId}{"info_type"} eq "record_type")
1855
my %NameSpaceAttr = getTypeAttr(getTypeDeclId($NameSpaceInfoId), $NameSpaceInfoId);
1856
return $NameSpaceAttr{"Name"};
1864
sub getNameSpaceId($)
1866
my $TypeInfoId = $_[0];
1867
my $TypeInfo = $LibInfo{$Version}{$TypeInfoId}{"info"};
1868
if($TypeInfo =~ /scpe[ ]*:[ ]*@([0-9]+) /)
1878
sub getEnumMembName($)
1880
my $TypeMembInfoId = $_[0];
1881
return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /purp[ ]*:[ ]*@([0-9]+)/);
1883
return "" if($LibInfo{$Version}{$Purp}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1884
my $EnumMembName = $1;
1885
$EnumMembName =~ s/[ ]+\Z//g;
1886
return $EnumMembName;
1889
sub getStructMembName($)
1891
my $TypeMembInfoId = $_[0];
1892
return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /name[ ]*:[ ]*@([0-9]+) /);
1893
my $NameInfoId = $1;
1894
return "" if($LibInfo{$Version}{$NameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
1895
my $StructMembName = $1;
1896
$StructMembName =~ s/[ ]+\Z//g;
1897
return $StructMembName;
1900
sub getEnumMembVal($)
1902
my $TypeMembInfoId = $_[0];
1903
return "" if($LibInfo{$Version}{$TypeMembInfoId}{"info"} !~ /valu[ ]*:[ ]*@([0-9]+) /);
1905
if($LibInfo{$Version}{$Valu}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
1917
my $Info = $LibInfo{$Version}{$_[0]}{"info"};
1918
if($Info =~ /size[ ]*:[ ]*@([0-9]+) /)
1920
my $SizeInfoId = $1;
1921
if($LibInfo{$Version}{$SizeInfoId}{"info"} =~ /low[ ]*:[ ]*(-?[0-9]+) /)
1936
sub getStructMembType($)
1938
my $TypeMembInfoId = $_[0];
1939
if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /type[ ]*:[ ]*@([0-9]+) /)
1949
sub getStructMembBitFieldSize($)
1951
my $TypeMembInfoId = $_[0];
1952
if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ / bitfield /)
1954
return getSize($TypeMembInfoId);
1962
sub getStructMembAccess($)
1964
my $MembInfo = $LibInfo{$Version}{$_[0]}{"info"};
1965
if($MembInfo =~ /accs[ ]*:[ ]*([a-zA-Z]+) /)
1968
if($Access eq "prot")
1972
elsif($Access eq "priv")
1987
sub getNextMembInfoId($)
1989
my $TypeMembInfoId = $_[0];
1990
if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
2000
sub getNextStructMembInfoId($)
2002
my $TypeMembInfoId = $_[0];
2003
if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /chan[ ]*:[ ]*@([0-9]+) /)
2015
my $TypeMembInfoId = $_[0];
2016
if($LibInfo{$Version}{$TypeMembInfoId}{"info_type"} eq "field_decl")
2018
if($LibInfo{$Version}{$TypeMembInfoId}{"info"} =~ /name[ ]*:[ ]*@([0-9]+) /)
2033
sub getTypeHeader($)
2035
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2036
if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2046
sub register_header($$$)
2048
my ($Destination, $Position, $LibVersion) = @_;
2049
return if(not $Destination);
2050
if($Destination=~/\A\// and not -f $Destination)
2052
print "\nERROR: specified header \'$Destination\' does not exist\n";
2055
my $Header_Name = get_FileName($Destination);
2056
$Headers{$LibVersion}{$Destination}{"Name"} = $Header_Name;
2057
$Headers{$LibVersion}{$Destination}{"Position"} = $Position;
2058
$Headers{$LibVersion}{$Destination}{"Identity"} = $Destination;
2059
$HeaderName_Destinations{$LibVersion}{$Header_Name}{$Destination} = 1;
2064
my $LibVersion = $_[0];
2065
foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Include_Paths"}))
2067
$Dest =~ s/\A\s+|\s+\Z//g;
2071
print "ERROR: can't access \'$Dest\'\n";
2073
$Header_Dependency{$LibVersion}{$Dest} = 1;
2075
foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
2076
{#fill %Header_Dependency
2079
foreach my $Dir (cmd_find($Dest,"d",""))
2082
$Header_Dependency{$LibVersion}{$Dir} = 1;
2087
$Header_Dependency{$LibVersion}{get_Dir($Dest)} = 1;
2091
foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Headers"}))
2093
$Dest =~ s/\A\s+|\s+\Z//g;
2095
if(is_header($Dest, $LibVersion))
2097
register_header($Dest, $Position, $LibVersion);
2102
foreach my $Destination (sort {lc($a) cmp lc($b)} (cmd_find($Dest,"f","")))
2104
chomp($Destination);
2105
next if(not is_header($Destination, $LibVersion));
2106
register_header($Destination, $Position, $LibVersion);
2112
print "WARNING: \'$Dest\' was not found in the specified include paths\n";
2113
register_header($Dest, $Position, $LibVersion);
2117
if(keys(%{$Headers{$LibVersion}})==1)
2119
my $Destination = (keys(%{$Headers{$LibVersion}}))[0];
2120
$Headers{$LibVersion}{$Destination}{"Identity"} = $Headers{$LibVersion}{$Destination}{"Name"};
2122
foreach my $Header_Name (keys(%{$HeaderName_Destinations{$LibVersion}}))
2123
{#set relative paths (for dublicates)
2124
if(keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}})>1)
2126
my $FirstDest = (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))[0];
2127
my $Prefix = get_Dir($FirstDest);
2128
while($Prefix =~ /\A(.+)\/[^\/]+\Z/)
2131
my $Changes_Number = 0;
2133
foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
2135
if($Dest =~ /\A$Prefix\/(.*)\Z/)
2137
$Identity{$Dest} = $1;
2141
if($Changes_Number eq keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
2143
foreach my $Dest (keys(%{$HeaderName_Destinations{$LibVersion}{$Header_Name}}))
2145
$Headers{$LibVersion}{$Dest}{"Identity"} = $Identity{$Dest};
2149
$Prefix = $NewPrefix;
2153
if(not keys(%{$Headers{$LibVersion}}))
2155
print "ERROR: header files were not found\n";
2163
if($Path =~ /\A(.*\/)([^\/]*)\Z/)
2176
return "" if($Path =~ m*\A\./*);
2177
if($Path =~ /\A(.*)\/([^\/]*)\Z/)
2190
$Str =~ s/([()\[\]{}$ &'"`;,<>])/\\$1/g;
2196
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2197
if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2209
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2210
if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2222
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2223
if($TypeInfo =~ /srcp[ ]*:[ ]*([0-9a-zA-Z\_\-\<\>\.\+]+):([0-9]+) /)
2235
my ($TypeDeclId, $TypeId) = @_;
2236
return "Const" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*c / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
2237
return "Typedef" if($LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:/ and $LibInfo{$Version}{$TypeId}{"info"} !~ /qual[ ]*:/);
2238
return "Volatile" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*v / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
2239
return "Restrict" if($LibInfo{$Version}{$TypeId}{"info"} =~ /qual[ ]*:[ ]*r / and $LibInfo{$Version}{$TypeId}{"info"} =~ /unql[ ]*:[ ]*\@/);
2240
my $TypeType = getTypeTypeByTypeId($TypeId);
2241
if($TypeType eq "Struct")
2243
if($TypeDeclId and $LibInfo{$Version}{$TypeDeclId}{"info_type"} eq "template_decl")
2259
sub getTypeTypeByTypeId($)
2262
my $TypeType = $LibInfo{$Version}{$TypeId}{"info_type"};
2263
if($TypeType =~ /integer_type|real_type|boolean_type|void_type|complex_type/)
2267
elsif(isFuncPtr($TypeId))
2271
elsif($TypeType eq "pointer_type")
2275
elsif($TypeType eq "reference_type")
2279
elsif($TypeType eq "union_type")
2283
elsif($TypeType eq "enumeral_type")
2287
elsif($TypeType eq "record_type")
2291
elsif($TypeType eq "array_type")
2295
elsif($TypeType eq "complex_type")
2299
elsif($TypeType eq "function_type")
2301
return "FunctionType";
2303
elsif($TypeType eq "method_type")
2305
return "MethodType";
2313
sub getNameByInfo($)
2315
my $TypeInfo = $LibInfo{$Version}{$_[0]}{"info"};
2316
return "" if($TypeInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
2317
my $TypeNameInfoId = $1;
2318
return "" if($LibInfo{$Version}{$TypeNameInfoId}{"info"} !~ /strg[ ]*:[ ]*(.*)[ ]+lngt/);
2320
$TypeName =~ s/[ ]+\Z//g;
2324
sub getFuncShortName($)
2326
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2327
if($FuncInfo =~ / operator /)
2329
if($FuncInfo =~ /note[ ]*:[ ]*conversion /)
2331
return "operator ".get_TypeName($FuncDescr{$Version}{$_[0]}{"Return"});
2335
return "" if($FuncInfo !~ / operator[ ]+([a-zA-Z]+) /);
2336
return "operator".$Operator_Indication{$1};
2341
return "" if($FuncInfo !~ /name[ ]*:[ ]*@([0-9]+) /);
2342
my $FuncNameInfoId = $1;
2343
return "" if($LibInfo{$Version}{$FuncNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+lngt/);
2348
sub getFuncMnglName($)
2350
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2351
return "" if($FuncInfo !~ /mngl[ ]*:[ ]*@([0-9]+) /);
2352
my $FuncMnglNameInfoId = $1;
2353
return "" if($LibInfo{$Version}{$FuncMnglNameInfoId}{"info"} !~ /strg[ ]*:[ ]*([^ ]*)[ ]+/);
2354
my $FuncMnglName = $1;
2355
$FuncMnglName =~ s/[ ]+\Z//g;
2356
return $FuncMnglName;
2359
sub getFuncReturn($)
2361
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2362
return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
2363
my $FuncTypeInfoId = $1;
2364
return "" if($LibInfo{$Version}{$FuncTypeInfoId}{"info"} !~ /retn[ ]*:[ ]*@([0-9]+) /);
2365
my $FuncReturnTypeId = $1;
2366
if($TypeDescr{$Version}{getTypeDeclId($FuncReturnTypeId)}{$FuncReturnTypeId}{"Type"} eq "Restrict")
2367
{#delete restrict spec
2368
$FuncReturnTypeId = getRestrictBase($FuncReturnTypeId);
2370
return $FuncReturnTypeId;
2375
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2376
if($FuncInfo =~ /orig[ ]*:[ ]*@([0-9]+) /)
2386
sub unmangleArray(@)
2388
if($#_>$MAX_COMMAND_LINE_ARGUMENTS)
2390
my @Half = splice(@_, 0, ($#_+1)/2);
2391
return (unmangleArray(@Half), unmangleArray(@_))
2395
my $UnmangleCommand = "c++filt ".join(" ", @_);
2396
return split("\n", `$UnmangleCommand`);
2400
sub get_Signature($$)
2402
my ($Interface, $LibVersion) = @_;
2403
return $Cache{"get_Signature"}{$Interface}{$LibVersion} if($Cache{"get_Signature"}{$Interface}{$LibVersion});
2404
my ($MnglName, $SymbolVersion) = ($Interface, "");
2405
if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
2407
($MnglName, $SymbolVersion) = ($1, $2);
2409
if($MnglName =~ /\A(_ZGV|_ZTI|_ZTS|_ZTT|_ZTV|_ZThn|_ZTv0_n)/)
2411
$Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
2412
return $Cache{"get_Signature"}{$Interface}{$LibVersion};
2414
if(not $CompleteSignature{$LibVersion}{$Interface})
2416
if($Interface =~ /\A_Z/)
2418
$Cache{"get_Signature"}{$Interface}{$LibVersion} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
2419
return $Cache{"get_Signature"}{$Interface}{$LibVersion};
2423
$Cache{"get_Signature"}{$Interface}{$LibVersion} = $Interface;
2427
my ($Func_Signature, @Param_Types_FromUnmangledName) = ();
2428
my $ShortName = $CompleteSignature{$LibVersion}{$Interface}{"ShortName"};
2429
if($Interface =~ /\A_Z/)
2431
if($CompleteSignature{$LibVersion}{$Interface}{"Class"})
2433
$Func_Signature = get_TypeName($CompleteSignature{$LibVersion}{$Interface}{"Class"}, $LibVersion)."::".(($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})?"~":"").$ShortName;
2437
$Func_Signature = $ShortName;
2439
@Param_Types_FromUnmangledName = get_Signature_Parts($tr_name{$MnglName}, 0);
2443
$Func_Signature = $MnglName;
2445
my @ParamArray = ();
2446
foreach my $Pos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{$LibVersion}{$Interface}{"Param"}}))
2448
next if($Pos eq "");
2449
my $ParamTypeId = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"type"};
2450
my $ParamTypeName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ParamTypeId}}{$ParamTypeId}{"Name"};
2451
$ParamTypeName = $Param_Types_FromUnmangledName[$Pos] if(not $ParamTypeName);
2452
if(my $ParamName = $CompleteSignature{$LibVersion}{$Interface}{"Param"}{$Pos}{"name"})
2454
if($ParamTypeName=~/\([*]+\)/)
2456
$ParamTypeName=~s/\(([*]+)\)/\($1$ParamName\)/;
2457
push(@ParamArray, $ParamTypeName);
2461
push(@ParamArray, $ParamTypeName." ".$ParamName);
2466
push(@ParamArray, $ParamTypeName);
2469
if(not $CompleteSignature{$LibVersion}{$Interface}{"Data"})
2471
if($Interface=~/\A_Z/)
2473
if($CompleteSignature{$LibVersion}{$Interface}{"Constructor"})
2475
if($Interface=~/C1/)
2477
$Func_Signature .= " [in-charge]";
2479
elsif($Interface=~/C2/)
2481
$Func_Signature .= " [not-in-charge]";
2484
elsif($CompleteSignature{$LibVersion}{$Interface}{"Destructor"})
2486
if($Interface=~/D1/)
2488
$Func_Signature .= " [in-charge]";
2490
elsif($Interface=~/D2/)
2492
$Func_Signature .= " [not-in-charge]";
2494
elsif($Interface=~/D0/)
2496
$Func_Signature .= " [in-charge-deleting]";
2500
$Func_Signature .= " (".join(", ", @ParamArray).")";
2502
if($Interface=~/\A_ZNK/)
2504
$Func_Signature .= " const";
2506
$Func_Signature .= "\@".$SymbolVersion if($SymbolVersion);
2507
$Cache{"get_Signature"}{$Interface}{$LibVersion} = $Func_Signature;
2508
return $Func_Signature;
2511
sub getVarNameByAttr($)
2513
my $FuncInfoId = $_[0];
2515
return "" if(not $FuncDescr{$Version}{$FuncInfoId}{"ShortName"});
2516
if($FuncDescr{$Version}{$FuncInfoId}{"Class"})
2518
$VarName .= $TypeDescr{$Version}{getTypeDeclId($FuncDescr{$Version}{$FuncInfoId}{"Class"})}{$FuncDescr{$Version}{$FuncInfoId}{"Class"}}{"Name"};
2521
$VarName .= $FuncDescr{$Version}{$FuncInfoId}{"ShortName"};
2525
sub mangleFuncName($)
2532
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2533
return "" if($FuncInfo !~ /type[ ]*:[ ]*@([0-9]+) /);
2534
my $FuncTypeInfoId = $1;
2535
my $FunctionType = $LibInfo{$Version}{$FuncTypeInfoId}{"info_type"};
2536
if($FunctionType eq "method_type")
2540
elsif($FunctionType eq "function_type")
2546
return $FunctionType;
2550
sub getFuncTypeId($)
2552
my $FuncInfo = $LibInfo{$Version}{$_[0]}{"info"};
2553
if($FuncInfo =~ /type[ ]*:[ ]*@([0-9]+)( |\Z)/)
2565
return (not isAnon($_[0]));
2570
return (($_[0] =~ m/\.\_[0-9]+/) or ($_[0] =~ m/anon-/));
2573
sub unmangled_Compact($$)
2574
#Removes all non-essential (for C++ language) whitespace from a string. If
2575
#the whitespace is essential it will be replaced with exactly one ' '
2576
#character. Works correctly only for unmangled names.
2577
#If level > 1 is supplied, can relax its intent to compact the string.
2580
my $level = $_[1] || 1;
2581
my $o1 = ($level>1)?' ':'';
2582
#First, we reduce all spaces that we can
2583
my $coms='[-()<>:*&~!|+=%@~"?.,/[^'."']";
2584
my $coms_nobr='[-()<:*&~!|+=%@~"?.,'."']";
2585
my $clos='[),;:\]]';
2586
$result=~s/^\s+//gm;
2587
$result=~s/\s+$//gm;
2588
$result=~s/((?!\n)\s)+/ /g;
2589
$result=~s/(\w+)\s+($coms+)/$1$o1$2/gm;
2590
#$result=~s/(\w)(\()/$1$o1$2/gm if $o1;
2591
$result=~s/($coms+)\s+(\w+)/$1$o1$2/gm;
2592
$result=~s/(\()\s+(\w)/$1$2/gm if $o1;
2593
$result=~s/(\w)\s+($clos)/$1$2/gm;
2594
$result=~s/($coms+)\s+($coms+)/$1 $2/gm;
2595
$result=~s/($coms_nobr+)\s+($coms+)/$1$o1$2/gm;
2596
$result=~s/($coms+)\s+($coms_nobr+)/$1$o1$2/gm;
2597
#don't forget about >> and <:. In unmangled names global-scope modifier
2598
#is not used, so <: will always be a digraph and requires no special treatment.
2599
#We also try to remove other parts that are better to be removed here than in other places
2601
$result=~s/\bconst\s+const\b/const/gm;
2602
$result=~s/\bvolatile\s+volatile\b/volatile/gm;
2603
$result=~s/\bconst\s+volatile\b\s+const\b/const volatile/gm;
2604
$result=~s/\bvolatile\s+const\b\s+volatile\b/const volatile/gm;
2605
#Place cv in proper order
2606
$result=~s/\bvolatile\s+const\b/const volatile/gm;
2610
sub unmangled_PostProcess($)
2613
#s/\bunsigned int\b/unsigned/g;
2614
$result =~ s/\bshort unsigned int\b/unsigned short/g;
2615
$result =~ s/\bshort int\b/short/g;
2616
$result =~ s/\blong long unsigned int\b/unsigned long long/g;
2617
$result =~ s/\blong unsigned int\b/unsigned long/g;
2618
$result =~ s/\blong long int\b/long long/g;
2619
$result =~ s/\blong int\b/long/g;
2620
$result =~ s/\)const\b/\) const/g;
2621
$result =~ s/\blong long unsigned\b/unsigned long long/g;
2622
$result =~ s/\blong unsigned\b/unsigned long/g;
2626
# From libtodb2/libtodb.pm
2627
# Trim string spaces.
2631
$string =~ s/^\s+//;
2632
$string =~ s/\s+$//;
2637
{#type name correction
2638
my $CorrectName = $_[0];
2639
$CorrectName = unmangled_Compact($CorrectName, 1);
2640
$CorrectName = unmangled_PostProcess($CorrectName);
2641
return $CorrectName;
2644
sub getDump_AllInOne()
2646
return if(not keys(%Headers));
2647
`mkdir -p temp && rm -f temp/*`;
2648
my $Header_Depend = "";
2649
foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
2651
$Header_Depend .= " -I".esc($Dep);
2653
my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
2654
open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
2655
foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
2657
print LIB_HEADER "#include <$Preamble_Header>\n";
2659
foreach my $Destination (sort {int($Headers{$Version}{$a}{"Position"})<=>int($Headers{$Version}{$b}{"Position"})} keys(%{$Headers{$Version}}))
2661
my $HName = get_FileName($Destination);
2662
next if($Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$HName} and $HeaderName_Destinations{$Version}{$HName} and keys(%{$HeaderName_Destinations{$Version}{$HName}})==1));
2663
print LIB_HEADER "#include <$Destination>\n";
2666
system("g++ >".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
2669
print "WARNING: some errors have occured while compiling header(s), fix it first!\nyou can see compilation errors in the file \'$ERR_PATH{$Version}\'\n";
2671
$ConstantsSrc{$Version} = cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
2672
system("mkdir", "-p", "header_compile_errors/$TargetLibraryName/temp/");
2673
system("cp", "-f", "temp/$TargetLibraryName"."_v$Version.h", "header_compile_errors/$TargetLibraryName/temp/");
2674
return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
2677
sub getDump_Separately($)
2681
my $Destination = $_[0];
2682
my $Header_Depend = "";
2683
foreach my $Dep (sort {length($a) <=> length($b)} keys(%{$Header_Dependency{$Version}}))
2685
$Header_Depend .= " -I".esc($Dep);
2687
my $Lib_VersionName = esc($TargetLibraryName)."_v".$Version;
2688
open(LIB_HEADER, ">temp/$TargetLibraryName"."_v$Version.h");
2689
foreach my $Preamble_Header (sort {int($Include_Preamble{$Version}{$a}{"Position"})<=>int($Include_Preamble{$Version}{$b}{"Position"})} keys(%{$Include_Preamble{$Version}}))
2691
print LIB_HEADER "#include <$Preamble_Header>\n";
2693
my $Destination_HName = get_FileName($Destination);
2694
if(not ( $Include_Preamble{$Version}{$Destination} or ($Include_Preamble{$Version}{$Destination_HName} and $HeaderName_Destinations{$Version}{$Destination_HName} and keys(%{$HeaderName_Destinations{$Version}{$Destination_HName}})==1) ))
2696
print LIB_HEADER "#include <$Destination>\n";
2699
system("g++ >>".esc($ERR_PATH{$Version})." 2>&1 -fdump-translation-unit temp/$Lib_VersionName.h $CompilerOptions{$Version} $Header_Depend");
2702
$HeaderCompileError{get_FileName($Destination)} = 1;
2704
$ConstantsSrc{$Version} .= cmd_preprocessor("temp/$Lib_VersionName.h", $CompilerOptions{$Version}." ".$Header_Depend, "define\\ \\|undef\\ \\|#[ ]\\+[0-9]\\+ \".*\"");
2705
return (split("\n", `find . -maxdepth 1 -name "$Lib_VersionName\.h*\.tu"`))[0];
2711
return "" if(not $Path or not -e $Path);
2712
my $Cmd = "file ".esc($Path);
2713
my $Cmd_Out = `$Cmd`;
2717
sub cmd_preprocessor($$$)
2719
my ($Path, $AddOpt, $Grep) = @_;
2720
return "" if(not $Path or not -f $Path);
2721
my $Cmd = "g++ -dD -E -x c++-header ".esc($Path)." 2>/dev/null $AddOpt";
2724
$Cmd .= " | grep \"$Grep\"";
2726
my $Cmd_Out = `$Cmd`;
2732
my ($Path, $Grep) = @_;
2733
return "" if(not $Path or not -e $Path);
2734
my $Cmd = "cat ".esc($Path);
2737
$Cmd .= " | grep \"$Grep\"";
2739
my $Cmd_Out = `$Cmd`;
2745
my ($Path, $Type, $Name) = @_;
2746
return () if(not $Path or not -e $Path);
2747
my $Cmd = "find ".esc($Path);
2750
$Cmd .= " -type $Type";
2754
$Cmd .= " -name \"$Name\"";
2756
return split("\n", `$Cmd`);
2762
return "" if(not $Path or not -e $Path);
2763
my $Cmd = "tar -xvzf ".esc($Path);
2764
my $Cmd_Out = `$Cmd`;
2770
my ($Destination, $LibVersion) = @_;
2771
return 0 if(-d $Destination);
2772
return 1 if($Destination =~ /\.(h|hh|hhh|hpp|tcc)\Z/i);
2773
return 0 if($Destination =~ /\.\w+\Z/i);#cpp|c|gch|tu|fs|pas
2774
if($Destination =~ /\A\//)
2776
return (cmd_file($Destination) =~ /:[ ]*ASCII C[\+]* program text/);
2780
foreach my $Prefix (keys(%{$Header_Dependency{$LibVersion}}))
2782
my $Path = $Prefix."/".$Destination;
2785
if(cmd_file($Path) =~ /:[ ]*ASCII C[\+]* program text/)
2795
sub parseHeaders_AllInOne($)
2798
print "checking header(s) ".$Descriptor{$Version}{"Version"}." ...\n";
2799
system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
2800
system("rm", "-fr", $ERR_PATH{$Version});
2801
my $DumpPath = getDump_AllInOne();
2804
print "\nERROR: can't create gcc syntax tree for header(s)\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
2809
system("rm", "-fr", "temp");
2814
my $Destination = $_[0];
2815
my $DumpPath = getDump_Separately($Destination);
2818
print "ERROR: can't create gcc syntax tree for header\nyou can see compilation errors in the file '$ERR_PATH{$Version}'\n";
2823
system("rm", "-fr", "temp");
2826
sub is_in_library($$)
2828
my ($MnglName, $LibVersion) = @_;
2829
return ($Interface_Library{$LibVersion}{$MnglName} or ($SymVer{$LibVersion}{$MnglName} and $Interface_Library{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}));
2832
sub prepareInterfaces($)
2834
my $LibVersion = $_[0];
2835
my (@MnglNames, @UnMnglNames) = ();
2836
if($CheckHeadersOnly)
2838
foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
2840
if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
2842
push(@MnglNames, $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"});
2845
if($#MnglNames > -1)
2847
@UnMnglNames = reverse(unmangleArray(@MnglNames));
2848
foreach my $FuncInfoId (sort keys(%{$FuncDescr{$LibVersion}}))
2850
if($FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"} =~ /\A_Z/)
2852
my $UnmangledName = pop(@UnMnglNames);
2853
$tr_name{$FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"}} = $UnmangledName;
2858
my (%NotMangled_Int, %Mangled_Int) = ();
2859
foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
2861
my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
2862
if($MnglName=~/\A_Z/)
2864
$Mangled_Int{$FuncInfoId} = $MnglName;
2868
$NotMangled_Int{$FuncInfoId} = $MnglName;
2870
next if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly);
2871
next if($MnglName =~ /\A_Z/ and $tr_name{$MnglName} =~ /\.\_[0-9]/);
2872
next if(not $FuncDescr{$LibVersion}{$FuncInfoId}{"Header"});
2873
%{$CompleteSignature{$LibVersion}{$MnglName}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
2874
#interface and its symlink have same signatures
2875
if($SymVer{$LibVersion}{$MnglName})
2877
%{$CompleteSignature{$LibVersion}{$SymVer{$LibVersion}{$MnglName}}} = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
2879
delete($FuncDescr{$LibVersion}{$FuncInfoId});
2881
if(keys(%Mangled_Int))
2883
foreach my $Interface_Id (keys(%NotMangled_Int))
2885
delete($CompleteSignature{$LibVersion}{$NotMangled_Int{$Interface_Id}});
2893
my $LibVersion = $_[0];
2894
foreach my $FuncInfoId (keys(%{$FuncDescr{$LibVersion}}))
2896
my $MnglName = $FuncDescr{$LibVersion}{$FuncInfoId}{"MnglName"};
2897
if(not $MnglName or not is_in_library($MnglName, $LibVersion) and not $CheckHeadersOnly)
2899
delete($FuncDescr{$LibVersion}{$FuncInfoId});
2902
if(defined $InterfacesListPath and not $InterfacesList{$MnglName})
2904
delete($FuncDescr{$LibVersion}{$FuncInfoId});
2907
if(defined $AppPath and not $InterfacesList_App{$MnglName})
2909
delete($FuncDescr{$LibVersion}{$FuncInfoId});
2912
my %FuncInfo = %{$FuncDescr{$LibVersion}{$FuncInfoId}};
2913
detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Return"}}, $FuncInfo{"Return"}, $LibVersion);
2914
detect_TypeUsing($Tid_TDid{$LibVersion}{$FuncInfo{"Class"}}, $FuncInfo{"Class"}, $LibVersion);
2915
foreach my $Param_Pos (keys(%{$FuncInfo{"Param"}}))
2917
my $Param_TypeId = $FuncInfo{"Param"}{$Param_Pos}{"type"};
2918
detect_TypeUsing($Tid_TDid{$LibVersion}{$Param_TypeId}, $Param_TypeId, $LibVersion);
2921
foreach my $TDid (keys(%{$TypeDescr{$LibVersion}}))
2923
foreach my $Tid (keys(%{$TypeDescr{$LibVersion}{$TDid}}))
2925
if(not $UsedType{$LibVersion}{$TDid}{$Tid})
2927
delete($TypeDescr{$LibVersion}{$TDid}{$Tid});
2928
if(not keys(%{$TypeDescr{$LibVersion}{$TDid}}))
2930
delete($TypeDescr{$LibVersion}{$TDid});
2932
delete($Tid_TDid{$LibVersion}{$Tid}) if($Tid_TDid{$LibVersion}{$Tid} eq $TDid);
2938
sub detect_TypeUsing($$$)
2940
my ($TypeDeclId, $TypeId, $LibVersion) = @_;
2941
return if($UsedType{$LibVersion}{$TypeDeclId}{$TypeId});
2942
my %Type = get_Type($TypeDeclId, $TypeId, $LibVersion);
2943
if($Type{"Type"} =~ /Struct|Union|Class|FuncPtr|Enum/)
2945
$UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
2946
foreach my $Memb_Pos (keys(%{$Type{"Memb"}}))
2948
my $Member_TypeId = $Type{"Memb"}{$Memb_Pos}{"type"};
2949
detect_TypeUsing($Tid_TDid{$LibVersion}{$Member_TypeId}, $Member_TypeId, $LibVersion);
2951
if($Type{"Type"} eq "FuncPtr")
2953
my $ReturnType = $Type{"Return"};
2954
detect_TypeUsing($Tid_TDid{$LibVersion}{$ReturnType}, $ReturnType, $LibVersion);
2957
elsif($Type{"Type"} =~ /Const|Pointer|Ref|Volatile|Restrict|Array|/)
2959
$UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
2960
detect_TypeUsing($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
2962
elsif($Type{"Type"} eq "Intrinsic")
2964
$UsedType{$LibVersion}{$TypeDeclId}{$TypeId} = 1;
2968
delete($TypeDescr{$LibVersion}{$TypeDeclId}{$TypeId});
2969
if(not keys(%{$TypeDescr{$LibVersion}{$TypeDeclId}}))
2971
delete($TypeDescr{$LibVersion}{$TypeDeclId});
2973
delete($Tid_TDid{$LibVersion}{$TypeId}) if($Tid_TDid{$LibVersion}{$TypeId} eq $TypeDeclId);
2977
sub initializeClassVirtFunc($)
2979
my $LibVersion = $_[0];
2980
foreach my $Interface (keys(%{$CompleteSignature{$LibVersion}}))
2982
if($CompleteSignature{$LibVersion}{$Interface}{"Virt"})
2984
my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{"Name"};
2985
$ClassVirtFunc{$LibVersion}{$ClassName}{$Interface} = 1;
2986
$ClassIdVirtFunc{$LibVersion}{$CompleteSignature{$LibVersion}{$Interface}{"Class"}}{$Interface} = 1;
2987
$ClassId{$LibVersion}{$ClassName} = $CompleteSignature{$LibVersion}{$Interface}{"Class"};
2992
sub checkVirtFuncRedefinitions($)
2994
my $LibVersion = $_[0];
2995
foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
2997
$CheckedTypes{$Class_Name} = 1;
2998
foreach my $VirtFuncName (keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
3000
$CompleteSignature{$LibVersion}{$VirtFuncName}{"VirtualRedefine"} = find_virtual_method_in_base_classes($VirtFuncName, $ClassId{$LibVersion}{$Class_Name}, $LibVersion);
3005
sub setVirtFuncPositions($)
3007
my $LibVersion = $_[0];
3008
foreach my $Class_Name (keys(%{$ClassVirtFunc{$LibVersion}}))
3010
$CheckedTypes{$Class_Name} = 1;
3012
foreach my $VirtFuncName (sort {int($CompleteSignature{$LibVersion}{$a}{"Line"}) <=> int($CompleteSignature{$LibVersion}{$b}{"Line"})} keys(%{$ClassVirtFunc{$LibVersion}{$Class_Name}}))
3014
if($ClassVirtFunc{1}{$Class_Name}{$VirtFuncName} and $ClassVirtFunc{2}{$Class_Name}{$VirtFuncName} and not $CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"} and not $CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
3016
$CompleteSignature{$LibVersion}{$VirtFuncName}{"Position"} = $Position;
3023
sub check_VirtualTable($$)
3025
my ($TargetFunction, $LibVersion) = @_;
3026
my $Class_Id = $CompleteSignature{$LibVersion}{$TargetFunction}{"Class"};
3027
my $Class_DId = $Tid_TDid{$LibVersion}{$Class_Id};
3028
my %Class_Type = get_Type($Class_DId, $Class_Id, $LibVersion);
3029
$CheckedTypes{$Class_Type{"Name"}} = 1;
3030
foreach my $VirtFuncName (keys(%{$ClassVirtFunc{2}{$Class_Type{"Name"}}}))
3032
if($ClassId{1}{$Class_Type{"Name"}} and not $ClassVirtFunc{1}{$Class_Type{"Name"}}{$VirtFuncName} and $AddedInt{$VirtFuncName})
3034
if($CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"})
3036
if($TargetFunction eq $VirtFuncName)
3038
my $BaseClass_Id = $CompleteSignature{2}{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
3039
my %BaseClass_Type = get_Type($Tid_TDid{2}{$BaseClass_Id}, $BaseClass_Id, 2);
3040
my $BaseClass_Name = $BaseClass_Type{"Name"};
3041
%{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition"}{$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}}}}=(
3042
"Type_Name"=>$Class_Type{"Name"},
3043
"Type_Type"=>$Class_Type{"Type"},
3044
"Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
3045
"Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
3046
"Target"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
3047
"Signature"=>$tr_name{$TargetFunction},
3048
"Old_Value"=>$tr_name{$CompleteSignature{2}{$VirtFuncName}{"VirtualRedefine"}},
3049
"New_Value"=>$tr_name{$TargetFunction},
3050
"Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3051
"New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3054
elsif($TargetFunction ne $VirtFuncName)
3056
%{$CompatProblems{$TargetFunction}{"Added_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
3057
"Type_Name"=>$Class_Type{"Name"},
3058
"Type_Type"=>$Class_Type{"Type"},
3059
"Header"=>$Class_Type{"Header"},
3060
"Line"=>$Class_Type{"Line"},
3061
"Target"=>$tr_name{$VirtFuncName},
3062
"Signature"=>$tr_name{$TargetFunction},
3063
"Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3064
"New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3068
foreach my $VirtFuncName (keys(%{$ClassVirtFunc{1}{$Class_Type{"Name"}}}))
3070
if($ClassId{2}{$Class_Type{"Name"}} and not $ClassVirtFunc{2}{$Class_Type{"Name"}}{$VirtFuncName} and $WithdrawnInt{$VirtFuncName})
3072
if($CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"})
3074
if($TargetFunction eq $VirtFuncName)
3076
my $BaseClass_Id = $CompleteSignature{1}{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}{"Class"};
3077
my $BaseClass_Name = $TypeDescr{1}{$Tid_TDid{1}{$BaseClass_Id}}{$BaseClass_Id}{"Name"};
3078
%{$CompatProblems{$TargetFunction}{"Virtual_Function_Redefinition_B"}{$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}}}}=(
3079
"Type_Name"=>$Class_Type{"Name"},
3080
"Type_Type"=>$Class_Type{"Type"},
3081
"Header"=>$CompleteSignature{2}{$TargetFunction}{"Header"},
3082
"Line"=>$CompleteSignature{2}{$TargetFunction}{"Line"},
3083
"Target"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
3084
"Signature"=>$tr_name{$TargetFunction},
3085
"Old_Value"=>$tr_name{$TargetFunction},
3086
"New_Value"=>$tr_name{$CompleteSignature{1}{$VirtFuncName}{"VirtualRedefine"}},
3087
"Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3088
"New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3093
%{$CompatProblems{$TargetFunction}{"Withdrawn_Virtual_Function"}{$tr_name{$VirtFuncName}}}=(
3094
"Type_Name"=>$Class_Type{"Name"},
3095
"Type_Type"=>$Class_Type{"Type"},
3096
"Header"=>$Class_Type{"Header"},
3097
"Line"=>$Class_Type{"Line"},
3098
"Target"=>$tr_name{$VirtFuncName},
3099
"Signature"=>$tr_name{$TargetFunction},
3100
"Old_SoName"=>$Interface_Library{1}{$TargetFunction},
3101
"New_SoName"=>$Interface_Library{2}{$TargetFunction} );
3107
sub find_virtual_method_in_base_classes($$$)
3109
my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
3110
foreach my $BaseClass_Id (keys(%{$TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$Checked_ClassId}}{$Checked_ClassId}{"BaseClass"}}))
3112
my $VirtMethodInClass = find_virtual_method_in_class($VirtFuncName, $BaseClass_Id, $LibVersion);
3113
if($VirtMethodInClass)
3115
return $VirtMethodInClass;
3117
my $VirtMethodInBaseClasses = find_virtual_method_in_base_classes($VirtFuncName, $BaseClass_Id, $LibVersion);
3118
if($VirtMethodInBaseClasses)
3120
return $VirtMethodInBaseClasses;
3126
sub find_virtual_method_in_class($$$)
3128
my ($VirtFuncName, $Checked_ClassId, $LibVersion) = @_;
3129
my $Suffix = getFuncSuffix($VirtFuncName, $LibVersion);
3130
foreach my $Checked_VirtFuncName (keys(%{$ClassIdVirtFunc{$LibVersion}{$Checked_ClassId}}))
3132
if($Suffix eq getFuncSuffix($Checked_VirtFuncName, $LibVersion)
3133
and ((not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} and not $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"} and $CompleteSignature{$LibVersion}{$VirtFuncName}{"ShortName"} eq $CompleteSignature{$LibVersion}{$Checked_VirtFuncName}{"ShortName"}) or ($CompleteSignature{$LibVersion}{$VirtFuncName}{"Constructor"} or $CompleteSignature{$LibVersion}{$VirtFuncName}{"Destructor"})))
3135
return $Checked_VirtFuncName;
3141
sub getFuncSuffix($$)
3143
my ($FuncName, $LibVersion) = @_;
3144
my $ClassId = $CompleteSignature{$LibVersion}{$FuncName}{"Class"};
3145
my $ClassName = $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$ClassId}}{$ClassId}{"Name"};
3146
my $ShortName = $CompleteSignature{$LibVersion}{$FuncName}{"ShortName"};
3147
my $Suffix = $tr_name{$FuncName};
3148
$Suffix =~ s/\A$ClassName\:\:[~]*$ShortName[ ]*//g;
3152
sub isRecurType($$$$)
3154
foreach (@RecurTypes)
3156
if($_->{"Tid1"} eq $_[0]
3157
and $_->{"TDid1"} eq $_[1]
3158
and $_->{"Tid2"} eq $_[2]
3159
and $_->{"TDid2"} eq $_[3])
3167
sub find_MemberPair_Pos_byName($$)
3169
my ($Member_Name, $Pair_Type) = @_;
3170
foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
3172
if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"name"} eq $Member_Name)
3174
return $MemberPair_Pos;
3180
sub getBitfieldSum($$)
3182
my ($Member_Pos, $Pair_Type) = @_;
3183
my $BitfieldSum = 0;
3184
while($Member_Pos>-1)
3186
return $BitfieldSum if(not $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"});
3187
$BitfieldSum += $Pair_Type->{"Memb"}{$Member_Pos}{"bitfield"};
3190
return $BitfieldSum;
3193
sub find_MemberPair_Pos_byVal($$)
3195
my ($Member_Value, $Pair_Type) = @_;
3196
foreach my $MemberPair_Pos (sort keys(%{$Pair_Type->{"Memb"}}))
3198
if($Pair_Type->{"Memb"}{$MemberPair_Pos}{"value"} eq $Member_Value)
3200
return $MemberPair_Pos;
3206
my %Priority_Value=(
3212
sub max_priority($$)
3214
my ($Priority1, $Priority2) = @_;
3215
if(cmp_priority($Priority1, $Priority2))
3225
sub cmp_priority($$)
3227
my ($Priority1, $Priority2) = @_;
3228
return ($Priority_Value{$Priority1}>$Priority_Value{$Priority2});
3231
sub set_Problems_Priority()
3233
foreach my $InterfaceName (sort keys(%CompatProblems))
3235
foreach my $Kind (sort keys(%{$CompatProblems{$InterfaceName}}))
3237
foreach my $Location (sort keys(%{$CompatProblems{$InterfaceName}{$Kind}}))
3239
my $IsInTypeInternals = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"IsInTypeInternals"};
3240
my $InitialType_Type = $CompatProblems{$InterfaceName}{$Kind}{$Location}{"InitialType_Type"};
3241
if($Kind eq "Function_Become_Static")
3243
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3245
elsif($Kind eq "Function_Become_NonStatic")
3247
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3249
elsif($Kind eq "Parameter_Type_And_Size")
3251
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3253
elsif($Kind eq "Parameter_Type")
3255
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3257
elsif($Kind eq "Withdrawn_Parameter")
3259
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3261
elsif($Kind eq "Added_Parameter")
3263
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3265
elsif($Kind eq "Parameter_BaseType_And_Size")
3267
if($InitialType_Type eq "Pointer")
3269
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3273
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3276
elsif($Kind eq "Parameter_BaseType")
3278
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3280
elsif($Kind eq "Parameter_PointerLevel")
3282
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3284
elsif($Kind eq "Return_Type_And_Size")
3286
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3288
elsif($Kind eq "Return_Type")
3290
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3292
elsif($Kind eq "Return_BaseType_And_Size")
3294
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3296
elsif($Kind eq "Return_BaseType")
3298
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3300
elsif($Kind eq "Return_PointerLevel")
3302
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3304
if($Kind eq "Added_Virtual_Function")
3306
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3308
elsif($Kind eq "Withdrawn_Virtual_Function")
3310
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3312
elsif($Kind eq "Virtual_Function_Position")
3314
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3316
elsif($Kind eq "Virtual_Function_Redefinition")
3318
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3320
elsif($Kind eq "Virtual_Function_Redefinition_B")
3322
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3324
elsif($Kind eq "Size")
3326
if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3328
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3332
if($IsInTypeInternals)
3334
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3338
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3342
elsif($Kind eq "BaseType")
3344
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3346
elsif($Kind eq "Added_Member_And_Size")
3348
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3350
elsif($Kind eq "Added_Middle_Member_And_Size")
3352
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3354
elsif($Kind eq "Withdrawn_Member_And_Size")
3356
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3358
elsif($Kind eq "Withdrawn_Member")
3360
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3362
elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
3364
if($IsInTypeInternals)
3366
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3370
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3373
elsif($Kind eq "Withdrawn_Middle_Member")
3375
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3377
elsif($Kind eq "Member_Rename")
3379
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3381
elsif($Kind eq "Enum_Member_Value")
3383
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3385
elsif($Kind eq "Enum_Member_Name")
3387
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3389
elsif($Kind eq "Member_Type_And_Size")
3391
if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3393
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3397
if($IsInTypeInternals)
3399
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3403
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3407
elsif($Kind eq "Member_Type")
3409
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3411
elsif($Kind eq "Member_BaseType_And_Size")
3413
if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3415
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3419
if($IsInTypeInternals)
3421
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3425
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "High";
3429
elsif($Kind eq "Member_BaseType")
3431
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3433
elsif($Kind eq "Member_PointerLevel")
3435
if(($InitialType_Type eq "Pointer") or ($InitialType_Type eq "Array"))
3437
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3441
if($IsInTypeInternals)
3443
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Low";
3447
$CompatProblems{$InterfaceName}{$Kind}{$Location}{"Priority"} = "Medium";
3458
my %TypeDescriptor=(
3463
push(@RecurTypes, \%TypeDescriptor);
3466
sub mergeTypes($$$$)
3468
my ($Type1_Id, $Type1_DId, $Type2_Id, $Type2_DId) = @_;
3469
my (%Sub_SubProblems, %SubProblems) = ();
3470
if((not $Type1_Id and not $Type1_DId) or (not $Type2_Id and not $Type2_DId))
3471
{#Not Empty Inputs Only
3474
if($Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId})
3476
return %{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}};
3478
my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
3479
my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
3480
my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
3481
my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
3482
return () if(not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"});
3483
if(isRecurType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"}))
3484
{#Recursive Declarations
3487
return if(not $Type1_Pure{"Name"} or not $Type2_Pure{"Name"});
3488
return if($OpaqueTypes{1}{$Type1_Pure{"Name"}} or $OpaqueTypes{2}{$Type1_Pure{"Name"}} or $OpaqueTypes{1}{$Type1{"Name"}} or $OpaqueTypes{2}{$Type1{"Name"}});
3490
my %Typedef_1 = goToFirst($Type1{"TDid"}, $Type1{"Tid"}, 1, "Typedef");
3491
my %Typedef_2 = goToFirst($Type2{"TDid"}, $Type2{"Tid"}, 2, "Typedef");
3492
if($Typedef_1{"Type"} eq "Typedef" and $Typedef_2{"Type"} eq "Typedef" and $Typedef_1{"Name"} eq $Typedef_2{"Name"})
3494
my %Base_1 = get_OneStep_BaseType($Typedef_1{"TDid"}, $Typedef_1{"Tid"}, 1);
3495
my %Base_2 = get_OneStep_BaseType($Typedef_2{"TDid"}, $Typedef_2{"Tid"}, 2);
3496
if($Base_1{"Name"}!~/anon\-/ and $Base_2{"Name"}!~/anon\-/
3497
and ($Base_1{"Name"} ne $Base_2{"Name"}))
3499
%{$SubProblems{"BaseType"}{$Typedef_1{"Name"}}}=(
3500
"Type_Name"=>$Typedef_1{"Name"},
3501
"Type_Type"=>"Typedef",
3502
"Header"=>$Typedef_2{"Header"},
3503
"Line"=>$Typedef_2{"Line"},
3504
"Old_Value"=>$Base_1{"Name"},
3505
"New_Value"=>$Base_2{"Name"} );
3509
if(($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} ne "Pointer") and $Type1_Pure{"Name"}!~/anon\-/)
3514
pushType($Type1_Pure{"Tid"}, $Type1_Pure{"TDid"}, $Type2_Pure{"Tid"}, $Type2_Pure{"TDid"});
3515
if(($Type1_Pure{"Name"} eq $Type2_Pure{"Name"}) and ($Type1_Pure{"Type"} =~ /Struct|Class|Union/))
3517
if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3519
%{$SubProblems{"Size"}{$Type1_Pure{"Name"}}}=(
3520
"Type_Name"=>$Type1_Pure{"Name"},
3521
"Type_Type"=>$Type1_Pure{"Type"},
3522
"Header"=>$Type2_Pure{"Header"},
3523
"Line"=>$Type2_Pure{"Line"},
3524
"Old_Value"=>$Type1_Pure{"Size"},
3525
"New_Value"=>$Type2_Pure{"Size"} );
3528
if($Type1_Pure{"Name"} and $Type2_Pure{"Name"} and ($Type1_Pure{"Name"} ne $Type2_Pure{"Name"}) and ($Type1_Pure{"Name"} !~ /\Avoid[ ]*\*/) and ($Type2_Pure{"Name"} =~ /\Avoid[ ]*\*/))
3533
if($Type1_Pure{"BaseType"}{"Tid"} and $Type2_Pure{"BaseType"}{"Tid"})
3535
%Sub_SubProblems = &mergeTypes($Type1_Pure{"BaseType"}{"Tid"}, $Type1_Pure{"BaseType"}{"TDid"}, $Type2_Pure{"BaseType"}{"Tid"}, $Type2_Pure{"BaseType"}{"TDid"});
3536
foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
3538
foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
3540
%{$SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}} = %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
3541
$SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}{"InitialType_Type"} = $Type1_Pure{"Type"};
3545
foreach my $Member_Pos (sort keys(%{$Type1_Pure{"Memb"}}))
3547
next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
3548
my $Member_Name = $Type1_Pure{"Memb"}{$Member_Pos}{"name"};
3549
next if(not $Member_Name);
3550
my $Member_Location = $Member_Name;
3551
my $MemberPair_Pos = find_MemberPair_Pos_byName($Member_Name, \%Type2_Pure);
3552
if(($MemberPair_Pos eq "lost") and (($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class")))
3554
if($Member_Pos > keys(%{$Type2_Pure{"Memb"}}) - 1)
3556
if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3558
%{$SubProblems{"Withdrawn_Member_And_Size"}{$Member_Name}}=(
3559
"Target"=>$Member_Name,
3560
"Type_Name"=>$Type1_Pure{"Name"},
3561
"Type_Type"=>$Type1_Pure{"Type"},
3562
"Header"=>$Type2_Pure{"Header"},
3563
"Line"=>$Type2_Pure{"Line"},
3564
"Old_Size"=>$Type1_Pure{"Size"},
3565
"New_Size"=>$Type2_Pure{"Size"} );
3569
%{$SubProblems{"Withdrawn_Member"}{$Member_Name}}=(
3570
"Target"=>$Member_Name,
3571
"Type_Name"=>$Type1_Pure{"Name"},
3572
"Type_Type"=>$Type1_Pure{"Type"},
3573
"Header"=>$Type2_Pure{"Header"},
3574
"Line"=>$Type2_Pure{"Line"} );
3578
elsif($Member_Pos < keys(%{$Type1_Pure{"Memb"}}) - 1)
3580
my $MemberType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
3581
my %MemberType_Pure = get_PureType($Tid_TDid{1}{$MemberType_Id}, $MemberType_Id, 1);
3582
my $MemberStraightPairType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
3583
my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{2}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 2);
3585
if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure) eq "lost")
3587
%{$SubProblems{"Member_Rename"}{$Member_Name}}=(
3588
"Target"=>$Member_Name,
3589
"Type_Name"=>$Type1_Pure{"Name"},
3590
"Type_Type"=>$Type1_Pure{"Type"},
3591
"Header"=>$Type2_Pure{"Header"},
3592
"Line"=>$Type2_Pure{"Line"},
3593
"Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3594
"New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
3595
$MemberPair_Pos = $Member_Pos;
3599
if($Type1_Pure{"Memb"}{$Member_Pos}{"bitfield"})
3601
my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type1_Pure)%($POINTER_SIZE*8);
3602
if($BitfieldSum and $BitfieldSum-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"}>=0)
3604
%{$SubProblems{"Withdrawn_Middle_Member"}{$Member_Name}}=(
3605
"Target"=>$Member_Name,
3606
"Type_Name"=>$Type1_Pure{"Name"},
3607
"Type_Type"=>$Type1_Pure{"Type"},
3608
"Header"=>$Type2_Pure{"Header"},
3609
"Line"=>$Type2_Pure{"Line"} );
3613
%{$SubProblems{"Withdrawn_Middle_Member_And_Size"}{$Member_Name}}=(
3614
"Target"=>$Member_Name,
3615
"Type_Name"=>$Type1_Pure{"Name"},
3616
"Type_Type"=>$Type1_Pure{"Type"},
3617
"Header"=>$Type2_Pure{"Header"},
3618
"Line"=>$Type2_Pure{"Line"} );
3623
if($Type1_Pure{"Type"} eq "Enum")
3625
my $Member_Value1 = $Type1_Pure{"Memb"}{$Member_Pos}{"value"};
3626
next if(not $Member_Value1);
3627
my $Member_Value2 = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"};
3628
if($MemberPair_Pos eq "lost")
3630
$MemberPair_Pos = find_MemberPair_Pos_byVal($Member_Value1, \%Type2_Pure);
3631
if($MemberPair_Pos ne "lost")
3633
%{$SubProblems{"Enum_Member_Name"}{$Type1_Pure{"Memb"}{$Member_Pos}{"value"}}}=(
3634
"Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
3635
"Type_Name"=>$Type1_Pure{"Name"},
3636
"Type_Type"=>"Enum",
3637
"Header"=>$Type2_Pure{"Header"},
3638
"Line"=>$Type2_Pure{"Line"},
3639
"Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3640
"New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"name"} );
3645
if($Member_Value1 ne "" and $Member_Value2 ne "")
3647
if($Member_Value1 ne $Member_Value2)
3649
%{$SubProblems{"Enum_Member_Value"}{$Member_Name}}=(
3650
"Target"=>$Member_Name,
3651
"Type_Name"=>$Type1_Pure{"Name"},
3652
"Type_Type"=>"Enum",
3653
"Header"=>$Type2_Pure{"Header"},
3654
"Line"=>$Type2_Pure{"Line"},
3655
"Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"value"},
3656
"New_Value"=>$Type2_Pure{"Memb"}{$MemberPair_Pos}{"value"} );
3662
my $MemberType1_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
3663
my $MemberType2_Id = $Type2_Pure{"Memb"}{$MemberPair_Pos}{"type"};
3664
%Sub_SubProblems = detectTypeChange($MemberType1_Id, $MemberType2_Id, "Member");
3665
foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
3667
%{$SubProblems{$Sub_SubProblemType}{$Member_Name}}=(
3668
"Target"=>$Member_Name,
3669
"Member_Position"=>$Member_Pos,
3670
"Type_Name"=>$Type1_Pure{"Name"},
3671
"Type_Type"=>$Type1_Pure{"Type"},
3672
"Header"=>$Type2_Pure{"Header"},
3673
"Line"=>$Type2_Pure{"Line"});
3674
@{$SubProblems{$Sub_SubProblemType}{$Member_Name}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}};
3676
if($MemberType1_Id and $MemberType2_Id)
3677
{#checking member type change (replace)
3678
%Sub_SubProblems = &mergeTypes($MemberType1_Id, $Tid_TDid{1}{$MemberType1_Id}, $MemberType2_Id, $Tid_TDid{2}{$MemberType2_Id});
3679
foreach my $Sub_SubProblemType (keys(%Sub_SubProblems))
3681
foreach my $Sub_SubLocation (keys(%{$Sub_SubProblems{$Sub_SubProblemType}}))
3683
my $NewLocation = ($Sub_SubLocation)?$Member_Location."->".$Sub_SubLocation:$Member_Location;
3684
%{$SubProblems{$Sub_SubProblemType}{$NewLocation}}=(
3685
"IsInTypeInternals"=>"Yes");
3686
@{$SubProblems{$Sub_SubProblemType}{$NewLocation}}{keys(%{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}})} = values %{$Sub_SubProblems{$Sub_SubProblemType}{$Sub_SubLocation}};
3687
if($Sub_SubLocation !~ /\-\>/)
3689
$SubProblems{$Sub_SubProblemType}{$NewLocation}{"Member_Type_Name"} = get_TypeName($MemberType1_Id, 1);
3690
$SubProblems{$Sub_SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($MemberType1_Id, 1);
3696
if(($Type2_Pure{"Type"} eq "Struct") or ($Type2_Pure{"Type"} eq "Class"))
3698
foreach my $Member_Pos (sort keys(%{$Type2_Pure{"Memb"}}))
3699
{#checking added members
3700
next if(not $Type2_Pure{"Memb"}{$Member_Pos}{"name"});
3701
my $MemberPair_Pos = find_MemberPair_Pos_byName($Type2_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type1_Pure);
3702
if($MemberPair_Pos eq "lost")
3704
if($Member_Pos > keys(%{$Type1_Pure{"Memb"}}) - 1)
3706
if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3708
if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
3710
my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
3711
next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
3713
%{$SubProblems{"Added_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
3714
"Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
3715
"Type_Name"=>$Type1_Pure{"Name"},
3716
"Type_Type"=>$Type1_Pure{"Type"},
3717
"Header"=>$Type2_Pure{"Header"},
3718
"Line"=>$Type2_Pure{"Line"} );
3723
my $MemberType_Id = $Type2_Pure{"Memb"}{$Member_Pos}{"type"};
3724
my $MemberType_DId = $Tid_TDid{2}{$MemberType_Id};
3725
my %MemberType_Pure = get_PureType($MemberType_DId, $MemberType_Id, 2);
3727
my $MemberStraightPairType_Id = $Type1_Pure{"Memb"}{$Member_Pos}{"type"};
3728
my %MemberStraightPairType_Pure = get_PureType($Tid_TDid{1}{$MemberStraightPairType_Id}, $MemberStraightPairType_Id, 1);
3730
if(($MemberType_Pure{"Size"} eq $MemberStraightPairType_Pure{"Size"}) and find_MemberPair_Pos_byName($Type1_Pure{"Memb"}{$Member_Pos}{"name"}, \%Type2_Pure) eq "lost")
3732
next if($Type1_Pure{"Memb"}{$Member_Pos}{"access"} eq "private");
3733
%{$SubProblems{"Member_Rename"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
3734
"Target"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3735
"Type_Name"=>$Type1_Pure{"Name"},
3736
"Type_Type"=>$Type1_Pure{"Type"},
3737
"Header"=>$Type2_Pure{"Header"},
3738
"Line"=>$Type2_Pure{"Line"},
3739
"Old_Value"=>$Type1_Pure{"Memb"}{$Member_Pos}{"name"},
3740
"New_Value"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"} );
3744
if($Type1_Pure{"Size"} ne $Type2_Pure{"Size"})
3746
if($Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"})
3748
my $BitfieldSum = getBitfieldSum($Member_Pos-1, \%Type2_Pure)%($POINTER_SIZE*8);
3749
next if($BitfieldSum and $BitfieldSum<=$POINTER_SIZE*8-$Type2_Pure{"Memb"}{$Member_Pos}{"bitfield"});
3751
%{$SubProblems{"Added_Middle_Member_And_Size"}{$Type2_Pure{"Memb"}{$Member_Pos}{"name"}}}=(
3752
"Target"=>$Type2_Pure{"Memb"}{$Member_Pos}{"name"},
3753
"Type_Name"=>$Type1_Pure{"Name"},
3754
"Type_Type"=>$Type1_Pure{"Type"},
3755
"Header"=>$Type2_Pure{"Header"},
3756
"Line"=>$Type2_Pure{"Line"} );
3763
%{$Cache{"mergeTypes"}{$Type1_Id}{$Type1_DId}{$Type2_Id}{$Type2_DId}} = %SubProblems;
3765
return %SubProblems;
3768
sub get_TypeName($$)
3770
my ($TypeId, $LibVersion) = @_;
3771
return $TypeDescr{$LibVersion}{$Tid_TDid{$LibVersion}{$TypeId}}{$TypeId}{"Name"};
3776
my ($TypeDId, $TypeId, $LibVersion, $Type_Type) = @_;
3777
if(defined $Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type})
3779
return %{$Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type}};
3781
return () if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3782
my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3783
return () if(not $Type{"Type"});
3784
if($Type{"Type"} ne $Type_Type)
3786
return () if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3787
%Type = goToFirst($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion, $Type_Type);
3789
$Cache{"goToFirst"}{$TypeDId}{$TypeId}{$LibVersion}{$Type_Type} = \%Type;
3793
my %TypeSpecAttributes = (
3801
sub get_PureType($$$)
3803
my ($TypeDId, $TypeId, $LibVersion) = @_;
3804
return "" if(not $TypeId);
3805
if(defined $Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion})
3807
return %{$Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion}};
3809
return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3810
my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3811
if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
3813
$CheckedTypes{$Type{"Name"}} = 1;
3815
return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3816
if($TypeSpecAttributes{$Type{"Type"}})
3818
%Type = get_PureType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3820
$Cache{"get_PureType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
3824
sub get_PointerLevel($$$)
3826
my ($TypeDId, $TypeId, $LibVersion) = @_;
3827
return "" if(not $TypeId);
3828
if(defined $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion})
3830
return $Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion};
3832
return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3833
my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3834
return 0 if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3835
my $PointerLevel = 0;
3836
if($Type{"Type"} eq "Pointer")
3840
$PointerLevel += get_PointerLevel($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3841
$Cache{"get_PointerLevel"}{$TypeDId}{$TypeId}{$LibVersion} = $PointerLevel;
3842
return $PointerLevel;
3845
sub get_BaseType($$$)
3847
my ($TypeDId, $TypeId, $LibVersion) = @_;
3848
return "" if(not $TypeId);
3849
if(defined $Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion})
3851
return %{$Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion}};
3853
return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3854
my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3855
if($Type{"Type"} =~ /Struct|Union|Typedef|Class|Enum/)
3857
$CheckedTypes{$Type{"Name"}} = 1;
3859
return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3860
%Type = get_BaseType($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3861
$Cache{"get_BaseType"}{$TypeDId}{$TypeId}{$LibVersion} = \%Type;
3865
sub get_OneStep_BaseType($$$)
3867
my ($TypeDId, $TypeId, $LibVersion) = @_;
3868
return "" if(not $TypeId);
3869
return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3870
my %Type = %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3871
return %Type if(not $Type{"BaseType"}{"TDid"} and not $Type{"BaseType"}{"Tid"});
3872
return get_Type($Type{"BaseType"}{"TDid"}, $Type{"BaseType"}{"Tid"}, $LibVersion);
3877
my ($TypeDId, $TypeId, $LibVersion) = @_;
3878
return "" if(not $TypeId);
3879
return "" if(not $TypeDescr{$LibVersion}{$TypeDId}{$TypeId});
3880
return %{$TypeDescr{$LibVersion}{$TypeDId}{$TypeId}};
3885
foreach my $Interface (sort keys(%AddedInt))
3886
{#checking added interfaces
3887
next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
3888
next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
3889
next if(defined $AppPath and not $InterfacesList_App{$Interface});
3890
next if($FuncAttr{2}{$Interface}{"Private"});
3891
next if(not $FuncAttr{2}{$Interface}{"Header"});
3892
%{$CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}}=(
3893
"Header"=>$FuncAttr{2}{$Interface}{"Header"},
3894
"Line"=>$FuncAttr{2}{$Interface}{"Line"},
3895
"Signature"=>$FuncAttr{2}{$Interface}{"Signature"},
3896
"New_SoName"=>$Interface_Library{2}{$Interface} );
3898
foreach my $Interface (sort keys(%WithdrawnInt))
3899
{#checking withdrawn interfaces
3900
next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
3901
next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
3902
next if(defined $AppPath and not $InterfacesList_App{$Interface});
3903
next if($FuncAttr{1}{$Interface}{"Private"});
3904
next if(not $FuncAttr{1}{$Interface}{"Header"});
3905
%{$CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}}=(
3906
"Header"=>$FuncAttr{1}{$Interface}{"Header"},
3907
"Line"=>$FuncAttr{1}{$Interface}{"Line"},
3908
"Signature"=>$FuncAttr{1}{$Interface}{"Signature"},
3909
"Old_SoName"=>$Interface_Library{1}{$Interface} );
3913
sub mergeSignatures()
3915
my %SubProblems = ();
3917
prepareInterfaces(1);
3918
prepareInterfaces(2);
3921
initializeClassVirtFunc(1);
3922
initializeClassVirtFunc(2);
3924
checkVirtFuncRedefinitions(1);
3925
checkVirtFuncRedefinitions(2);
3927
setVirtFuncPositions(1);
3928
setVirtFuncPositions(2);
3930
foreach my $Interface (sort keys(%AddedInt))
3931
{#collecting the attributes of added interfaces
3932
next if($CheckedInterfaces{$Interface});
3933
if($CompleteSignature{2}{$Interface})
3935
if($CompleteSignature{2}{$Interface}{"Private"})
3937
$FuncAttr{2}{$Interface}{"Private"} = 1;
3939
if($CompleteSignature{2}{$Interface}{"Protected"})
3941
$FuncAttr{2}{$Interface}{"Protected"} = 1;
3943
if($CompleteSignature{2}{$Interface}{"Header"})
3945
$FuncAttr{2}{$Interface}{"Header"} = $CompleteSignature{2}{$Interface}{"Header"};
3947
if($CompleteSignature{2}{$Interface}{"Line"})
3949
$FuncAttr{2}{$Interface}{"Line"} = $CompleteSignature{2}{$Interface}{"Line"};
3951
$FuncAttr{2}{$Interface}{"Signature"} = get_Signature($Interface, 2);
3952
foreach my $ParamPos (keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
3954
my $ParamType_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
3955
my $ParamType_DId = $Tid_TDid{2}{$ParamType_Id};
3956
my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 2);
3958
#checking virtual table
3959
check_VirtualTable($Interface, 2);
3960
$CheckedInterfaces{$Interface} = 1;
3963
foreach my $Interface (sort keys(%WithdrawnInt))
3964
{#collecting the attributes of withdrawn interfaces
3965
next if($CheckedInterfaces{$Interface});
3966
if($CompleteSignature{1}{$Interface})
3968
if($CompleteSignature{1}{$Interface}{"Private"})
3970
$FuncAttr{1}{$Interface}{"Private"} = 1;
3972
if($CompleteSignature{1}{$Interface}{"Protected"})
3974
$FuncAttr{1}{$Interface}{"Protected"} = 1;
3976
if($CompleteSignature{1}{$Interface}{"Header"})
3978
$FuncAttr{1}{$Interface}{"Header"} = $CompleteSignature{1}{$Interface}{"Header"};
3980
if($CompleteSignature{1}{$Interface}{"Line"})
3982
$FuncAttr{1}{$Interface}{"Line"} = $CompleteSignature{1}{$Interface}{"Line"};
3984
$FuncAttr{1}{$Interface}{"Signature"} = get_Signature($Interface, 1);
3985
foreach my $ParamPos (keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
3987
my $ParamType_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
3988
my $ParamType_DId = $Tid_TDid{1}{$ParamType_Id};
3989
my %ParamType = get_Type($ParamType_DId, $ParamType_Id, 1);
3991
#checking virtual table
3992
check_VirtualTable($Interface, 1);
3993
$CheckedInterfaces{$Interface} = 1;
3997
foreach my $Interface (sort keys(%{$CompleteSignature{1}}))
3998
{#checking interfaces
3999
if(($Interface !~ /\@/) and ($SymVer{1}{$Interface} =~ /\A(.*)[\@]+/))
4001
next if($1 eq $Interface);
4003
my ($MnglName, $SymbolVersion) = ($Interface, "");
4004
if($Interface =~ /\A([^@]+)[\@]+([^@]+)\Z/)
4006
($MnglName, $SymbolVersion) = ($1, $2);
4008
next if($InternalInterfaces{1}{$Interface} or $InternalInterfaces{2}{$Interface});
4009
next if(defined $InterfacesListPath and not $InterfacesList{$Interface});
4010
next if(defined $AppPath and not $InterfacesList_App{$Interface});
4011
next if($CheckedInterfaces{$Interface});
4012
next if($CompleteSignature{1}{$Interface}{"Private"});
4013
next if(not $CompleteSignature{1}{$Interface}{"Header"} or not $CompleteSignature{2}{$Interface}{"Header"});
4014
next if(not $CompleteSignature{1}{$Interface}{"MnglName"} or not $CompleteSignature{2}{$Interface}{"MnglName"});
4015
next if((not $CompleteSignature{1}{$Interface}{"PureVirt"} and $CompleteSignature{2}{$Interface}{"PureVirt"}) or ($CompleteSignature{1}{$Interface}{"PureVirt"} and not $CompleteSignature{2}{$Interface}{"PureVirt"}));
4016
$CheckedInterfaces{$Interface} = 1;
4017
#checking virtual table
4018
check_VirtualTable($Interface, 1);
4019
#checking attributes
4020
if($CompleteSignature{2}{$Interface}{"Static"} and not $CompleteSignature{1}{$Interface}{"Static"})
4022
%{$CompatProblems{$Interface}{"Function_Become_Static"}{"Attributes"}}=(
4023
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4024
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4025
"Signature"=>get_Signature($Interface, 1),
4026
"Old_SoName"=>$Interface_Library{1}{$Interface},
4027
"New_SoName"=>$Interface_Library{2}{$Interface} );
4029
elsif(not $CompleteSignature{2}{$Interface}{"Static"} and $CompleteSignature{1}{$Interface}{"Static"})
4031
%{$CompatProblems{$Interface}{"Function_Become_NonStatic"}{"Attributes"}}=(
4032
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4033
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4034
"Signature"=>get_Signature($Interface, 1),
4035
"Old_SoName"=>$Interface_Library{1}{$Interface},
4036
"New_SoName"=>$Interface_Library{2}{$Interface} );
4038
if($CompleteSignature{1}{$Interface}{"Virt"} and $CompleteSignature{2}{$Interface}{"Virt"})
4040
if($CompleteSignature{1}{$Interface}{"Position"}!=$CompleteSignature{2}{$Interface}{"Position"})
4042
my $Class_Id = $CompleteSignature{1}{$Interface}{"Class"};
4043
my $Class_DId = $Tid_TDid{1}{$Class_Id};
4044
my %Class_Type = get_Type($Class_DId, $Class_Id, 1);
4045
%{$CompatProblems{$Interface}{"Virtual_Function_Position"}{$tr_name{$MnglName}}}=(
4046
"Type_Name"=>$Class_Type{"Name"},
4047
"Type_Type"=>$Class_Type{"Type"},
4048
"Header"=>$Class_Type{"Header"},
4049
"Line"=>$Class_Type{"Line"},
4050
"Old_Value"=>$CompleteSignature{1}{$Interface}{"Position"},
4051
"New_Value"=>$CompleteSignature{2}{$Interface}{"Position"},
4052
"Signature"=>get_Signature($Interface, 1),
4053
"Target"=>$tr_name{$MnglName},
4054
"Old_SoName"=>$Interface_Library{1}{$Interface},
4055
"New_SoName"=>$Interface_Library{2}{$Interface} );
4058
foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{2}{$Interface}{"Param"}}))
4059
{#checking added parameters
4060
last if($Interface=~/\A_Z/);
4061
if(not defined $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos})
4062
{#checking withdrawn parameters
4063
my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
4064
my $Parameter_Name = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"name"};
4065
last if(get_TypeName($ParamType2_Id, 2) eq "...");
4066
%{$CompatProblems{$Interface}{"Added_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
4067
"Target"=>$Parameter_Name,
4068
"Parameter_Position"=>$ParamPos,
4069
"Signature"=>get_Signature($Interface, 1),
4070
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4071
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4072
"Old_SoName"=>$Interface_Library{1}{$Interface},
4073
"New_SoName"=>$Interface_Library{2}{$Interface});
4076
foreach my $ParamPos (sort {int($a) <=> int($b)} keys(%{$CompleteSignature{1}{$Interface}{"Param"}}))
4077
{#checking parameters
4078
my $ParamType1_Id = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"type"};
4079
my $Parameter_Name = $CompleteSignature{1}{$Interface}{"Param"}{$ParamPos}{"name"};
4080
if(not defined $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos} and get_TypeName($ParamType1_Id, 1) ne "..." and $Interface!~/\A_Z/)
4081
{#checking withdrawn parameters
4082
%{$CompatProblems{$Interface}{"Withdrawn_Parameter"}{num_to_str($ParamPos+1)." Parameter"}}=(
4083
"Target"=>$Parameter_Name,
4084
"Parameter_Position"=>$ParamPos,
4085
"Signature"=>get_Signature($Interface, 1),
4086
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4087
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4088
"Old_SoName"=>$Interface_Library{1}{$Interface},
4089
"New_SoName"=>$Interface_Library{2}{$Interface});
4092
my $ParamType2_Id = $CompleteSignature{2}{$Interface}{"Param"}{$ParamPos}{"type"};
4093
next if(not $ParamType1_Id or not $ParamType2_Id);
4094
my $Parameter_Location = ($Parameter_Name)?$Parameter_Name:num_to_str($ParamPos+1)." Parameter";
4096
#checking type change(replace)
4097
%SubProblems = detectTypeChange($ParamType1_Id, $ParamType2_Id, "Parameter");
4098
foreach my $SubProblemType (keys(%SubProblems))
4100
%{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}=(
4101
"Target"=>$Parameter_Name,
4102
"Parameter_Position"=>$ParamPos,
4103
"Signature"=>get_Signature($Interface, 1),
4104
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4105
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4106
"Old_SoName"=>$Interface_Library{1}{$Interface},
4107
"New_SoName"=>$Interface_Library{2}{$Interface});
4108
@{$CompatProblems{$Interface}{$SubProblemType}{$Parameter_Location}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
4111
#checking type definition changes
4112
%SubProblems = mergeTypes($ParamType1_Id, $Tid_TDid{1}{$ParamType1_Id}, $ParamType2_Id, $Tid_TDid{2}{$ParamType2_Id});
4113
foreach my $SubProblemType (keys(%SubProblems))
4115
foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
4117
my $NewLocation = ($SubLocation)?$Parameter_Location."->".$SubLocation:$Parameter_Location;
4118
%{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
4119
"Signature"=>get_Signature($Interface, 1),
4120
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4121
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4122
"Old_SoName"=>$Interface_Library{1}{$Interface},
4123
"New_SoName"=>$Interface_Library{2}{$Interface},
4124
"Parameter_Type_Name"=>get_TypeName($ParamType1_Id, 1),
4125
"Parameter_Position"=>$ParamPos,
4126
"Parameter_Name"=>$Parameter_Name);
4127
@{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
4128
if($SubLocation !~ /\-\>/)
4130
$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ParamType1_Id, 1);
4135
#checking return type
4136
my $ReturnType1_Id = $CompleteSignature{1}{$Interface}{"Return"};
4137
my $ReturnType2_Id = $CompleteSignature{2}{$Interface}{"Return"};
4138
%SubProblems = detectTypeChange($ReturnType1_Id, $ReturnType2_Id, "Return");
4139
foreach my $SubProblemType (keys(%SubProblems))
4141
%{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}=(
4142
"Signature"=>get_Signature($Interface, 1),
4143
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4144
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4145
"Old_SoName"=>$Interface_Library{1}{$Interface},
4146
"New_SoName"=>$Interface_Library{2}{$Interface});
4147
@{$CompatProblems{$Interface}{$SubProblemType}{"RetVal"}}{keys(%{$SubProblems{$SubProblemType}})} = values %{$SubProblems{$SubProblemType}};
4149
if($ReturnType1_Id and $ReturnType2_Id)
4152
%SubProblems = mergeTypes($ReturnType1_Id, $Tid_TDid{1}{$ReturnType1_Id}, $ReturnType2_Id, $Tid_TDid{2}{$ReturnType2_Id});
4153
foreach my $SubProblemType (keys(%SubProblems))
4155
foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
4157
my $NewLocation = ($SubLocation)?"RetVal->".$SubLocation:"RetVal";
4158
%{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
4159
"Signature"=>get_Signature($Interface, 1),
4160
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4161
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4162
"Old_SoName"=>$Interface_Library{1}{$Interface},
4163
"New_SoName"=>$Interface_Library{2}{$Interface},
4164
"Return_Type_Name"=>get_TypeName($ReturnType1_Id, 1) );
4165
@{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
4166
if($SubLocation !~ /\-\>/)
4168
$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ReturnType1_Id, 1);
4174
#checking object type
4175
my $ObjectType1_Id = $CompleteSignature{1}{$Interface}{"Class"};
4176
my $ObjectType2_Id = $CompleteSignature{2}{$Interface}{"Class"};
4177
if($ObjectType1_Id and $ObjectType2_Id)
4179
my $ThisType1_Id = getTypeIdByName(get_TypeName($ObjectType1_Id, 1)."*const", 1);
4180
my $ThisType2_Id = getTypeIdByName(get_TypeName($ObjectType2_Id, 2)."*const", 2);
4181
if($ThisType1_Id and $ThisType2_Id)
4184
%SubProblems = mergeTypes($ThisType1_Id, $Tid_TDid{1}{$ThisType1_Id}, $ThisType2_Id, $Tid_TDid{2}{$ThisType2_Id});
4185
foreach my $SubProblemType (keys(%SubProblems))
4187
foreach my $SubLocation (keys(%{$SubProblems{$SubProblemType}}))
4189
my $NewLocation = ($SubLocation)?"Obj->".$SubLocation:"Obj";
4190
%{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}=(
4191
"Signature"=>get_Signature($Interface, 1),
4192
"Header"=>$CompleteSignature{1}{$Interface}{"Header"},
4193
"Line"=>$CompleteSignature{1}{$Interface}{"Line"},
4194
"Old_SoName"=>$Interface_Library{1}{$Interface},
4195
"New_SoName"=>$Interface_Library{2}{$Interface},
4196
"Object_Type_Name"=>get_TypeName($ObjectType1_Id, 1) );
4197
@{$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}}{keys(%{$SubProblems{$SubProblemType}{$SubLocation}})} = values %{$SubProblems{$SubProblemType}{$SubLocation}};
4198
if($SubLocation !~ /\-\>/)
4200
$CompatProblems{$Interface}{$SubProblemType}{$NewLocation}{"Start_Type_Name"} = get_TypeName($ObjectType1_Id, 1);
4207
set_Problems_Priority();
4210
sub getTypeIdByName($$)
4212
my ($TypeName, $Version) = @_;
4213
return $TName_Tid{$Version}{correctName($TypeName)};
4216
sub detectTypeChange($$$)
4218
my ($Type1_Id, $Type2_Id, $Prefix) = @_;
4219
my %LocalProblems = ();
4220
my $Type1_DId = $Tid_TDid{1}{$Type1_Id};
4221
my $Type2_DId = $Tid_TDid{2}{$Type2_Id};
4222
my %Type1 = get_Type($Type1_DId, $Type1_Id, 1);
4223
my %Type2 = get_Type($Type2_DId, $Type2_Id, 2);
4224
my %Type1_Base = get_BaseType($Type1_DId, $Type1_Id, 1);
4225
my %Type2_Base = get_BaseType($Type2_DId, $Type2_Id, 2);
4226
my %Type1_Pure = get_PureType($Type1_DId, $Type1_Id, 1);
4227
my %Type2_Pure = get_PureType($Type2_DId, $Type2_Id, 2);
4228
my $Type1_PointerLevel = get_PointerLevel($Type1_DId, $Type1_Id, 1);
4229
my $Type2_PointerLevel = get_PointerLevel($Type2_DId, $Type2_Id, 2);
4230
return () if(not $Type1{"Name"} or not $Type2{"Name"} or not $Type1{"Size"} or not $Type2{"Size"} or not $Type1_Pure{"Size"} or not $Type2_Pure{"Size"} or not $Type1_Base{"Name"} or not $Type2_Base{"Name"} or not $Type1_Base{"Size"} or not $Type2_Base{"Size"} or $Type1_PointerLevel eq "" or $Type2_PointerLevel eq "");
4231
if($Type1_Base{"Name"} ne $Type2_Base{"Name"})
4233
if($Type1_Base{"Name"}!~/anon\-/ and $Type2_Base{"Name"}!~/anon\-/)
4235
if($Type1_Base{"Size"}!=$Type2_Base{"Size"})
4237
%{$LocalProblems{$Prefix."_BaseType_And_Size"}}=(
4238
"Old_Value"=>$Type1_Base{"Name"},
4239
"New_Value"=>$Type2_Base{"Name"},
4240
"Old_Size"=>$Type1_Base{"Size"},
4241
"New_Size"=>$Type2_Base{"Size"},
4242
"InitialType_Type"=>$Type1_Pure{"Type"});
4246
%{$LocalProblems{$Prefix."_BaseType"}}=(
4247
"Old_Value"=>$Type1_Base{"Name"},
4248
"New_Value"=>$Type2_Base{"Name"},
4249
"InitialType_Type"=>$Type1_Pure{"Type"});
4253
elsif($Type1{"Name"} ne $Type2{"Name"})
4255
if($Type1{"Name"}!~/anon\-/ and $Type2{"Name"}!~/anon\-/)
4257
if($Type1{"Size"}!=$Type2{"Size"})
4259
%{$LocalProblems{$Prefix."_Type_And_Size"}}=(
4260
"Old_Value"=>$Type1{"Name"},
4261
"New_Value"=>$Type2{"Name"},
4262
"Old_Size"=>($Type1{"Type"} eq "Array")?$Type1{"Size"}*$Type1_Base{"Size"}:$Type1{"Size"},
4263
"New_Size"=>($Type2{"Type"} eq "Array")?$Type2{"Size"}*$Type2_Base{"Size"}:$Type2{"Size"},
4264
"InitialType_Type"=>$Type1_Pure{"Type"});
4268
%{$LocalProblems{$Prefix."_Type"}}=(
4269
"Old_Value"=>$Type1{"Name"},
4270
"New_Value"=>$Type2{"Name"},
4271
"InitialType_Type"=>$Type1_Pure{"Type"});
4276
if($Type1_PointerLevel!=$Type2_PointerLevel)
4278
%{$LocalProblems{$Prefix."_PointerLevel"}}=(
4279
"Old_Value"=>$Type1_PointerLevel,
4280
"New_Value"=>$Type2_PointerLevel);
4282
return %LocalProblems;
4285
sub htmlSpecChars($)
4288
$Str =~ s/\&([^#])/&$1/g;
4291
$Str =~ s/([^ ])( )([^ ])/$1\@ALONE_SP\@$3/g;
4292
$Str =~ s/ / /g;
4293
$Str =~ s/\@ALONE_SP\@/ /g;
4294
$Str =~ s/\n/<br\/>/g;
4298
sub highLight_Signature($)
4300
my $Signature = $_[0];
4301
return highLight_Signature_PPos_Italic($Signature, "", 0, 0);
4304
sub highLight_Signature_Italic($)
4306
my $Signature = $_[0];
4307
return highLight_Signature_PPos_Italic($Signature, "", 1, 0);
4310
sub highLight_Signature_Italic_Color($)
4312
my $Signature = $_[0];
4313
return highLight_Signature_PPos_Italic($Signature, "", 1, 1);
4316
sub highLight_Signature_PPos_Italic($$$$)
4318
my ($FullSignature, $Parameter_Position, $ItalicParams, $ColorParams) = @_;
4319
my ($Signature, $SymbolVersion) = ($FullSignature, "");
4320
if($FullSignature =~ /\A(.+)[\@]+(.+)\Z/)
4322
($Signature, $SymbolVersion) = ($1, $2);
4324
if($Signature=~/\Atypeinfo\W/)
4326
return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
4328
if($Signature!~/\)(| const)\Z/)
4330
return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
4332
$Signature =~ /(.+?)\(.*\)(| const)\Z/;
4333
my ($Begin, $End) = ($1, $2);
4336
foreach my $Part (get_Signature_Parts($Signature, 1))
4338
$Part =~ s/\A\s+|\s+\Z//g;
4339
my ($Part_Styled, $ParamName) = ($Part, "");
4340
if($Part=~/\([\*]+(\w+)\)/i)
4344
elsif($Part=~/(\w+)[\,\)]*\Z/i)
4350
push(@Parts, $Part);
4353
if($ItalicParams and not $TName_Tid{1}{$Part} and not $TName_Tid{2}{$Part})
4355
if(($Parameter_Position ne "") and ($Part_Num == $Parameter_Position))
4357
$Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='focus_param'>$ParamName</span>$2!ig;
4361
$Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span class='color_param'>$ParamName</span>$2!ig;
4365
$Part_Styled =~ s!(\W)$ParamName([\,\)]|\Z)!$1<span style='font-style:italic;'>$ParamName</span>$2!ig;
4368
$Part_Styled = "<span style='white-space:nowrap;'>".$Part_Styled."</span>";
4369
push(@Parts, $Part_Styled);
4372
$Signature = $Begin."<span class='int_p'>"."(".join(" ", @Parts).")"."</span>".$End;
4373
$Signature =~ s!\[\]![<span style='padding-left:2px;'>]</span>!g;
4374
$Signature =~ s!operator=!operator<span style='padding-left:2px'>=</span>!g;
4375
$Signature =~ s!(\[in-charge\]|\[not-in-charge\]|\[in-charge-deleting\])!<span style='color:Black;font-weight:normal;'>$1</span>!g;
4376
return $Signature.(($SymbolVersion)?"<span class='symver'> \@ $SymbolVersion</span>":"");
4379
sub get_Signature_Parts($$)
4381
my ($Signature, $Comma) = @_;
4383
my $Bracket_Num = 0;
4384
my $Bracket2_Num = 0;
4385
my $Parameters = $Signature;
4386
if($Signature=~/>|</)
4388
$Parameters=~s/>/>/g;
4389
$Parameters=~s/</</g;
4392
if($Parameters =~ s/.+?\((.*)\)(| const)\Z/$1/)
4394
foreach my $Pos (0 .. length($Parameters) - 1)
4396
my $Symbol = substr($Parameters, $Pos, 1);
4397
$Bracket_Num += 1 if($Symbol eq "(");
4398
$Bracket_Num -= 1 if($Symbol eq ")");
4399
$Bracket2_Num += 1 if($Symbol eq "<");
4400
$Bracket2_Num -= 1 if($Symbol eq ">");
4401
if($Symbol eq "," and $Bracket_Num==0 and $Bracket2_Num==0)
4403
$Parts[$Part_Num] .= $Symbol if($Comma);
4408
$Parts[$Part_Num] .= $Symbol;
4411
if($Signature=~/>|</)
4413
foreach my $Part (@Parts)
4427
my %TypeProblems_Kind=(
4428
"Added_Virtual_Function"=>1,
4429
"Withdrawn_Virtual_Function"=>1,
4430
"Virtual_Function_Position"=>1,
4431
"Virtual_Function_Redefinition"=>1,
4432
"Virtual_Function_Redefinition_B"=>1,
4434
"Added_Member_And_Size"=>1,
4435
"Added_Middle_Member_And_Size"=>1,
4436
"Withdrawn_Member_And_Size"=>1,
4437
"Withdrawn_Member"=>1,
4438
"Withdrawn_Middle_Member_And_Size"=>1,
4440
"Enum_Member_Value"=>1,
4441
"Enum_Member_Name"=>1,
4442
"Member_Type_And_Size"=>1,
4444
"Member_BaseType_And_Size"=>1,
4445
"Member_BaseType"=>1,
4446
"Member_PointerLevel"=>1,
4450
my %InterfaceProblems_Kind=(
4451
"Added_Interface"=>1,
4452
"Withdrawn_Interface"=>1,
4453
"Function_Become_Static"=>1,
4454
"Function_Become_NonStatic"=>1,
4455
"Parameter_Type_And_Size"=>1,
4456
"Parameter_Type"=>1,
4457
"Parameter_BaseType_And_Size"=>1,
4458
"Parameter_BaseType"=>1,
4459
"Parameter_PointerLevel"=>1,
4460
"Return_Type_And_Size"=>1,
4462
"Return_BaseType_And_Size"=>1,
4463
"Return_BaseType"=>1,
4464
"Return_PointerLevel"=>1,
4465
"Withdrawn_Parameter"=>1,
4466
"Added_Parameter"=>1
4469
sub testSystem_cpp()
4471
print "testing for C++ library changes\n";
4472
my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
4474
#Withdrawn_Parameter
4475
@DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
4476
@Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
4478
@DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
4479
@Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
4482
@DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
4483
@Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
4485
@DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
4486
@Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
4488
#Added_Virtual_Function
4489
@DataDefs_v1 = (@DataDefs_v1, "class type_test_added_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
4490
@Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
4491
@Sources_v1 = (@Sources_v1, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
4493
@DataDefs_v2 = (@DataDefs_v2, "class type_test_added_virtual_function\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4494
@Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func1(int param)\n{\n return param;\n}");
4495
@Sources_v2 = (@Sources_v2, "int type_test_added_virtual_function::func2(int param)\n{\n return param;\n}");
4497
#added simple function
4498
@DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_funcptr(FUNCPTR_TYPE*const** f);");
4499
@Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
4501
#Withdrawn_Virtual_Function
4502
@DataDefs_v1 = (@DataDefs_v1, "class type_test_withdrawn_virtual_function\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4503
@Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
4504
@Sources_v1 = (@Sources_v1, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
4506
@DataDefs_v2 = (@DataDefs_v2, "class type_test_withdrawn_virtual_function\n{\npublic:\n int func1(int param);\n virtual int func2(int param);\n};");
4507
@Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func1(int param)\n{\n return param;\n}");
4508
@Sources_v2 = (@Sources_v2, "int type_test_withdrawn_virtual_function::func2(int param)\n{\n return param;\n}");
4510
#Virtual_Function_Position
4511
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4512
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
4513
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
4515
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
4516
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func1(int param)\n{\n return param;\n}");
4517
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position::func2(int param)\n{\n return param;\n}");
4519
#virtual functions safe replace
4520
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4521
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
4522
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
4524
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4525
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func1(int param)\n{\n return param;\n}");
4526
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace_base::func2(int param)\n{\n return param;\n}");
4528
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4529
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
4530
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
4532
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_position_safe_replace:public type_test_virtual_function_position_safe_replace_base\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
4533
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func1(int param)\n{\n return param;\n}");
4534
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_position_safe_replace::func2(int param)\n{\n return param;\n}");
4536
#virtual table changes
4537
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4538
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4539
@Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
4540
@Sources_v1 = (@Sources_v1, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
4541
@Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
4542
@Sources_v1 = (@Sources_v1, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
4544
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4545
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_table:public type_test_virtual_table_base\n{\npublic:\n virtual int func2(int param);\n virtual int func1(int param);\n};");
4546
@Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func1(int param)\n{\n return param;\n}");
4547
@Sources_v2 = (@Sources_v2, "int type_test_virtual_table_base::func2(int param)\n{\n return param;\n}");
4548
@Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func1(int param)\n{\n return param;\n}");
4549
@Sources_v2 = (@Sources_v2, "int type_test_virtual_table::func2(int param)\n{\n return param;\n}");
4551
#Virtual_Function_Redefinition
4552
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4553
@DataDefs_v1 = (@DataDefs_v1, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func3(int param);\n};");
4554
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func1(int param)\n{\n return param;\n}");
4555
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition_base::func2(int param)\n{\n return param;\n}");
4556
@Sources_v1 = (@Sources_v1, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
4558
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func1(int param);\n virtual int func2(int param);\n};");
4559
@DataDefs_v2 = (@DataDefs_v2, "class type_test_virtual_function_redefinition:public type_test_virtual_function_redefinition_base\n{\npublic:\n virtual int func2(int param);\n virtual int func3(int param);\n};");
4560
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func1(int param){\n return param;\n}");
4561
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition_base::func2(int param){\n return param;\n}");
4562
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func2(int param)\n{\n return param;\n}");
4563
@Sources_v2 = (@Sources_v2, "int type_test_virtual_function_redefinition::func3(int param)\n{\n return param;\n}");
4566
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\npublic:\n virtual type_test_size func1(type_test_size param);\n int i;\n long j;\n double k;\n type_test_size* p;\n};");
4567
@Sources_v1 = (@Sources_v1, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
4569
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\npublic:\n virtual type_test_size func1(type_test_size param);\n int i;\n long j;\n double k;\n type_test_size* p;\n int added_member;\n};");
4570
@Sources_v2 = (@Sources_v2, "type_test_size type_test_size::func1(type_test_size param)\n{\n return param;\n}");
4572
#Added_Member_And_Size
4573
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\npublic:\n virtual type_test_added_member func1(type_test_added_member param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n};");
4574
@Sources_v1 = (@Sources_v1, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
4576
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\npublic:\n virtual type_test_added_member func1(type_test_added_member param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n int added_member;\n};");
4577
@Sources_v2 = (@Sources_v2, "type_test_added_member type_test_added_member::func1(type_test_added_member param)\n{\n return param;\n}");
4579
#Method object changes
4580
@DataDefs_v1 = (@DataDefs_v1, "class type_test_object_added_member\n{\npublic:\n virtual int func1(int param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n};");
4581
@Sources_v1 = (@Sources_v1, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
4583
@DataDefs_v2 = (@DataDefs_v2, "class type_test_object_added_member\n{\npublic:\n virtual int func1(int param);\n int i;\n long j;\n double k;\n type_test_added_member* p;\n int added_member;\n};");
4584
@Sources_v2 = (@Sources_v2, "int type_test_object_added_member::func1(int param)\n{\n return param;\n}");
4587
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_bitfield\n{\npublic:\n virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n type_test_added_bitfield* p;\n};");
4588
@Sources_v1 = (@Sources_v1, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
4590
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_bitfield\n{\npublic:\n virtual type_test_added_bitfield func1(type_test_added_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n int added_bitfield : 1;\n type_test_added_bitfield* p;\n};");
4591
@Sources_v2 = (@Sources_v2, "type_test_added_bitfield type_test_added_bitfield::func1(type_test_added_bitfield param)\n{\n return param;\n}");
4594
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_bitfield\n{\npublic:\n virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n int withdrawn_bitfield : 1;\n type_test_withdrawn_bitfield* p;\n};");
4595
@Sources_v1 = (@Sources_v1, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
4597
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_bitfield\n{\npublic:\n virtual type_test_withdrawn_bitfield func1(type_test_withdrawn_bitfield param);\n int i;\n long j;\n double k;\n int b1 : 32;\n int b2 : 31;\n type_test_withdrawn_bitfield* p;\n};");
4598
@Sources_v2 = (@Sources_v2, "type_test_withdrawn_bitfield type_test_withdrawn_bitfield::func1(type_test_withdrawn_bitfield param)\n{\n return param;\n}");
4600
#Added_Middle_Member_And_Size
4601
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\npublic:\n virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n int i;\n long j;\n double k;\n type_test_added_middle_member* p;\n};");
4602
@Sources_v1 = (@Sources_v1, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n return param;\n}");
4604
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\npublic:\n virtual type_test_added_middle_member func1(type_test_added_middle_member param);\n int i;\n int added_middle_member;\n long j;\n double k;\n type_test_added_middle_member* p;\n};");
4605
@Sources_v2 = (@Sources_v2, "type_test_added_middle_member type_test_added_middle_member::func1(type_test_added_middle_member param)\n{\n return param;\n}");
4608
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\npublic:\n virtual type_test_member_rename func1(type_test_member_rename param);\n long i;\n long j;\n double k;\n type_test_member_rename* p;\n};");
4609
@Sources_v1 = (@Sources_v1, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
4611
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\npublic:\n virtual type_test_member_rename func1(type_test_member_rename param);\n long renamed_member;\n long j;\n double k;\n type_test_member_rename* p;\n};");
4612
@Sources_v2 = (@Sources_v2, "type_test_member_rename type_test_member_rename::func1(type_test_member_rename param)\n{\n return param;\n}");
4614
#Withdrawn_Member_And_Size
4615
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\npublic:\n virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_member* p;\n int withdrawn_member;\n};");
4616
@Sources_v1 = (@Sources_v1, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
4618
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\npublic:\n virtual type_test_withdrawn_member func1(type_test_withdrawn_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_member* p;\n};");
4619
@Sources_v2 = (@Sources_v2, "type_test_withdrawn_member type_test_withdrawn_member::func1(type_test_withdrawn_member param)\n{\n return param;\n}");
4621
#Withdrawn_Middle_Member_And_Size
4622
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\npublic:\n virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n int i;\n int withdrawn_middle_member;\n long j;\n double k;\n type_test_withdrawn_middle_member* p;\n};");
4623
@Sources_v1 = (@Sources_v1, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n return param;\n}");
4625
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\npublic:\n virtual type_test_withdrawn_middle_member func1(type_test_withdrawn_middle_member param);\n int i;\n long j;\n double k;\n type_test_withdrawn_middle_member* p;\n};");
4626
@Sources_v2 = (@Sources_v2, "type_test_withdrawn_middle_member type_test_withdrawn_middle_member::func1(type_test_withdrawn_middle_member param)\n{\n return param;\n}");
4629
@DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
4630
@DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
4631
@Sources_v1 = (@Sources_v1,
4632
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
4644
@DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
4645
@DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
4646
@Sources_v2 = (@Sources_v2,
4647
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
4660
@DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
4661
@DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
4662
@Sources_v1 = (@Sources_v1,
4663
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
4675
@DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
4676
@DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
4677
@Sources_v2 = (@Sources_v2,
4678
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
4690
#Member_Type_And_Size
4691
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\npublic:\n type_test_member_type_and_size func1(type_test_member_type_and_size param);\n int i;\n long j;\n double k;\n type_test_member_type_and_size* p;\n};");
4692
@Sources_v1 = (@Sources_v1, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n return param;\n}");
4694
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\npublic:\n type_test_member_type_and_size func1(type_test_member_type_and_size param);\n long long i;\n long j;\n double k;\n type_test_member_type_and_size* p;\n};");
4695
@Sources_v2 = (@Sources_v2, "type_test_member_type_and_size type_test_member_type_and_size::func1(type_test_member_type_and_size param)\n{\n return param;\n}");
4698
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\npublic:\n type_test_member_type func1(type_test_member_type param);\n int i;\n long j;\n double k;\n type_test_member_type* p;\n};");
4699
@Sources_v1 = (@Sources_v1, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
4701
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\npublic:\n type_test_member_type func1(type_test_member_type param);\n float i;\n long j;\n double k;\n type_test_member_type* p;\n};");
4702
@Sources_v2 = (@Sources_v2, "type_test_member_type type_test_member_type::func1(type_test_member_type param)\n{\n return param;\n}");
4705
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\npublic:\n type_test_member_basetype func1(type_test_member_basetype param);\n int *i;\n long j;\n double k;\n type_test_member_basetype* p;\n};");
4706
@Sources_v1 = (@Sources_v1, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
4708
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\npublic:\n type_test_member_basetype func1(type_test_member_basetype param);\n long long *i;\n long j;\n double k;\n type_test_member_basetype* p;\n};");
4709
@Sources_v2 = (@Sources_v2, "type_test_member_basetype type_test_member_basetype::func1(type_test_member_basetype param)\n{\n return param;\n}");
4711
#Member_PointerLevel_And_Size
4712
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n long long i;\n long j;\n double k;\n type_test_member_pointerlevel_and_size* p;\n};");
4713
@Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n return param;\n}");
4715
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\npublic:\n type_test_member_pointerlevel_and_size func1(type_test_member_pointerlevel_and_size param);\n long long *i;\n long j;\n double k;\n type_test_member_pointerlevel_and_size* p;\n};");
4716
@Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel_and_size type_test_member_pointerlevel_and_size::func1(type_test_member_pointerlevel_and_size param)\n{\n return param;\n}");
4718
#Member_PointerLevel
4719
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\npublic:\n type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n int **i;\n long j;\n double k;\n type_test_member_pointerlevel* p;\n};");
4720
@Sources_v1 = (@Sources_v1, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
4722
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\npublic:\n type_test_member_pointerlevel func1(type_test_member_pointerlevel param);\n int *i;\n long j;\n double k;\n type_test_member_pointerlevel* p;\n};");
4723
@Sources_v2 = (@Sources_v2, "type_test_member_pointerlevel type_test_member_pointerlevel::func1(type_test_member_pointerlevel param)\n{\n return param;\n}");
4725
#Added_Interface (function)
4726
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_interface\n{\npublic:\n type_test_added_interface func1(type_test_added_interface param);\n int i;\n long j;\n double k;\n type_test_added_interface* p;\n};");
4727
@Sources_v1 = (@Sources_v1, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
4729
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_interface\n{\npublic:\n type_test_added_interface func1(type_test_added_interface param);\n type_test_added_interface added_func(type_test_added_interface param);\n int i;\n long j;\n double k;\n type_test_added_interface* p;\n};");
4730
@DataDefs_v2 = (@DataDefs_v2, "int added_func_2(void *** param);");
4731
@Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::func1(type_test_added_interface param)\n{\n return param;\n}");
4732
@Sources_v2 = (@Sources_v2, "type_test_added_interface type_test_added_interface::added_func(type_test_added_interface param)\n{\n return param;\n}");
4733
@Sources_v2 = (@Sources_v2, "int added_func_2(void *** param)\n{\n return 0;\n}");
4735
#Added_Interface (global variable)
4736
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_variable\n{\npublic:\n int func1(type_test_added_variable param);\n int i;\n long j;\n double k;\n type_test_added_variable* p;\n};");
4737
@Sources_v1 = (@Sources_v1, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return i;\n}");
4739
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_variable\n{\npublic:\n int func1(type_test_added_variable param);\n static int i;\n long j;\n double k;\n type_test_added_variable* p;\n};");
4740
@Sources_v2 = (@Sources_v2, "int type_test_added_variable::func1(type_test_added_variable param)\n{\n return type_test_added_variable::i;\n}");
4741
@Sources_v2 = (@Sources_v2, "int type_test_added_variable::i=0;");
4743
#Withdrawn_Interface
4744
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_interface\n{\npublic:\n type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n type_test_withdrawn_interface withdrawn_func(type_test_withdrawn_interface param);\n int i;\n long j;\n double k;\n type_test_withdrawn_interface* p;\n};");
4745
@DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func_2(void *** param);");
4746
@Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
4747
@Sources_v1 = (@Sources_v1, "type_test_withdrawn_interface type_test_withdrawn_interface::withdrawn_func(type_test_withdrawn_interface param)\n{\n return param;\n}");
4748
@Sources_v1 = (@Sources_v1, "int withdrawn_func_2(void *** param)\n{\n return 0;\n}");
4750
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_interface\n{\npublic:\n type_test_withdrawn_interface func1(type_test_withdrawn_interface param);\n int i;\n long j;\n double k;\n type_test_withdrawn_interface* p;\n};");
4751
@Sources_v2 = (@Sources_v2, "type_test_withdrawn_interface type_test_withdrawn_interface::func1(type_test_withdrawn_interface param)\n{\n return param;\n}");
4753
#Function_Become_Static
4754
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_static\n{\npublic:\n type_test_become_static func_become_static(type_test_become_static param);\n int **i;\n long j;\n double k;\n type_test_become_static* p;\n};");
4755
@Sources_v1 = (@Sources_v1, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n return param;\n}");
4757
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_static\n{\npublic:\n static type_test_become_static func_become_static(type_test_become_static param);\n int **i;\n long j;\n double k;\n type_test_become_static* p;\n};");
4758
@Sources_v2 = (@Sources_v2, "type_test_become_static type_test_become_static::func_become_static(type_test_become_static param)\n{\n return param;\n}");
4760
#Function_Become_NonStatic
4761
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_become_nonstatic\n{\npublic:\n static type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n int **i;\n long j;\n double k;\n type_test_become_nonstatic* p;\n};");
4762
@Sources_v1 = (@Sources_v1, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n return param;\n}");
4764
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_become_nonstatic\n{\npublic:\n type_test_become_nonstatic func_become_nonstatic(type_test_become_nonstatic param);\n int **i;\n long j;\n double k;\n type_test_become_nonstatic* p;\n};");
4765
@Sources_v2 = (@Sources_v2, "type_test_become_nonstatic type_test_become_nonstatic::func_become_nonstatic(type_test_become_nonstatic param)\n{\n return param;\n}");
4767
#Parameter_Type_And_Size
4768
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
4769
@Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
4771
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
4772
@Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
4775
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
4776
@Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
4778
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
4779
@Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
4782
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
4783
@Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
4785
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
4786
@Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
4788
#Parameter_PointerLevel_And_Size
4789
@DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
4790
@Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
4792
@DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
4793
@Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
4795
#Parameter_PointerLevel
4796
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
4797
@Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
4799
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
4800
@Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
4802
#Return_Type_And_Size
4803
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
4804
@Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
4806
@DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
4807
@Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
4810
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
4811
@Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
4813
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
4814
@Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
4817
@DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetype(int param);");
4818
@Sources_v1 = (@Sources_v1, "int *func_return_basetype(int param)\n{\n int *x = new int[10];\n return x;\n}");
4820
@DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetype(int param);");
4821
@Sources_v2 = (@Sources_v2, "long long *func_return_basetype(int param)\n{\n long long *x = new long long[10];\n return x;\n}");
4823
#Return_PointerLevel_And_Size
4824
@DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
4825
@Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
4827
@DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
4828
@Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n long long* x = new long long[10];\n return x;\n}");
4830
#Return_PointerLevel
4831
@DataDefs_v1 = (@DataDefs_v1, "int* func_return_pointerlevel(int param);");
4832
@Sources_v1 = (@Sources_v1, "int* func_return_pointerlevel(int param)\n{\n int* x = new int[10];\n return x;\n}");
4834
@DataDefs_v2 = (@DataDefs_v2, "int **func_return_pointerlevel(int param);");
4835
@Sources_v2 = (@Sources_v2, "int **func_return_pointerlevel(int param)\n{\n int** x = new int*[10];\n return x;\n}");
4837
#typedef to anon struct
4838
@DataDefs_v1 = (@DataDefs_v1, "
4845
} type_test_anon_typedef;
4846
int func_test_anon_typedef(type_test_anon_typedef param);");
4847
@Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
4849
@DataDefs_v2 = (@DataDefs_v2, "
4859
char q_skiptable[256];
4864
} type_test_anon_typedef;
4865
int func_test_anon_typedef(type_test_anon_typedef param);");
4866
@Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
4869
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\npublic:\n virtual type_test_opaque func1(type_test_opaque param);\n int i;\n long j;\n double k;\n type_test_opaque* p;\n};");
4870
@Sources_v1 = (@Sources_v1, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
4872
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\npublic:\n virtual type_test_opaque func1(type_test_opaque param);\n int i;\n long j;\n double k;\n type_test_opaque* p;\n int added_member;\n};");
4873
@Sources_v2 = (@Sources_v2, "type_test_opaque type_test_opaque::func1(type_test_opaque param)\n{\n return param;\n}");
4876
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\npublic:\n virtual type_test_internal func1(type_test_internal param);\n int i;\n long j;\n double k;\n type_test_internal* p;\n};");
4877
@Sources_v1 = (@Sources_v1, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
4879
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\npublic:\n virtual type_test_internal func1(type_test_internal param);\n int i;\n long j;\n double k;\n type_test_internal* p;\n int added_member;\n};");
4880
@Sources_v2 = (@Sources_v2, "type_test_internal type_test_internal::func1(type_test_internal param)\n{\n return param;\n}");
4882
#starting versioning
4883
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
4884
@Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
4886
@DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
4887
@Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z37func_return_type_and_start_versioningi,_Z37func_return_type_and_start_versioningi\@TEST_2.0\");");
4889
#Return_Type And Good Versioning
4890
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
4891
@Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
4893
@DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
4894
@Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z40func_return_type_and_good_versioning_oldi,_Z36func_return_type_and_good_versioningi\@TEST_1.0\");");
4896
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
4897
@Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z36func_return_type_and_good_versioningi,_Z36func_return_type_and_good_versioningi\@TEST_2.0\");");
4899
#Return_Type and bad versioning
4900
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
4901
@Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
4903
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
4904
@Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z39func_return_type_and_bad_versioning_oldi,_Z35func_return_type_and_bad_versioningi\@TEST_1.0\");");
4906
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
4907
@Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver _Z35func_return_type_and_bad_versioningi,_Z35func_return_type_and_bad_versioningi\@TEST_2.0\");");
4909
#unnamed struct fields within structs
4910
@DataDefs_v1 = (@DataDefs_v1, "
4918
} type_test_unnamed;
4919
int func_test_unnamed(type_test_unnamed param);");
4920
@Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
4922
@DataDefs_v2 = (@DataDefs_v2, "
4930
} type_test_unnamed;
4931
int func_test_unnamed(type_test_unnamed param);");
4932
@Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
4935
@DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
4936
@DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
4938
@DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
4939
@DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
4942
@DataDefs_v1 = (@DataDefs_v1, "
4943
union type_test_union {
4951
int func_test_union(type_test_union param);");
4952
@Sources_v1 = (@Sources_v1, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
4954
@DataDefs_v2 = (@DataDefs_v2, "
4955
union type_test_union {
4957
long double new_member;
4964
int func_test_union(type_test_union param);");
4965
@Sources_v2 = (@Sources_v2, "int func_test_union(type_test_union param)\n{\n return 0;\n}");
4968
@DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
4969
@Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
4971
@DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
4972
@Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
4974
#typedefs in member type
4975
@DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
4976
@Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
4978
@DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\n public:\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(type_test_member_typedef_change param);");
4979
@Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(type_test_member_typedef_change param)\n{\n return 1;\n}");
4981
create_TestSuite("abi_changes_test_cpp", "C++", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "_ZN18type_test_internal5func1ES_");
4986
print "\ntesting for C library changes\n";
4987
my (@DataDefs_v1, @Sources_v1, @DataDefs_v2, @Sources_v2) = ();
4989
#Withdrawn_Parameter
4990
@DataDefs_v1 = (@DataDefs_v1, "int func_withdrawn_parameter(int param, int withdrawn_param);");
4991
@Sources_v1 = (@Sources_v1, "int func_withdrawn_parameter(int param, int withdrawn_param)\n{\n return 0;\n}");
4993
@DataDefs_v2 = (@DataDefs_v2, "int func_withdrawn_parameter(int param);");
4994
@Sources_v2 = (@Sources_v2, "int func_withdrawn_parameter(int param)\n{\n return 0;\n}");
4997
@DataDefs_v1 = (@DataDefs_v1, "int func_added_parameter(int param);");
4998
@Sources_v1 = (@Sources_v1, "int func_added_parameter(int param)\n{\n return 0;\n}");
5000
@DataDefs_v2 = (@DataDefs_v2, "int func_added_parameter(int param, int added_param);");
5001
@Sources_v2 = (@Sources_v2, "int func_added_parameter(int param, int added_param)\n{\n return 0;\n}");
5003
#added function with typedef funcptr parameter
5004
@DataDefs_v2 = (@DataDefs_v2, "typedef int (*FUNCPTR_TYPE)(int a, int b);\nint added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f);");
5005
@Sources_v2 = (@Sources_v2, "int added_function_param_typedef_funcptr(FUNCPTR_TYPE*const** f)\n{\n return 0;\n}");
5007
#added function with funcptr parameter
5008
@DataDefs_v2 = (@DataDefs_v2, "int added_function_param_funcptr(int(*func)(int, int));");
5009
@Sources_v2 = (@Sources_v2, "int added_function_param_funcptr(int(*func)(int, int))\n{\n return 0;\n}");
5011
#added function with no limited parameters
5012
@DataDefs_v2 = (@DataDefs_v2, "int added_function_nolimit_param(float p1, ...);");
5013
@Sources_v2 = (@Sources_v2, "int added_function_nolimit_param(float p1, ...)\n{\n return 0;\n}");
5016
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_size\n{\n long long i[5];\n long j;\n double k;\n struct type_test_size* p;\n};");
5017
@DataDefs_v1 = (@DataDefs_v1, "int func_test_type_size(struct type_test_size param, int param_2);");
5018
@Sources_v1 = (@Sources_v1, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
5020
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_size\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_size* p;\n};");
5021
@DataDefs_v2 = (@DataDefs_v2, "int func_test_type_size(struct type_test_size param, int param_2);");
5022
@Sources_v2 = (@Sources_v2, "int func_test_type_size(struct type_test_size param, int param_2)\n{\n return param_2;\n}");
5024
#Added_Member_And_Size
5025
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
5026
@DataDefs_v1 = (@DataDefs_v1, "int func_test_added_member(struct type_test_added_member param, int param_2);");
5027
@Sources_v1 = (@Sources_v1, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
5029
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n int added_member;\n};");
5030
@DataDefs_v2 = (@DataDefs_v2, "int func_test_added_member(struct type_test_added_member param, int param_2);");
5031
@Sources_v2 = (@Sources_v2, "int func_test_added_member(struct type_test_added_member param, int param_2)\n{\n return param_2;\n}");
5033
#Added_Middle_Member_And_Size
5034
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_added_middle_member\n{\n int i;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
5035
@DataDefs_v1 = (@DataDefs_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
5036
@Sources_v1 = (@Sources_v1, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n return param_2;\n}");
5038
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_added_middle_member\n{\n int i;\n int added_middle_member;\n long j;\n double k;\n struct type_test_added_member* p;\n};");
5039
@DataDefs_v2 = (@DataDefs_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2);");
5040
@Sources_v2 = (@Sources_v2, "int func_test_added_middle_member(struct type_test_added_middle_member param, int param_2)\n{\n return param_2;\n}");
5043
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_rename\n{\n long i;\n long j;\n double k;\n struct type_test_member_rename* p;\n};");
5044
@DataDefs_v1 = (@DataDefs_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
5045
@Sources_v1 = (@Sources_v1, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
5047
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_rename\n{\n long renamed_member;\n long j;\n double k;\n struct type_test_member_rename* p;\n};");
5048
@DataDefs_v2 = (@DataDefs_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2);");
5049
@Sources_v2 = (@Sources_v2, "int func_test_member_rename(struct type_test_member_rename param, int param_2)\n{\n return param_2;\n}");
5051
#Withdrawn_Member_And_Size
5052
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_member* p;\n int withdrawn_member;\n};");
5053
@DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
5054
@Sources_v1 = (@Sources_v1, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
5056
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_member* p;\n};");
5057
@DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2);");
5058
@Sources_v2 = (@Sources_v2, "int func_test_withdrawn_member(struct type_test_withdrawn_member param, int param_2)\n{\n return param_2;\n}");
5060
#Withdrawn_Middle_Member
5061
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_withdrawn_middle_member\n{\n int i;\n int withdrawn_middle_member;\n long j;\n double k;\n struct type_test_withdrawn_middle_member* p;\n};");
5062
@DataDefs_v1 = (@DataDefs_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
5063
@Sources_v1 = (@Sources_v1, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n return param_2;\n}");
5065
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_withdrawn_middle_member\n{\n int i;\n long j;\n double k;\n struct type_test_withdrawn_middle_member* p;\n};");
5066
@DataDefs_v2 = (@DataDefs_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2);");
5067
@Sources_v2 = (@Sources_v2, "int func_test_withdrawn_middle_member(struct type_test_withdrawn_middle_member param, int param_2)\n{\n return param_2;\n}");
5070
@DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_value_change\n{\n MEMBER_1=1,\n MEMBER_2=2\n};");
5071
@DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
5072
@Sources_v1 = (@Sources_v1,
5073
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
5085
@DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_value_change\n{\n MEMBER_1=2,\n MEMBER_2=1\n};");
5086
@DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_value_change(enum type_test_enum_member_value_change param);");
5087
@Sources_v2 = (@Sources_v2,
5088
"int func_test_enum_member_value_change(enum type_test_enum_member_value_change param)
5101
@DataDefs_v1 = (@DataDefs_v1, "enum type_test_enum_member_rename\n{\n BRANCH_1=1,\n BRANCH_2=2\n};");
5102
@DataDefs_v1 = (@DataDefs_v1, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
5103
@Sources_v1 = (@Sources_v1,
5104
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
5116
@DataDefs_v2 = (@DataDefs_v2, "enum type_test_enum_member_rename\n{\n BRANCH_FIRST=1,\n BRANCH_SECOND=1\n};");
5117
@DataDefs_v2 = (@DataDefs_v2, "int func_test_enum_member_rename(enum type_test_enum_member_rename param);");
5118
@Sources_v2 = (@Sources_v2,
5119
"int func_test_enum_member_rename(enum type_test_enum_member_rename param)
5131
#Member_Type_And_Size
5132
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type_and_size\n{\n int i;\n long j;\n double k;\n struct type_test_member_type_and_size* p;\n};");
5133
@DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
5134
@Sources_v1 = (@Sources_v1, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n return param_2;\n}");
5136
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type_and_size\n{\n int i;\n long j;\n long double k;\n struct type_test_member_type_and_size* p;\n};");
5137
@DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2);");
5138
@Sources_v2 = (@Sources_v2, "int func_test_member_type_and_size(struct type_test_member_type_and_size param, int param_2)\n{\n return param_2;\n}");
5141
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_type\n{\n int i;\n long j;\n double k;\n struct type_test_member_type* p;\n};");
5142
@DataDefs_v1 = (@DataDefs_v1, "int func_test_member_type(struct type_test_member_type param, int param_2);");
5143
@Sources_v1 = (@Sources_v1, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
5145
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_type\n{\n float i;\n long j;\n double k;\n struct type_test_member_type* p;\n};");
5146
@DataDefs_v2 = (@DataDefs_v2, "int func_test_member_type(struct type_test_member_type param, int param_2);");
5147
@Sources_v2 = (@Sources_v2, "int func_test_member_type(struct type_test_member_type param, int param_2)\n{\n return param_2;\n}");
5150
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_basetype\n{\n int i;\n long *j;\n double k;\n struct type_test_member_basetype* p;\n};");
5151
@DataDefs_v1 = (@DataDefs_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
5152
@Sources_v1 = (@Sources_v1, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
5154
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_basetype\n{\n int i;\n long long *j;\n double k;\n struct type_test_member_basetype* p;\n};");
5155
@DataDefs_v2 = (@DataDefs_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2);");
5156
@Sources_v2 = (@Sources_v2, "int func_test_member_basetype(struct type_test_member_basetype param, int param_2)\n{\n return param_2;\n}");
5158
#Member_PointerLevel_And_Size
5159
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel_and_size\n{\n int i;\n long long j;\n double k;\n struct type_test_member_pointerlevel_and_size* p;\n};");
5160
@DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
5161
@Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n return param_2;\n}");
5163
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel_and_size\n{\n int i;\n long long *j;\n double k;\n struct type_test_member_pointerlevel_and_size* p;\n};");
5164
@DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2);");
5165
@Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel_and_size(struct type_test_member_pointerlevel_and_size param, int param_2)\n{\n return param_2;\n}");
5167
#Member_PointerLevel
5168
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_member_pointerlevel\n{\n int i;\n long *j;\n double k;\n struct type_test_member_pointerlevel* p;\n};");
5169
@DataDefs_v1 = (@DataDefs_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
5170
@Sources_v1 = (@Sources_v1, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
5172
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_member_pointerlevel\n{\n int i;\n long **j;\n double k;\n struct type_test_member_pointerlevel* p;\n};");
5173
@DataDefs_v2 = (@DataDefs_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2);");
5174
@Sources_v2 = (@Sources_v2, "int func_test_member_pointerlevel(struct type_test_member_pointerlevel param, int param_2)\n{\n return param_2;\n}");
5177
@DataDefs_v2 = (@DataDefs_v2, "int added_func(int param);");
5178
@Sources_v2 = (@Sources_v2, "int added_func(int param)\n{\n return param;\n}");
5180
#Withdrawn_Interface
5181
@DataDefs_v1 = (@DataDefs_v1, "int withdrawn_func(int param);");
5182
@Sources_v1 = (@Sources_v1, "int withdrawn_func(int param)\n{\n return param;\n}");
5184
#Parameter_Type_And_Size
5185
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type_and_size(int param, int other_param);");
5186
@Sources_v1 = (@Sources_v1, "int func_parameter_type_and_size(int param, int other_param)\n{\n return other_param;\n}");
5188
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type_and_size(long long param, int other_param);");
5189
@Sources_v2 = (@Sources_v2, "int func_parameter_type_and_size(long long param, int other_param)\n{\n return other_param;\n}");
5192
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_type(int param, int other_param);");
5193
@Sources_v1 = (@Sources_v1, "int func_parameter_type(int param, int other_param)\n{\n return other_param;\n}");
5195
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_type(float param, int other_param);");
5196
@Sources_v2 = (@Sources_v2, "int func_parameter_type(float param, int other_param)\n{\n return other_param;\n}");
5198
#Parameter_BaseType (Typedef)
5199
@DataDefs_v1 = (@DataDefs_v1, "typedef int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
5200
@Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
5202
@DataDefs_v2 = (@DataDefs_v2, "typedef const int* PARAM_TYPEDEF;\nint func_parameter_basetypechange_typedef(PARAM_TYPEDEF param);");
5203
@Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange_typedef(PARAM_TYPEDEF param)\n{\n return 0;\n}");
5206
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_basetypechange(int *param);");
5207
@Sources_v1 = (@Sources_v1, "int func_parameter_basetypechange(int *param)\n{\n return sizeof(*param);\n}");
5209
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_basetypechange(long long *param);");
5210
@Sources_v2 = (@Sources_v2, "int func_parameter_basetypechange(long long *param)\n{\n return sizeof(*param);\n}");
5212
#Parameter_PointerLevel_And_Size
5213
@DataDefs_v1 = (@DataDefs_v1, "long long func_parameter_pointerlevel_and_size(long long param);");
5214
@Sources_v1 = (@Sources_v1, "long long func_parameter_pointerlevel_and_size(long long param)\n{\n return param;\n}");
5216
@DataDefs_v2 = (@DataDefs_v2, "long long func_parameter_pointerlevel_and_size(long long *param);");
5217
@Sources_v2 = (@Sources_v2, "long long func_parameter_pointerlevel_and_size(long long *param)\n{\n return param[5];\n}");
5219
#Parameter_PointerLevel
5220
@DataDefs_v1 = (@DataDefs_v1, "int func_parameter_pointerlevel(int *param);");
5221
@Sources_v1 = (@Sources_v1, "int func_parameter_pointerlevel(int *param)\n{\n return param[5];\n}");
5223
@DataDefs_v2 = (@DataDefs_v2, "int func_parameter_pointerlevel(int **param);");
5224
@Sources_v2 = (@Sources_v2, "int func_parameter_pointerlevel(int **param)\n{\n return param[5][5];\n}");
5226
#Return_Type_And_Size
5227
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_size(int param);");
5228
@Sources_v1 = (@Sources_v1, "int func_return_type_and_size(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
5230
@DataDefs_v2 = (@DataDefs_v2, "long long func_return_type_and_size(int param);");
5231
@Sources_v2 = (@Sources_v2, "long long func_return_type_and_size(int param)\n{\n return 2^(sizeof(long long)*8-1)-1;\n}");
5234
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type(int param);");
5235
@Sources_v1 = (@Sources_v1, "int func_return_type(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
5237
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type(int param);");
5238
@Sources_v2 = (@Sources_v2, "float func_return_type(int param)\n{\n return 0.7;\n}");
5241
@DataDefs_v1 = (@DataDefs_v1, "int *func_return_basetypechange(int param);");
5242
@Sources_v1 = (@Sources_v1, "int *func_return_basetypechange(int param)\n{\n int *x = (int*)malloc(10*sizeof(int));\n *x = 2^(sizeof(int)*8-1)-1;\n return x;\n}");
5244
@DataDefs_v2 = (@DataDefs_v2, "long long *func_return_basetypechange(int param);");
5245
@Sources_v2 = (@Sources_v2, "long long *func_return_basetypechange(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
5247
#Return_PointerLevel_And_Size
5248
@DataDefs_v1 = (@DataDefs_v1, "long long func_return_pointerlevel_and_size(int param);");
5249
@Sources_v1 = (@Sources_v1, "long long func_return_pointerlevel_and_size(int param)\n{\n return 100;\n}");
5251
@DataDefs_v2 = (@DataDefs_v2, "long long *func_return_pointerlevel_and_size(int param);");
5252
@Sources_v2 = (@Sources_v2, "long long *func_return_pointerlevel_and_size(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
5254
#Return_PointerLevel
5255
@DataDefs_v1 = (@DataDefs_v1, "long long *func_return_pointerlevel(int param);");
5256
@Sources_v1 = (@Sources_v1, "long long *func_return_pointerlevel(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n return x;\n}");
5258
@DataDefs_v2 = (@DataDefs_v2, "long long **func_return_pointerlevel(int param);");
5259
@Sources_v2 = (@Sources_v2, "long long **func_return_pointerlevel(int param)\n{\n long long *x = (long long*)malloc(10*sizeof(long long));\n *x = 2^(sizeof(long long)*8-1)-1;\n long *y = (long*)malloc(sizeof(long long));\n *y=(long)&x;\n return (long long **)y;\n}");
5261
#typedef to anon struct
5262
@DataDefs_v1 = (@DataDefs_v1, "
5268
} type_test_anon_typedef;
5269
int func_test_anon_typedef(type_test_anon_typedef param);");
5270
@Sources_v1 = (@Sources_v1, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
5272
@DataDefs_v2 = (@DataDefs_v2, "
5281
char q_skiptable[256];
5286
} type_test_anon_typedef;
5287
int func_test_anon_typedef(type_test_anon_typedef param);");
5288
@Sources_v2 = (@Sources_v2, "int func_test_anon_typedef(type_test_anon_typedef param)\n{\n return 0;\n}");
5291
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_opaque\n{\n long long i[5];\n long j;\n double k;\n struct type_test_opaque* p;\n};");
5292
@DataDefs_v1 = (@DataDefs_v1, "int func_test_opaque(struct type_test_opaque param, int param_2);");
5293
@Sources_v1 = (@Sources_v1, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
5295
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_opaque\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_opaque* p;\n};");
5296
@DataDefs_v2 = (@DataDefs_v2, "int func_test_opaque(struct type_test_opaque param, int param_2);");
5297
@Sources_v2 = (@Sources_v2, "int func_test_opaque(struct type_test_opaque param, int param_2)\n{\n return param_2;\n}");
5300
@DataDefs_v1 = (@DataDefs_v1, "struct type_test_internal\n{\n long long i[5];\n long j;\n double k;\n struct type_test_internal* p;\n};");
5301
@DataDefs_v1 = (@DataDefs_v1, "int func_test_internal(struct type_test_internal param, int param_2);");
5302
@Sources_v1 = (@Sources_v1, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
5304
@DataDefs_v2 = (@DataDefs_v2, "struct type_test_internal\n{\n long long i[5];\n long long j;\n double k;\n struct type_test_internal* p;\n};");
5305
@DataDefs_v2 = (@DataDefs_v2, "int func_test_internal(struct type_test_internal param, int param_2);");
5306
@Sources_v2 = (@Sources_v2, "int func_test_internal(struct type_test_internal param, int param_2)\n{\n return param_2;\n}");
5308
#starting versioning
5309
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_start_versioning(int param);");
5310
@Sources_v1 = (@Sources_v1, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}");
5312
@DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_start_versioning(int param);");
5313
@Sources_v2 = (@Sources_v2, "int func_return_type_and_start_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_start_versioning,func_return_type_and_start_versioning\@TEST_2.0\");");
5315
#Return_Type and good versioning
5316
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_good_versioning(int param);");
5317
@Sources_v1 = (@Sources_v1, "int func_return_type_and_good_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_1.0\");");
5319
@DataDefs_v2 = (@DataDefs_v2, "int func_return_type_and_good_versioning_old(int param);");
5320
@Sources_v2 = (@Sources_v2, "int func_return_type_and_good_versioning_old(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_good_versioning_old,func_return_type_and_good_versioning\@TEST_1.0\");");
5322
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_good_versioning(int param);");
5323
@Sources_v2 = (@Sources_v2, "float func_return_type_and_good_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_good_versioning,func_return_type_and_good_versioning\@TEST_2.0\");");
5325
#Return_Type and bad versioning
5326
@DataDefs_v1 = (@DataDefs_v1, "int func_return_type_and_bad_versioning(int param);");
5327
@Sources_v1 = (@Sources_v1, "int func_return_type_and_bad_versioning(int param)\n{\n return 2^(sizeof(int)*8-1)-1;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_1.0\");");
5329
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning_old(int param);");
5330
@Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning_old(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning_old,func_return_type_and_bad_versioning\@TEST_1.0\");");
5332
@DataDefs_v2 = (@DataDefs_v2, "float func_return_type_and_bad_versioning(int param);");
5333
@Sources_v2 = (@Sources_v2, "float func_return_type_and_bad_versioning(int param)\n{\n return 0.7;\n}\n__asm__(\".symver func_return_type_and_bad_versioning,func_return_type_and_bad_versioning\@TEST_2.0\");");
5335
#unnamed struct/union fields within structs/unions
5336
@DataDefs_v1 = (@DataDefs_v1, "
5344
} type_test_unnamed;
5345
int func_test_unnamed(type_test_unnamed param);");
5346
@Sources_v1 = (@Sources_v1, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
5348
@DataDefs_v2 = (@DataDefs_v2, "
5356
} type_test_unnamed;
5357
int func_test_unnamed(type_test_unnamed param);");
5358
@Sources_v2 = (@Sources_v2, "int func_test_unnamed(type_test_unnamed param)\n{\n return 0;\n}");
5361
@DataDefs_v1 = (@DataDefs_v1, "#define TEST_PUBLIC_CONSTANT \"old_value\"");
5362
@DataDefs_v2 = (@DataDefs_v2, "#define TEST_PUBLIC_CONSTANT \"new_value\"");
5364
@DataDefs_v1 = (@DataDefs_v1, "#define TEST_PRIVATE_CONSTANT \"old_value\"\n#undef TEST_PRIVATE_CONSTANT");
5365
@DataDefs_v2 = (@DataDefs_v2, "#define TEST_PRIVATE_CONSTANT \"new_value\"\n#undef TEST_PRIVATE_CONSTANT");
5368
@DataDefs_v1 = (@DataDefs_v1, "
5374
} *type_test_anonptr_typedef;
5375
extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
5379
@Sources_v1 = (@Sources_v1, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
5381
@DataDefs_v2 = (@DataDefs_v2, "
5387
} *type_test_anonptr_typedef;
5388
extern __attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param);
5392
@Sources_v2 = (@Sources_v2, "__attribute__ ((visibility(\"default\"))) int func_test_anonptr_typedef(type_test_anonptr_typedef param)\n{\n return 0;\n}");
5395
@DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
5396
@Sources_v1 = (@Sources_v1, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1.0;\n}");
5398
@DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE;\nint func_parameter_typedef_change(TYPEDEF_TYPE param);");
5399
@Sources_v2 = (@Sources_v2, "int func_parameter_typedef_change(TYPEDEF_TYPE param)\n{\n return 1;\n}");
5401
#typedefs in member type
5402
@DataDefs_v1 = (@DataDefs_v1, "typedef float TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
5403
@Sources_v1 = (@Sources_v1, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
5405
@DataDefs_v2 = (@DataDefs_v2, "typedef int TYPEDEF_TYPE_2;\nstruct type_test_member_typedef_change{\nTYPEDEF_TYPE_2 m;};\nint func_test_member_typedef_change(struct type_test_member_typedef_change param);");
5406
@Sources_v2 = (@Sources_v2, "int func_test_member_typedef_change(struct type_test_member_typedef_change param)\n{\n return 1;\n}");
5408
create_TestSuite("abi_changes_test_c", "C", join("\n\n", @DataDefs_v1), join("\n\n", @Sources_v1), join("\n\n", @DataDefs_v2), join("\n\n", @Sources_v2), "type_test_opaque", "func_test_internal");
5411
sub create_TestSuite($$$$$$$$)
5413
my ($Dir, $Lang, $DataDefs_v1, $Sources_v1, $DataDefs_v2, $Sources_v2, $Opaque, $Private) = @_;
5414
my $Ext = ($Lang eq "C++")?"cpp":"c";
5415
my $Gcc = ($Lang eq "C++")?"g++":"gcc";
5416
#creating test suite
5417
my $Path_v1 = "$Dir/lib_abi_changes_test.v1";
5418
my $Path_v2 = "$Dir/lib_abi_changes_test.v2";
5420
system("rm", "-fr", $Path_v1, $Path_v2);
5421
system("mkdir", "-p", $Path_v1, $Path_v2);
5423
writeFile("$Path_v1/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
5424
writeFile("$Path_v1/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v1."\n");
5425
writeFile("$Path_v1/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v1."\n");
5426
writeFile("$Dir/descriptor.v1", "<version>\n 1.0.0\n</version>\n\n<headers>\n ".$ENV{"PWD"}."/$Path_v1/\n</headers>\n\n<libs>\n ".$ENV{"PWD"}."/$Path_v1/\n</libs>\n\n<opaque_types>\n $Opaque\n</opaque_types>\n\n<skip_interfaces>\n $Private\n</skip_interfaces>\n\n<include_paths>\n ".$ENV{"PWD"}."/$Path_v1\n</include_paths>\n");
5428
writeFile("$Path_v2/version", "TEST_1.0 {\n};\nTEST_2.0 {\n};\n");
5429
writeFile("$Path_v2/lib_abi_changes_test.h", "#include <stdlib.h>\n".$DataDefs_v2."\n");
5430
writeFile("$Path_v2/lib_abi_changes_test.$Ext", "#include \"lib_abi_changes_test.h\"\n".$Sources_v2."\n");
5431
writeFile("$Dir/descriptor.v2", "<version>\n 2.0.0\n</version>\n\n<headers>\n ".$ENV{"PWD"}."/$Path_v2/\n</headers>\n\n<libs>\n ".$ENV{"PWD"}."/$Path_v2/\n</libs>\n\n<opaque_types>\n $Opaque\n</opaque_types>\n\n<skip_interfaces>\n $Private\n</skip_interfaces>\n\n<include_paths>\n ".$ENV{"PWD"}."/$Path_v2\n</include_paths>\n");
5433
system("$Gcc $Path_v1/lib_abi_changes_test.h");
5436
print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.h\'\n";
5439
system("$Gcc -Wl,--version-script $Path_v1/version -shared $Path_v1/lib_abi_changes_test.$Ext -o $Path_v1/lib_abi_changes_test.so");
5442
print "ERROR: can't compile \'$Path_v1/lib_abi_changes_test.$Ext\'\n";
5445
system("$Gcc $Path_v2/lib_abi_changes_test.h");
5448
print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.h\'\n";
5451
system("$Gcc -Wl,--version-script $Path_v2/version -shared $Path_v2/lib_abi_changes_test.$Ext -o $Path_v2/lib_abi_changes_test.so");
5454
print "ERROR: can't compile \'$Path_v2/lib_abi_changes_test.$Ext\'\n";
5458
#running abi-compliance-checker
5459
system("$0 -l lib_$Dir -d1 $Dir/descriptor.v1 -d2 $Dir/descriptor.v2");
5464
my ($Path, $Content) = @_;
5465
return if(not $Path);
5466
open (FILE, ">".$Path) || die ("Can't open file $Path\n");
5467
print FILE $Content;
5474
return "" if(not $Path or not -f $Path);
5476
my $Content = join("\n", <FILE>);
5478
return toUnix($Content);
5490
my $Arch = $ENV{"CPU"};
5501
$Arch = "x86" if($Arch =~ /i[3-7]86/);
5505
sub get_Report_Header()
5507
my $Report_Header = "<h1>ABI compliance report for the library <span style='color:Blue;white-space:nowrap;'>$TargetLibraryName </span> from version <span style='color:Red;white-space:nowrap;'>".$Descriptor{1}{"Version"}."</span> to <span style='color:Red;white-space:nowrap;'>".$Descriptor{2}{"Version"}."</span> on <span style='color:Blue;'>".getArch()."</span> ".(($AppPath)?"relating to the portability of application <span style='color:Blue;'>".get_FileName($AppPath)."</span>":"")."</h1>\n";
5508
return "<!--Header-->\n".$Report_Header."<!--Header_End-->\n";
5511
sub get_SourceInfo()
5513
my $CheckedHeaders = "<!--Checked_Headers-->\n<a name='Checked_Headers'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked header files (".keys(%{$Headers{1}}).")</h2><hr/>\n";
5514
foreach my $Header_Dest (sort {lc($Headers{1}{$a}{"Name"}) cmp lc($Headers{1}{$b}{"Name"})} keys(%{$Headers{1}}))
5516
my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
5517
my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
5518
my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
5519
my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
5520
$CheckedHeaders .= "<span class='header_list_elem'>$Header_Name"."$Dest_Comment</span><br/>\n";
5522
$CheckedHeaders .= "<!--Checked_Headers_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5523
my $CheckedLibs = "<!--Checked_Libs-->\n<a name='Checked_Libs'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Checked shared objects (".keys(%{$SoNames_All{1}}).")</h2><hr/>\n";
5524
foreach my $Library (sort {lc($a) cmp lc($b)} keys(%{$SoNames_All{1}}))
5526
$CheckedLibs .= "<span class='solib_list_elem'>$Library</span><br/>\n";
5528
$CheckedLibs .= "<!--Checked_Libs_End--><br/><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5529
return $CheckedHeaders.$CheckedLibs;
5532
sub get_TypeProblems_Count($$)
5534
my ($TypeChanges, $TargetPriority) = @_;
5535
my $Type_Problems_Count = 0;
5536
foreach my $TypeName (sort keys(%{$TypeChanges}))
5538
my %Kinds_Target = ();
5539
foreach my $Kind (keys(%{$TypeChanges->{$TypeName}}))
5541
foreach my $Location (keys(%{$TypeChanges->{$TypeName}{$Kind}}))
5543
my $Priority = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Priority"};
5544
next if($Priority ne $TargetPriority);
5545
my $Target = $TypeChanges->{$TypeName}{$Kind}{$Location}{"Target"};
5546
next if($Kinds_Target{$Kind}{$Target});
5547
$Kinds_Target{$Kind}{$Target} = 1;
5548
$Type_Problems_Count += 1;
5552
return $Type_Problems_Count;
5557
my ($Added, $Withdrawn, $I_Problems_High, $I_Problems_Medium, $I_Problems_Low, $T_Problems_High, $T_Problems_Medium, $T_Problems_Low) = (0,0,0,0,0,0,0,0);
5558
foreach my $Interface (sort keys(%CompatProblems))
5560
foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5562
if($InterfaceProblems_Kind{$Kind})
5564
foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5566
if($Kind eq "Added_Interface")
5570
elsif($Kind eq "Withdrawn_Interface")
5576
if($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "High")
5578
$I_Problems_High += 1;
5580
elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Medium")
5582
$I_Problems_Medium += 1;
5584
elsif($CompatProblems{$Interface}{$Kind}{$Location}{"Priority"} eq "Low")
5586
$I_Problems_Low += 1;
5594
my (%TypeChanges, %Type_MaxPriority);
5595
foreach my $Interface (sort keys(%CompatProblems))
5597
foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
5599
if($TypeProblems_Kind{$Kind})
5601
foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
5603
my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
5604
my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
5605
%{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
5606
$Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
5612
foreach my $Type_Name (keys(%TypeChanges))
5614
foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
5616
foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
5618
my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
5619
if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
5621
delete($TypeChanges{$Type_Name}{$Kind}{$Location});
5627
$T_Problems_High = get_TypeProblems_Count(\%TypeChanges, "High");
5628
$T_Problems_Medium = get_TypeProblems_Count(\%TypeChanges, "Medium");
5629
$T_Problems_Low = get_TypeProblems_Count(\%TypeChanges, "Low");
5632
my $Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Summary</h2><hr/>";
5633
$Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
5636
my $Checked_Headers_Link = "0";
5637
$Checked_Headers_Link = "<a href='#Checked_Headers' style='color:Blue;'>".keys(%{$Headers{1}})."</a>" if(keys(%{$Headers{1}})>0);
5638
$Summary .= "<tr><td class='table_header summary_item'>Total header files checked</td><td class='summary_item_value'>$Checked_Headers_Link</td></tr>";
5640
my $Checked_Libs_Link = "0";
5641
$Checked_Libs_Link = "<a href='#Checked_Libs' style='color:Blue;'>".keys(%{$SoNames_All{1}})."</a>" if(keys(%{$SoNames_All{1}})>0);
5642
$Summary .= "<tr><td class='table_header summary_item'>Total shared objects checked</td><td class='summary_item_value'>$Checked_Libs_Link</td></tr>";
5643
$Summary .= "<tr><td class='table_header summary_item'>Total interfaces / types checked</td><td class='summary_item_value'>".keys(%CheckedInterfaces)." / ".keys(%CheckedTypes)."</td></tr>";
5645
my $Verdict = "<span style='color:Green;'><b>Compatible</b></span>";
5646
$Verdict = "<span style='color:Red;'><b>Incompatible</b></span>" if(($Withdrawn>0) or ($I_Problems_High>0) or ($T_Problems_High>0));
5647
$Summary .= "<tr><td class='table_header summary_item'>Verdict</td><td class='summary_item_value'>$Verdict</td></tr>";
5649
$Summary .= "</table>\n";
5652
my $Problem_Summary = "<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problem Summary</h2><hr/>";
5653
$Problem_Summary .= "<table cellpadding='3' border='1' style='border-collapse:collapse;'>";
5655
my $Added_Link = "0";
5656
$Added_Link = "<a href='#Added' style='color:Blue;'>$Added</a>" if($Added>0);
5657
$Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Added interfaces</td><td class='summary_item_value'>$Added_Link</td></tr>";
5659
my $WIthdrawn_Link = "0";
5660
$WIthdrawn_Link = "<a href='#Withdrawn' style='color:Blue;'>$Withdrawn</a>" if($Withdrawn>0);
5661
$Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Withdrawn interfaces</td><td class='summary_item_value'>$WIthdrawn_Link</td></tr>";
5664
$TH_Link = "<a href='#Type_Problems_High' style='color:Blue;'>$T_Problems_High</a>" if($T_Problems_High>0);
5665
$Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Problems in<br/>Data Types</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td align='right' class='summary_item_value'>$TH_Link</td></tr>";
5668
$TM_Link = "<a href='#Type_Problems_Medium' style='color:Blue;'>$T_Problems_Medium</a>" if($T_Problems_Medium>0);
5669
$Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$TM_Link</td></tr>";
5672
$TL_Link = "<a href='#Type_Problems_Low' style='color:Blue;'>$T_Problems_Low</a>" if($T_Problems_Low>0);
5673
$Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$TL_Link</td></tr>";
5676
$IH_Link = "<a href='#Interface_Problems_High' style='color:Blue;'>$I_Problems_High</a>" if($I_Problems_High>0);
5677
$Problem_Summary .= "<tr><td class='table_header summary_item' rowspan='3'>Interface<br/>problems</td><td class='table_header summary_item' style='color:Red;'>High risk</td><td class='summary_item_value'>$IH_Link</td></tr>";
5680
$IM_Link = "<a href='#Interface_Problems_Medium' style='color:Blue;'>$I_Problems_Medium</a>" if($I_Problems_Medium>0);
5681
$Problem_Summary .= "<tr><td class='table_header summary_item'>Medium risk</td><td class='summary_item_value'>$IM_Link</td></tr>";
5684
$IL_Link = "<a href='#Interface_Problems_Low' style='color:Blue;'>$I_Problems_Low</a>" if($I_Problems_Low>0);
5685
$Problem_Summary .= "<tr><td class='table_header summary_item'>Low risk</td><td class='summary_item_value'>$IL_Link</td></tr>";
5687
my $ChangedConstants_Link = "0";
5688
$ChangedConstants_Link = "<a href='#Constants' style='color:Blue;'>".keys(%ConstantProblems)."</a>" if(keys(%ConstantProblems)>0);
5689
$Problem_Summary .= "<tr><td class='table_header summary_item' colspan='2'>Constants Problems</td><td class='summary_item_value'>$ChangedConstants_Link</td></tr>";
5691
$Problem_Summary .= "</table>\n";
5692
return "<!--Summary-->\n".$Summary.$Problem_Summary."<!--Summary_End-->\n";
5695
sub get_Report_ChangedConstants()
5697
my ($CHANGED_CONSTANTS, %HeaderConstant);
5698
foreach my $Name (keys(%ConstantProblems))
5700
$HeaderConstant{$ConstantProblems{$Name}{"Header"}}{$Name} = 1;
5702
my $Constants_Number = 0;
5703
foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%HeaderConstant))
5705
$CHANGED_CONSTANTS .= "<span class='header_name'>$HeaderName</span><br/>\n";
5706
foreach my $Name (sort {lc($a) cmp lc($b)} keys(%{$HeaderConstant{$HeaderName}}))
5708
$Constants_Number += 1;
5709
my $Old_Value = htmlSpecChars($ConstantProblems{$Name}{"Old_Value"});
5710
my $New_Value = htmlSpecChars($ConstantProblems{$Name}{"New_Value"});
5711
my $Incompatibility = "The value of constant <b>$Name</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
5712
my $Effect = "If application uses this constant as a parameter of some interface than its execution may change.";
5713
my $ConstantProblemsReport = "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>1</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
5714
$CHANGED_CONSTANTS .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Name.$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$ConstantProblemsReport</table><br/>$ContentDivEnd\n";
5715
$CHANGED_CONSTANTS = insertIDs($CHANGED_CONSTANTS);
5717
$CHANGED_CONSTANTS .= "<br/>\n";
5719
if($CHANGED_CONSTANTS)
5721
$CHANGED_CONSTANTS = "<a name='Constants'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Constants Problems ($Constants_Number)</h2><hr/>\n"."<!--Changed_Constants-->\n".$CHANGED_CONSTANTS."<!--Changed_Constants_End-->\n"."<input id='Changed_Constants_Count' type='hidden' value=\'$Constants_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5723
return $CHANGED_CONSTANTS;
5726
sub get_Report_Added()
5728
my $ADDED_INTERFACES;
5730
my %FuncAddedInHeaderLib;
5731
foreach my $Interface (sort keys(%CompatProblems))
5733
foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5735
foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5737
if($Kind eq "Added_Interface")
5739
$FuncAddedInHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"New_SoName"}}{$Interface} = 1;
5745
my $Added_Number = 0;
5746
foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncAddedInHeaderLib))
5748
foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncAddedInHeaderLib{$HeaderName}}))
5752
$ADDED_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
5756
$ADDED_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
5758
foreach my $Interface (sort {lc($CompatProblems{$a}{"Added_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Added_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncAddedInHeaderLib{$HeaderName}{$SoName}}))
5762
my $Signature = $CompatProblems{$Interface}{"Added_Interface"}{"SharedLibrary"}{"Signature"};
5763
if($Interface =~ /\A_Z/)
5767
$SubReport = insertIDs($ContentSpanStart.highLight_Signature_Italic_Color(htmlSpecChars($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
5771
$SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5778
$SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
5782
$SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5785
$ADDED_INTERFACES .= $SubReport;
5787
$ADDED_INTERFACES .= "<br/>\n";
5790
if($ADDED_INTERFACES)
5792
$ADDED_INTERFACES = "<a name='Added'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Added Interfaces ($Added_Number)</h2><hr/>\n"."<!--Added_Interfaces-->\n".$ADDED_INTERFACES."<!--Added_Interfaces_End-->\n"."<input id='Added_Interfaces_Count' type='hidden' value=\'$Added_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5794
return $ADDED_INTERFACES;
5797
sub get_Report_Withdrawn()
5799
my $WITHDRAWN_INTERFACES;
5800
#withdrawn interfaces
5801
my %FuncWithdrawnFromHeaderLib;
5802
foreach my $Interface (sort keys(%CompatProblems))
5804
foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5806
foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5808
if($Kind eq "Withdrawn_Interface")
5810
$FuncWithdrawnFromHeaderLib{$CompatProblems{$Interface}{$Kind}{$Location}{"Header"}}{$CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"}}{$Interface} = 1;
5816
my $Withdrawn_Number = 0;
5817
foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncWithdrawnFromHeaderLib))
5819
foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}}))
5823
$WITHDRAWN_INTERFACES .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n";
5827
$WITHDRAWN_INTERFACES .= "<span class='solib_name'>$SoName</span><br/>\n";
5829
foreach my $Interface (sort {lc($CompatProblems{$a}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"}) cmp lc($CompatProblems{$b}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"})} keys(%{$FuncWithdrawnFromHeaderLib{$HeaderName}{$SoName}}))
5831
$Withdrawn_Number += 1;
5833
my $Signature = $CompatProblems{$Interface}{"Withdrawn_Interface"}{"SharedLibrary"}{"Signature"};
5834
if($Interface =~ /\A_Z/)
5838
$SubReport = insertIDs($ContentSpanStart.highLight_Signature_Italic_Color(htmlSpecChars($Signature)).$ContentSpanEnd."<br/>\n".$ContentDivStart."<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/><br/>".$ContentDivEnd."\n");
5842
$SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5849
$SubReport = "<span class=\"interface_name\">".highLight_Signature_Italic_Color($Signature)."</span>"."<br/>\n";
5853
$SubReport = "<span class=\"interface_name\">".$Interface."</span>"."<br/>\n";
5856
$WITHDRAWN_INTERFACES .= $SubReport;
5858
$WITHDRAWN_INTERFACES .= "<br/>\n";
5861
if($WITHDRAWN_INTERFACES)
5863
$WITHDRAWN_INTERFACES = "<a name='Withdrawn'></a><h2 style='margin-bottom:0px;padding-bottom:0px;'>Withdrawn Interfaces ($Withdrawn_Number)</h2><hr/>\n"."<!--Withdrawn_Interfaces-->\n".$WITHDRAWN_INTERFACES."<!--Withdrawn_Interfaces_End-->\n"."<input id='Withdrawn_Interfaces_Count' type='hidden' value=\'$Withdrawn_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
5865
return $WITHDRAWN_INTERFACES;
5868
sub get_Report_InterfaceProblems($)
5870
my $TargetPriority = $_[0];
5871
my ($INTERFACE_PROBLEMS, %FuncHeaderLib);
5872
foreach my $Interface (sort keys(%CompatProblems))
5874
foreach my $Kind (sort keys(%{$CompatProblems{$Interface}}))
5876
if($InterfaceProblems_Kind{$Kind} and ($Kind ne "Added_Interface") and ($Kind ne "Withdrawn_Interface"))
5878
foreach my $Location (sort keys(%{$CompatProblems{$Interface}{$Kind}}))
5880
my $SoName = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_SoName"};
5881
my $HeaderName = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
5882
$FuncHeaderLib{$HeaderName}{$SoName}{$Interface} = 1;
5888
my $Problems_Number = 0;
5890
foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%FuncHeaderLib))
5892
foreach my $SoName (sort {lc($a) cmp lc($b)} keys(%{$FuncHeaderLib{$HeaderName}}))
5894
my $HEADER_LIB_REPORT = "";
5895
foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%{$FuncHeaderLib{$HeaderName}{$SoName}}))
5898
my $InterfaceProblemsReport = "";
5900
foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
5902
foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
5904
my $Incompatibility = "";
5906
my $Old_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"});
5907
my $New_Value = htmlSpecChars($CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"});
5908
my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
5909
my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
5910
my $Old_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Size"};
5911
my $New_Size = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Size"};
5912
my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
5913
my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
5914
my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
5915
$Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"} if(not $Signature);
5916
next if($Priority ne $TargetPriority);
5917
if($Kind eq "Function_Become_Static")
5919
$Incompatibility = "Function become <b>static</b>.\n";
5920
$Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5922
elsif($Kind eq "Function_Become_NonStatic")
5924
$Incompatibility = "Function become <b>non-static</b>.\n";
5925
$Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5927
elsif($Kind eq "Parameter_Type_And_Size")
5929
$Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5930
$Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5932
elsif($Kind eq "Parameter_Type")
5934
$Incompatibility = "Type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5935
$Effect = "Replacement of parameter data type may indicate a change in the semantic meaning of this parameter.";
5937
elsif($Kind eq "Withdrawn_Parameter")
5939
$Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been withdrawn from the interface signature.\n";
5940
$Effect = "This parameter will be ignored by the interface.";
5942
elsif($Kind eq "Added_Parameter")
5944
$Incompatibility = "$Parameter_Position_Str parameter <b>$Target</b> has been added to the interface signature.\n";
5945
$Effect = "This parameter will not be initialized by applications.";
5947
elsif($Kind eq "Parameter_BaseType_And_Size")
5949
if($InitialType_Type eq "Pointer")
5951
$Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5952
$Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
5956
$Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5957
$Effect = "Layout of parameter's stack has been changed and therefore parameters in higher positions in the stack may be incorrectly initialized by applications.";
5960
elsif($Kind eq "Parameter_BaseType")
5962
if($InitialType_Type eq "Pointer")
5964
$Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5965
$Effect = "Memory stored by pointer may be incorrectly initialized by applications.";
5969
$Incompatibility = "Base type of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5970
$Effect = "Replacement of parameter base type may indicate a change in the semantic meaning of this parameter.";
5973
elsif($Kind eq "Parameter_PointerLevel")
5975
$Incompatibility = "Type pointer level of $Parameter_Position_Str parameter <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
5976
$Effect = "Possible incorrect initialization of $Parameter_Position_Str parameter <b>$Target</b> by applications.";
5978
elsif($Kind eq "Return_Type_And_Size")
5980
$Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5981
$Effect = "Applications will get a different return value and execution may change.";
5983
elsif($Kind eq "Return_Type")
5985
$Incompatibility = "Type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5986
$Effect = "Replacement of return type may indicate a change in its semantic meaning.";
5988
elsif($Kind eq "Return_BaseType_And_Size")
5990
$Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.\n";
5991
$Effect = "Applications will get a different return value and execution may change.";
5993
elsif($Kind eq "Return_BaseType")
5995
$Incompatibility = "Base type of return value has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.\n";
5996
$Effect = "Replacement of return base type may indicate a change in its semantic meaning.";
5998
elsif($Kind eq "Return_PointerLevel")
6000
$Incompatibility = "Type pointer level of return value has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.\n";
6001
$Effect = "Applications will get a different return value and execution may change.";
6003
if($Incompatibility)
6005
$InterfaceProblemsReport .= "<tr><td align='center' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>".$Effect."</span></td></tr>\n";
6007
$Problems_Number += 1;
6012
if($InterfaceProblemsReport)
6014
if($Interface =~ /\A_Z/)
6018
$HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<span class='mangled'>[ symbol: <b>$Interface</b> ]</span><br/>\n";
6022
$HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
6029
$HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".highLight_Signature_Italic_Color(htmlSpecChars($Signature))." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
6033
$HEADER_LIB_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".$Interface." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart\n";
6036
$HEADER_LIB_REPORT .= "<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$InterfaceProblemsReport</table><br/>$ContentDivEnd\n";
6037
$HEADER_LIB_REPORT = insertIDs($HEADER_LIB_REPORT);
6040
if($HEADER_LIB_REPORT)
6042
$INTERFACE_PROBLEMS .= "<span class='header_name'>$HeaderName</span>, <span class='solib_name'>$SoName</span><br/>\n".$HEADER_LIB_REPORT."<br/>";
6046
if($INTERFACE_PROBLEMS)
6048
$INTERFACE_PROBLEMS = "<a name=\'Interface_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Interface problems, $TargetPriority risk ($Problems_Number)</h2><hr/>\n"."<!--Interface_Problems_".$TargetPriority."-->\n".$INTERFACE_PROBLEMS."<!--Interface_Problems_".$TargetPriority."_End-->\n"."<input id=\'Interface_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
6050
return $INTERFACE_PROBLEMS;
6053
sub get_Report_TypeProblems($)
6055
my $TargetPriority = $_[0];
6056
my ($TYPE_PROBLEMS, %TypeHeader, %TypeChanges, %Type_MaxPriority) = ();
6057
foreach my $Interface (sort keys(%CompatProblems))
6059
foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
6061
if($TypeProblems_Kind{$Kind})
6063
foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
6065
my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
6066
my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
6067
my $Type_Header = $CompatProblems{$Interface}{$Kind}{$Location}{"Header"};
6068
%{$TypeChanges{$Type_Name}{$Kind}{$Location}} = %{$CompatProblems{$Interface}{$Kind}{$Location}};
6069
$TypeHeader{$Type_Header}{$Type_Name} = 1;
6070
$Type_MaxPriority{$Type_Name}{$Kind} = max_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority);
6075
foreach my $Type_Name (keys(%TypeChanges))
6077
foreach my $Kind (keys(%{$TypeChanges{$Type_Name}}))
6079
foreach my $Location (keys(%{$TypeChanges{$Type_Name}{$Kind}}))
6081
my $Priority = $TypeChanges{$Type_Name}{$Kind}{$Location}{"Priority"};
6082
if(cmp_priority($Type_MaxPriority{$Type_Name}{$Kind}, $Priority))
6084
delete($TypeChanges{$Type_Name}{$Kind}{$Location});
6089
my $Problems_Number = 0;
6090
foreach my $HeaderName (sort {lc($a) cmp lc($b)} keys(%TypeHeader))
6092
my $HEADER_REPORT = "";
6093
foreach my $TypeName (sort {lc($a) cmp lc($b)} keys(%{$TypeHeader{$HeaderName}}))
6096
my $TypeProblemsReport = "";
6097
my %Kinds_Locations = ();
6098
my %Kinds_Target = ();
6099
foreach my $Kind (keys(%{$TypeChanges{$TypeName}}))
6101
foreach my $Location (keys(%{$TypeChanges{$TypeName}{$Kind}}))
6103
my $Priority = $TypeChanges{$TypeName}{$Kind}{$Location}{"Priority"};
6104
next if($Priority ne $TargetPriority);
6105
$Kinds_Locations{$Kind}{$Location} = 1;
6106
my $Incompatibility = "";
6108
my $Target = $TypeChanges{$TypeName}{$Kind}{$Location}{"Target"};
6109
next if($Kinds_Target{$Kind}{$Target});
6110
$Kinds_Target{$Kind}{$Target} = 1;
6111
my $Old_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Value"});
6112
my $New_Value = htmlSpecChars($TypeChanges{$TypeName}{$Kind}{$Location}{"New_Value"});
6113
my $Old_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"Old_Size"};
6114
my $New_Size = $TypeChanges{$TypeName}{$Kind}{$Location}{"New_Size"};
6115
my $Type_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"Type_Type"};
6116
my $InitialType_Type = $TypeChanges{$TypeName}{$Kind}{$Location}{"InitialType_Type"};
6118
if($Kind eq "Added_Virtual_Function")
6120
$Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been added to this class and therefore the layout of virtual table has been changed.";
6121
$Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
6123
elsif($Kind eq "Withdrawn_Virtual_Function")
6125
$Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been withdrawn from this class and therefore the layout of virtual table has been changed.";
6126
$Effect = "Call of any virtual method in this class or its subclasses will result in crash of application.";
6128
elsif($Kind eq "Virtual_Function_Position")
6130
$Incompatibility = "The relative position of virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Target))."</span>"." has been changed from <b>$Old_Value</b> to <b>$New_Value</b> and therefore the layout of virtual table has been changed.";
6131
$Effect = "Call of this virtual method will result in crash of application.";
6133
elsif($Kind eq "Virtual_Function_Redefinition")
6135
$Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>";
6136
$Effect = "Method <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>";
6138
elsif($Kind eq "Virtual_Function_Redefinition_B")
6140
$Incompatibility = "Virtual method "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>"." has been redefined by "."<span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span>";
6141
$Effect = "Method <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($Old_Value))."</span> will be called instead of <span class='interface_name_black'>".highLight_Signature(htmlSpecChars($New_Value))."</span>";
6143
elsif($Kind eq "Size")
6145
$Incompatibility = "Size of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b> bytes.";
6146
$Effect = "Change of type size may lead to different effects in different contexts. $ContentSpanStart"."<span style='color:Black'>[+] ...</span>"."$ContentSpanEnd <label id=\"CONTENT_ID\" style=\"display:none;\"> In the context of function parameters, this change affects the parameter's stack layout and may lead to incorrect initialization of parameters in higher positions in the stack. In the context of structure members, this change affects the member's layout and may lead to incorrect attempts to access members in higher positions. Other effects are possible.</label>";
6148
elsif($Kind eq "BaseType")
6150
$Incompatibility = "Base of this type has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6151
$Effect = "Possible incorrect initialization of interface parameters by applications.";
6153
elsif($Kind eq "Added_Member_And_Size")
6155
$Incompatibility = "Member <b>$Target</b> has been added to this type.";
6156
$Effect = "The size of the inclusive type has been changed.";
6158
elsif($Kind eq "Added_Middle_Member_And_Size")
6160
$Incompatibility = "Member <b>$Target</b> has been added between the first member and the last member of this structural type.";
6161
$Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) The size of the inclusive type will also be affected.";
6163
elsif($Kind eq "Member_Rename")
6165
$Incompatibility = "Member <b>$Target</b> has been renamed to <b>$New_Value</b>.";
6166
$Effect = "Renaming of a member in a structural data type may indicate a change in the semantic meaning of the member.";
6168
elsif($Kind eq "Withdrawn_Member_And_Size")
6170
$Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
6171
$Effect = "1) Applications will access incorrect memory when attempting to access this member.<br/>2) The size of the inclusive type will also be affected.";
6173
elsif($Kind eq "Withdrawn_Member")
6175
$Incompatibility = "Member <b>$Target</b> has been withdrawn from this type.";
6176
$Effect = "Applications will access incorrect memory when attempting to access this member.";
6178
elsif($Kind eq "Withdrawn_Middle_Member_And_Size")
6180
$Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
6181
$Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Previous accesses of applications to the withdrawn member will be incorrect.";
6183
elsif($Kind eq "Withdrawn_Middle_Member")
6185
$Incompatibility = "Member <b>$Target</b> has been withdrawn from this structural type between the first member and the last member.";
6186
$Effect = "1) Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.<br/>2) Applications will access incorrect memory when attempting to access this member.";
6188
elsif($Kind eq "Enum_Member_Value")
6190
$Incompatibility = "Value of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6191
$Effect = "Applications may execute another branch of library code.";
6193
elsif($Kind eq "Enum_Member_Name")
6195
$Incompatibility = "Name of member with value <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6196
$Effect = "Applications may execute another branch of library code.";
6198
elsif($Kind eq "Member_Type_And_Size")
6200
$Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
6201
$Effect = "Layout of structure members has been changed and therefore members in higher positions in the structure definition may be incorrectly accessed by applications.";
6203
elsif($Kind eq "Member_Type")
6205
$Incompatibility = "Type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
6206
$Effect = "Replacement of the member data type may indicate a change in the semantic meaning of the member.";
6208
elsif($Kind eq "Member_BaseType_And_Size")
6210
if($InitialType_Type eq "Pointer")
6212
$Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
6213
$Effect = "Possible access of applications to incorrect memory via member pointer.";
6217
$Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b> (<b>$Old_Size</b> bytes)</span> to <span style='white-space:nowrap;'><b>$New_Value</b> (<b>$New_Size</b> bytes)</span>.";
6218
$Effect = "Layout of structure members has been changed and therefore members in higher positions in structure definition may be incorrectly accessed by applications.";
6221
elsif($Kind eq "Member_BaseType")
6223
if($InitialType_Type eq "Pointer")
6225
$Incompatibility = "Base type of member <b>$Target</b> (pointer) has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
6226
$Effect = "Possible access of applications to incorrect memory via member pointer.";
6230
$Incompatibility = "Base type of member <b>$Target</b> has been changed from <span style='white-space:nowrap;'><b>$Old_Value</b></span> to <span style='white-space:nowrap;'><b>$New_Value</b></span>.";
6231
$Effect = "Replacement of member base type may indicate a change in the semantic meaning of this member.";
6234
elsif($Kind eq "Member_PointerLevel")
6236
$Incompatibility = "Type pointer level of member <b>$Target</b> has been changed from <b>$Old_Value</b> to <b>$New_Value</b>.";
6237
$Effect = "Possible incorrect initialization of member <b>$Target</b> by applications.";
6239
if($Incompatibility)
6241
$TypeProblemsReport .= "<tr><td align='center' valign='top' class='table_header'><span class='problem_num'>$ProblemNum</span></td><td align='left' valign='top'><span class='problem_body'>".$Incompatibility."</span></td><td align='left' valign='top'><span class='problem_body'>$Effect</span></td></tr>\n";
6243
$Problems_Number += 1;
6244
$Kinds_Locations{$Kind}{$Location} = 1;
6249
if($TypeProblemsReport)
6251
my ($Affected_Interfaces_Header, $Affected_Interfaces) = getAffectedInterfaces($TypeName, \%Kinds_Locations);
6252
$HEADER_REPORT .= $ContentSpanStart."<span class='extension'>[+]</span> ".htmlSpecChars($TypeName)." ($ProblemNum)".$ContentSpanEnd."<br/>\n$ContentDivStart<table width='900px' cellpadding='3' cellspacing='0' class='problems_table'><tr><td align='center' width='2%' class='table_header'><span class='problem_title' style='white-space:nowrap;'></span></td><td width='47%' align='center' class='table_header'><span class='problem_sub_title'>Incompatibility</span></td><td align='center' class='table_header'><span class='problem_sub_title'>Effect</span></td></tr>$TypeProblemsReport</table>"."<span style='padding-left:10px'>$Affected_Interfaces_Header</span>$Affected_Interfaces<br/><br/>$ContentDivEnd\n";
6253
$HEADER_REPORT = insertIDs($HEADER_REPORT);
6258
$TYPE_PROBLEMS .= "<span class='header_name'>$HeaderName</span><br/>\n".$HEADER_REPORT."<br/>";
6264
if($TYPE_PROBLEMS =~ /'RetVal|'Obj/)
6266
my @Notations_Array = ();
6267
if($TYPE_PROBLEMS =~ /'RetVal/)
6269
@Notations_Array = (@Notations_Array, "<span style='color:#444444;padding-left:5px;'><b>RetVal</b></span> - function's return value");
6271
if($TYPE_PROBLEMS =~ /'Obj/)
6273
@Notations_Array = (@Notations_Array, "<span style='color:#444444;'><b>Obj</b></span> - method's object (C++)");
6275
$Notations = "Shorthand notations: ".join("; ", @Notations_Array).".<br/>\n";
6277
$TYPE_PROBLEMS = "<a name=\'Type_Problems_$TargetPriority\'></a>\n<h2 style='margin-bottom:0px;padding-bottom:0px;'>Problems in Data Types, $TargetPriority risk ($Problems_Number)</h2><hr/>\n".$Notations."<!--Type_Problems_".$TargetPriority."-->\n".$TYPE_PROBLEMS."<!--Type_Problems_".$TargetPriority."_End-->\n"."<input id=\'Type_Problems_$TargetPriority"."_Count"."\' type='hidden' value=\'$Problems_Number\' /><a style='font-size:11px;' href='#Top'>to the top</a><br/>\n";
6279
return $TYPE_PROBLEMS;
6282
my $ContentSpanStart_2 = "<span style='line-height:25px;' class=\"section_2\" onclick=\"javascript:showContent(this, 'CONTENT_ID')\">\n";
6284
sub getAffectedInterfaces($$)
6286
my ($Target_TypeName, $Kinds_Locations) = @_;
6287
my ($Affected_Interfaces_Header, $Affected_Interfaces, %FunctionNumber) = ();
6288
foreach my $Interface (sort {lc($tr_name{$a}) cmp lc($tr_name{$b})} keys(%CompatProblems))
6290
next if(($Interface =~ /C2/) or ($Interface =~ /D2/) or ($Interface =~ /D0/));
6291
next if(keys(%FunctionNumber)>1000);
6292
my $FunctionProblem = "";
6293
my $MinPath_Length = "";
6294
my $MaxPriority = 0;
6295
my $Location_Last = "";
6296
foreach my $Kind (keys(%{$CompatProblems{$Interface}}))
6298
foreach my $Location (keys(%{$CompatProblems{$Interface}{$Kind}}))
6300
next if(not $Kinds_Locations->{$Kind}{$Location});
6301
my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
6302
my $Signature = $CompatProblems{$Interface}{$Kind}{$Location}{"Signature"};
6303
my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
6304
my $Priority = $CompatProblems{$Interface}{$Kind}{$Location}{"Priority"};
6305
if($Type_Name eq $Target_TypeName)
6307
$FunctionNumber{$Interface} = 1;
6308
my $Path_Length = 0;
6309
while($Location =~ /\-\>/g){$Path_Length += 1;}
6310
if(($MinPath_Length eq "") or ($Path_Length<$MinPath_Length and $Priority_Value{$Priority}>$MaxPriority) or (($Location_Last =~ /RetVal/ or $Location_Last =~ /Obj/) and $Location !~ /RetVal|Obj/ and $Location !~ /\-\>/) or ($Location_Last =~ /RetVal|Obj/ and $Location_Last =~ /\-\>/ and $Location !~ /RetVal|Obj/ and $Location =~ /\-\>/))
6312
$MinPath_Length = $Path_Length;
6313
$MaxPriority = $Priority_Value{$Priority};
6314
$Location_Last = $Location;
6315
my $Description = get_AffectDescription($Interface, $Kind, $Location);
6316
$FunctionProblem = "<span class='interface_name_black' style='padding-left:20px;'>".highLight_Signature_PPos_Italic(htmlSpecChars($Signature), $Parameter_Position, 1, 0)."</span>:<br/>"."<span class='affect_description'>".addArrows($Description)."</span><br/><div style='height:4px;'> </div>\n";
6321
$Affected_Interfaces .= $FunctionProblem;
6323
$Affected_Interfaces .= "and other...<br/>" if(keys(%FunctionNumber)>5000);
6324
if($Affected_Interfaces)
6326
$Affected_Interfaces_Header = $ContentSpanStart_2."[+] affected interfaces (".keys(%FunctionNumber).")".$ContentSpanEnd;
6327
$Affected_Interfaces = $ContentDivStart.$Affected_Interfaces.$ContentDivEnd;
6329
return ($Affected_Interfaces_Header, $Affected_Interfaces);
6332
my %Kind_TypeStructureChanged=(
6334
"Added_Member_And_Size"=>1,
6335
"Added_Middle_Member_And_Size"=>1,
6337
"Withdrawn_Member_And_Size"=>1,
6338
"Withdrawn_Member"=>1,
6339
"Withdrawn_Middle_Member_And_Size"=>1,
6340
"Enum_Member_Value"=>1,
6341
"Enum_Member_Name"=>1,
6342
"Member_Type_And_Size"=>1,
6344
"Member_BaseType_And_Size"=>1,
6345
"Member_BaseType"=>1,
6346
"Member_PointerLevel"=>1,
6350
my %Kind_VirtualTableChanged=(
6351
"Added_Virtual_Function"=>1,
6352
"Withdrawn_Virtual_Function"=>1,
6353
"Virtual_Function_Position"=>1,
6354
"Virtual_Function_Redefinition"=>1,
6355
"Virtual_Function_Redefinition_B"=>1
6358
sub get_AffectDescription($$$)
6360
my ($Interface, $Kind, $Location) = @_;
6361
my $Target = $CompatProblems{$Interface}{$Kind}{$Location}{"Target"};
6362
my $Old_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"Old_Value"};
6363
my $New_Value = $CompatProblems{$Interface}{$Kind}{$Location}{"New_Value"};
6364
my $Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Type_Name"};
6365
my $Parameter_Position = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Position"};
6366
my $Parameter_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Name"};
6367
my $Parameter_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Parameter_Type_Name"};
6368
my $Member_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Member_Type_Name"};
6369
my $Object_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Object_Type_Name"};
6370
my $Return_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Return_Type_Name"};
6371
my $Start_Type_Name = $CompatProblems{$Interface}{$Kind}{$Location}{"Start_Type_Name"};
6372
my $InitialType_Type = $CompatProblems{$Interface}{$Kind}{$Location}{"InitialType_Type"};
6373
my $Parameter_Position_Str = num_to_str($Parameter_Position + 1);
6374
my @Sentence_Parts = ();
6375
my $Location_To_Type = $Location;
6376
$Location_To_Type =~ s/\-\>[^>]+?\Z//;
6377
if($Kind_VirtualTableChanged{$Kind})
6379
if($Kind eq "Virtual_Function_Redefinition")
6381
@Sentence_Parts = (@Sentence_Parts, "This method become virtual and will be called instead of redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."'.");
6383
elsif($Kind eq "Virtual_Function_Redefinition_B")
6385
@Sentence_Parts = (@Sentence_Parts, "This method become non-virtual and redefined method '".highLight_Signature(htmlSpecChars($Old_Value))."' will be called instead of it.");
6389
@Sentence_Parts = (@Sentence_Parts, "Call of this virtual method will result in crash of application because the layout of virtual table has been changed.");
6392
elsif($Kind_TypeStructureChanged{$Kind})
6394
if($Location_To_Type =~ /RetVal/)
6396
if($Location_To_Type =~ /\-\>/)
6398
@Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in return value");
6402
@Sentence_Parts = (@Sentence_Parts, "Return value");
6405
elsif($Location_To_Type =~ /Obj/)
6407
if($Location_To_Type =~ /\-\>/)
6409
@Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' in the object of this method");
6413
@Sentence_Parts = (@Sentence_Parts, "Object");
6418
if($Location_To_Type =~ /\-\>/)
6420
@Sentence_Parts = (@Sentence_Parts, "Member \'$Location_To_Type\' of $Parameter_Position_Str parameter");
6424
@Sentence_Parts = (@Sentence_Parts, "$Parameter_Position_Str parameter");
6428
@Sentence_Parts = (@Sentence_Parts, "\'$Parameter_Name\'");
6430
if($InitialType_Type eq "Pointer")
6432
@Sentence_Parts = (@Sentence_Parts, "(pointer)");
6435
if($Start_Type_Name eq $Type_Name)
6437
@Sentence_Parts = (@Sentence_Parts, "has type \'$Type_Name\'.");
6441
@Sentence_Parts = (@Sentence_Parts, "has base type \'$Type_Name\'.");
6444
return join(" ", @Sentence_Parts);
6447
sub create_HtmlReport()
6449
my $CssStyles = "<style type=\"text/css\">
6450
body{font-family:Arial;}
6451
hr{color:Black;background-color:Black;height:1px;border:0;}
6452
span.section{font-weight:bold;cursor:pointer;margin-left:7px;font-size:16px;font-family:Arial;color:#003E69;}
6453
span:hover.section{color:#336699;}
6454
span.section_2{cursor:pointer;margin-left:7px;font-size:14px;font-family:Arial;color:#cc3300;}
6455
span.extension{font-weight:100;font-size:16px;}
6456
span.problem_exact_location{color:Red;font-size:14px;}
6457
span.header_name{color:#cc3300;font-size:14px;font-family:Arial;font-weight:bold;}
6458
span.header_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
6459
span.solib_list_elem{padding-left:10px;color:#333333;font-size:15px;font-family:Arial;}
6460
span.solib_name{color:Green;font-size:14px;font-family:Arial;font-weight:bold;}
6461
span.interface_name{font-weight:bold;font-size:16px;font-family:Arial;color:#003E69;margin-left:7px;}
6462
span.interface_name_black{font-weight:bold;font-size:15px;font-family:Arial;color:#333333;}
6463
span.problem_title{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
6464
span.problem_sub_title{color:#333333;text-decoration:none;font-weight:bold;font-size:13px;font-family:Verdana;}
6465
span.problem_body{color:Black;font-size:14px;}
6466
span.int_p{font-weight:normal;}
6467
span.affect_description{padding-left:30px;font-size:14px;font-style:italic;line-height:13px;}
6468
table.problems_table{line-height:16px;margin-left:15px;margin-top:3px;border-collapse:collapse;}
6469
table.problems_table td{border-style:solid;border-color:Gray;border-width:1px;}
6470
td.table_header{background-color:#eeeeee;}
6471
td.summary_item{font-size:15px;font-family:Arial;text-align:left;}
6472
td.summary_item_value{padding-left:5px;padding-right:5px;width:35px;text-align:right;}
6473
span.problem_num{color:#333333;font-weight:bold;font-size:13px;font-family:Verdana;}
6474
span.mangled{padding-left:15px;font-size:13px;cursor:text;color:#444444;}
6475
span.symver{color:#555555;font-size:13px;white-space:nowrap;}
6476
span.color_param{font-style:italic;color:Brown;}
6477
span.focus_param{font-style:italic;color:Red;}</style>";
6479
my $JScripts = "<script type=\"text/javascript\" language=\"JavaScript\">
6480
function showContent(header, id) {
6481
e = document.getElementById(id);
6482
if(e.style.display == 'none')
6484
e.style.display = '';
6485
e.style.visibility = 'visible';
6486
header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[−]\");
6490
e.style.display = 'none';
6491
e.style.visibility = 'hidden';
6492
header.innerHTML = header.innerHTML.replace(/\\\[[^0-9 ]\\\]/gi,\"[+]\");
6496
writeFile("$REPORT_PATH/abi_compat_report.html", "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
6497
<title>ABI compliance report for the library $TargetLibraryName from version ".$Descriptor{1}{"Version"}." to ".$Descriptor{2}{"Version"}." on ".getArch()."\n</title>\n<!--Styles-->\n".$CssStyles."\n<!--Styles_End-->\n"."<!--JScripts-->\n".$JScripts."\n<!--JScripts_End-->\n</head>\n<body>\n<div><a name='Top'></a>\n".get_Report_Header()."<br/>\n".get_Summary()."<br/>\n".get_Report_Added().get_Report_Withdrawn().get_Report_TypeProblems("High").get_Report_TypeProblems("Medium").get_Report_TypeProblems("Low").get_Report_InterfaceProblems("High").get_Report_InterfaceProblems("Medium").get_Report_InterfaceProblems("Low").get_Report_ChangedConstants().get_SourceInfo()."</div>\n"."<br/><br/><br/><hr/><div style='width:100%;font-family:Arial;font-size:11px;' align='right'><i>Generated on ".(localtime time)." for <span style='font-weight:bold'>$TargetLibraryName</span> by <a href='http://ispras.linux-foundation.org/index.php/ABI_compliance_checker'>ABI-compliance-checker</a> $ABI_COMPLIANCE_CHECKER_VERSION </i></div>\n<div style='height:999px;'></div>\n</body></html>");
6502
if(int($_[0]) > int($_[1]))
6506
elsif($_[0] eq $_[1])
6519
#$Text =~ s/\-\>/→/g;
6520
$Text =~ s/\-\>/−>/g;
6527
while($Text =~ /CONTENT_ID/)
6529
if(int($Content_Counter)%2)
6533
$Text =~ s/CONTENT_ID/c_$ContentID/;
6535
$Content_Counter += 1;
6540
sub restrict_num_decimal_digits
6543
my $digs_to_cut=shift;
6545
if ($num=~/\d+\.(\d){$digs_to_cut,}/)
6547
$num=sprintf("%.".($digs_to_cut-1)."f", $num);
6552
sub parse_constants()
6555
foreach my $String (split("\n", $ConstantsSrc{$Version}))
6556
{#detecting public and private constants using sources
6557
if($String=~/#[ \t]+\d+[ \t]+\"(.+)\"/)
6561
if($String=~/\#[ \t]*define[ \t]+([_A-Z]+)[ \t]+(.*)[ \t]*\Z/)
6563
my ($Name, $Value) = ($1, $2);
6564
if(not $Constants{$Version}{$Name}{"Access"})
6566
$Constants{$Version}{$Name}{"Access"} = "public";
6567
$Constants{$Version}{$Name}{"Value"} = $Value;
6568
$Constants{$Version}{$Name}{"Header"} = get_FileName($CurHeader);
6571
elsif($String=~/\#[ \t]*undef[ \t]+([_A-Z]+)[ \t]*/)
6574
$Constants{$Version}{$Name}{"Access"} = "private";
6577
foreach my $Constant (keys(%{$Constants{$Version}}))
6579
if(($Constants{$Version}{$Constant}{"Access"} eq "private") or not $Constants{$Version}{$Constant}{"Value"}
6580
or $Constant=~/_h\Z/i)
6582
delete($Constants{$Version}{$Constant});
6586
delete($Constants{$Version}{$Constant}{"Access"});
6591
sub mergeConstants()
6593
return if(defined $AppPath);
6594
foreach my $Constant (keys(%{$Constants{1}}))
6596
my $Old_Value = $Constants{1}{$Constant}{"Value"};
6597
my $New_Value = $Constants{2}{$Constant}{"Value"};
6598
my $Header = $Constants{1}{$Constant}{"Header"};
6599
if($New_Value and $Old_Value and ($New_Value ne $Old_Value))
6601
%{$ConstantProblems{$Constant}} = (
6602
"Old_Value"=>$Old_Value,
6603
"New_Value"=>$New_Value,
6610
sub mergeHeaders_Separately()
6612
system("mkdir", "-p", "header_compile_errors/".$TargetLibraryName);
6613
system("rm", "-fr", $ERR_PATH{1}, $ERR_PATH{2});
6614
my ($Header_Num, $Prev_Header_Length) = (0, 0);
6615
my $All_Count = keys(%{$Headers{1}});
6616
foreach my $Header_Dest (sort {int($Headers{1}{$a}{"Position"})<=>int($Headers{1}{$b}{"Position"})} keys(%{$Headers{1}}))
6618
my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
6619
my $Dest_Count = keys(%{$HeaderName_Destinations{1}{$Header_Name}});
6620
my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
6621
my $Dest_Comment = ($Dest_Count>1 and $Identity=~/\//)?" ($Identity)":"";
6622
print get_one_step_title($Header_Name.$Dest_Comment, $Header_Num, $All_Count, $Prev_Header_Length, 1)."\r";
6626
%ClassVirtFunc = ();
6628
%CompleteSignature = ();
6631
parseHeader($Header_Dest);
6633
my $PairHeaderDest = find_pair_header($Header_Dest);
6634
if(not $PairHeaderDest)
6639
parseHeader($PairHeaderDest);
6643
$Prev_Header_Length = length($Header_Name.$Dest_Comment);
6645
print get_one_step_title("", $All_Count, $All_Count, $Prev_Header_Length, 0)."\n";
6648
sub get_one_step_title($$$$$)
6650
my ($Header_Name, $Num, $All_Count, $SpacesAtTheEnd, $ShowCurrent) = @_;
6651
my ($Spaces_1, $Spaces_2, $Title) = ();
6652
my $Title_1 = "checking headers: $Num/$All_Count [".restrict_num_decimal_digits($Num*100/$All_Count, 3)."%]".(($ShowCurrent)?",":"");
6653
foreach (0 .. length("checking headers: ")+length($All_Count)*2+11 - length($Title_1))
6657
$Title .= $Title_1.$Spaces_1;
6660
my $Title_2 = "current: $Header_Name";
6661
foreach (0 .. $SpacesAtTheEnd - length($Header_Name)-1)
6665
$Title .= $Title_2.$Spaces_2;
6669
foreach (0 .. $SpacesAtTheEnd + length(" current: ") - 1)
6677
sub find_pair_header($)
6679
my $Header_Dest = $_[0];
6680
my $Header_Name = $Headers{1}{$Header_Dest}{"Name"};
6681
my $Identity = $Headers{1}{$Header_Dest}{"Identity"};
6682
my @Pair_Dest = keys(%{$HeaderName_Destinations{2}{$Header_Name}});
6685
return $Pair_Dest[0];
6687
elsif($#Pair_Dest==-1)
6693
foreach my $Pair_Dest (@Pair_Dest)
6695
my $Pair_Identity = $Headers{2}{$Pair_Dest}{"Identity"};
6696
if($Identity eq $Pair_Identity)
6707
my $LibVersion = $_[0];
6708
my @SoLibPaths = getSoPaths($LibVersion);
6709
if($#SoLibPaths eq -1 and not $CheckHeadersOnly)
6711
print "ERROR: shared objects were not found\n";
6714
foreach my $SoLibPath (@SoLibPaths)
6716
getSymbols_Lib($LibVersion, $SoLibPath, 0);
6722
return ("", $_[0])if($_[0] !~ /\//);
6723
if($_[0] =~ /\A(.*\/)([^\/]*)\Z/)
6733
sub translateSymbols($)
6735
my $LibVersion = $_[0];
6736
my (@MnglNames, @UnMnglNames) = ();
6737
foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
6739
if($Interface =~ /\A_Z/)
6741
$Interface =~ s/[\@]+(.*)\Z//;
6742
push(@MnglNames, $Interface);
6746
$tr_name{$Interface} = $Interface;
6747
$mangled_name{$tr_name{$Interface}} = $Interface;
6750
if($#MnglNames > -1)
6752
@UnMnglNames = reverse(unmangleArray(@MnglNames));
6753
foreach my $Interface (sort keys(%{$Interface_Library{$LibVersion}}))
6755
if($Interface =~ /\A_Z/)
6757
$Interface =~ s/[\@]+(.*)\Z//;
6758
$tr_name{$Interface} = pop(@UnMnglNames);
6759
$mangled_name{correctName($tr_name{$Interface})} = $Interface;
6768
foreach my $Interface (keys(%{$Interface_Library{2}}))
6770
if(not $Interface_Library{1}{$Interface})
6772
$AddedInt{$Interface} = 1;
6773
my ($MnglName, $SymbolVersion) = ($Interface, "");
6774
if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
6776
($MnglName, $SymbolVersion) = ($1, $2);
6778
$FuncAttr{2}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
6783
sub detectWithdrawn()
6785
#detecting withdrawn
6786
foreach my $Interface (keys(%{$Interface_Library{1}}))
6788
if(not $Interface_Library{2}{$Interface} and not $Interface_Library{2}{$SymVer{2}{$Interface}})
6790
next if($DepInterfaces{2}{$Interface});
6791
$WithdrawnInt{$Interface} = 1;
6792
my ($MnglName, $SymbolVersion) = ($Interface, "");
6793
if($Interface =~ /\A(.+)[\@]+(.+)\Z/)
6795
($MnglName, $SymbolVersion) = ($1, $2);
6797
$FuncAttr{1}{$Interface}{"Signature"} = $tr_name{$MnglName}.(($SymbolVersion)?"\@".$SymbolVersion:"");
6804
my $LibName = $_[0];
6805
foreach my $LibNameInStack (@RecurLib)
6807
if($LibName eq $LibNameInStack)
6815
sub getSymbols_App($)
6818
return () if(not $Path or not -f $Path);
6820
open(APP, "readelf -WhlSsdA $Path |");
6821
my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
6825
#do nothing with symtab (but there are some plans for the future)
6831
elsif( /'.symtab'/ ) {
6834
elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
6835
if( $Ndx eq "UND" ) {
6836
#only exported interfaces
6837
push(@Ints, $fullname);
6847
if($_[0]=~/\s*\d+:\s+(\w*)\s+\w+\s+(\w+)\s+(\w+)\s+(\w+)\s+(\w+)\s((\w|@|\.)+)/)
6848
{#the line of 'readelf' output corresponding to the interface
6849
my ($value, $type, $bind, $vis, $Ndx, $fullname)=($1, $2, $3, $4, $5, $6);
6850
if(($bind ne "WEAK") and ($bind ne "GLOBAL")) {
6853
if(($type ne "FUNC") and ($type ne "OBJECT") and ($type ne "COMMON")) {
6856
if($vis ne "DEFAULT") {
6859
if(($Ndx eq "ABS") and ($value !~ /\D|1|2|3|4|5|6|7|8|9/)) {
6862
return ($fullname, $value, $Ndx);
6870
sub getSymbols_Lib($$$)
6872
my ($LibVersion, $Lib_Path, $IsNeededLib) = @_;
6873
return if(not $Lib_Path or not -f $Lib_Path);
6874
my ($Lib_Dir, $Lib_SoName) = separatePath($Lib_Path);
6875
return if($CheckedSoLib{$LibVersion}{$Lib_SoName} and $IsNeededLib);
6876
return if(isRecurLib($Lib_SoName) or $#RecurLib>=1);
6877
$CheckedSoLib{$LibVersion}{$Lib_SoName} = 1;
6878
push(@RecurLib, $Lib_SoName);
6879
my (%Value_Interface, %Interface_Value, %NeededLib) = ();
6880
if(not $IsNeededLib)
6882
$SoNames_All{$LibVersion}{$Lib_SoName} = 1;
6884
open(SOLIB, "readelf -WhlSsdA $Lib_Path |");
6885
my $symtab=0;#indicates that we are processing 'symtab' section of 'readelf' output
6889
#do nothing with symtab (but there are some plans for the future)
6895
elsif(/'.symtab'/) {
6898
elsif(/NEEDED.+\[([^\[\]]+)\]/)
6902
elsif(my ($fullname, $idx, $Ndx) = readlile_ELF($_)) {
6903
if( $Ndx eq "UND" ) {
6904
#ignore interfaces that are exported form somewhere else
6907
my ($realname, $version) = ($fullname, "");
6908
if($fullname =~ /\A([^@]+)[\@]+([^@]+)\Z/)
6910
($realname, $version) = ($1, $2);
6912
next if(defined $InterfacesListPath and not $InterfacesList{$realname});
6913
next if(defined $AppPath and not $InterfacesList_App{$realname});
6916
$DepInterfaces{$LibVersion}{$fullname} = 1;
6918
if(not $IsNeededLib or (defined $InterfacesListPath and $InterfacesList{$realname}) or (defined $AppPath and $InterfacesList_App{$realname}))
6920
$Interface_Library{$LibVersion}{$fullname} = $Lib_SoName;
6921
$Library_Interface{$LibVersion}{$Lib_SoName}{$fullname} = 1;
6922
$Interface_Value{$LibVersion}{$fullname} = $idx;
6923
$Value_Interface{$LibVersion}{$idx}{$fullname} = 1;
6924
if(not $Language{$LibVersion}{$Lib_SoName})
6926
if($fullname =~ /\A_Z[A-Z]*[0-9]+/)
6928
$Language{$LibVersion}{$Lib_SoName} = "C++";
6935
if(not $IsNeededLib)
6937
foreach my $Interface_Name (keys(%{$Interface_Library{$LibVersion}}))
6939
next if($Interface_Name !~ /\@/);
6940
my $Interface_SymName = "";
6941
foreach my $InterfaceName_SameValue (keys(%{$Value_Interface{$LibVersion}{$Interface_Value{$LibVersion}{$Interface_Name}}}))
6943
if($InterfaceName_SameValue ne $Interface_Name)
6945
$SymVer{$LibVersion}{$InterfaceName_SameValue} = $Interface_Name;
6946
$Interface_SymName = $InterfaceName_SameValue;
6950
if(not $Interface_SymName)
6952
if($Interface_Name =~ /\A([^@]*)[\@]+([^@]*)\Z/ and not $SymVer{$LibVersion}{$1})
6954
$SymVer{$LibVersion}{$1} = $Interface_Name;
6959
foreach my $SoLib (keys(%NeededLib))
6961
getSymbols_Lib($LibVersion, find_solib_path($Lib_Dir, $SoLib), 1);
6966
sub find_solib_path($$)
6968
my ($Dir, $SoName) = @_;
6970
if(-f $Dir."/".$SoName)
6972
return $Dir."/".$SoName;
6976
return $SoLib_DefaultPath{$SoName};
6980
sub symbols_Preparation($)
6981
{#recreate %SoNames and %Language using info from *.abi file
6982
my $LibVersion = $_[0];
6983
foreach my $Lib_SoName (keys(%{$Library_Interface{$LibVersion}}))
6985
foreach my $Interface_Name (keys(%{$Library_Interface{$LibVersion}{$Lib_SoName}}))
6987
$Interface_Library{$LibVersion}{$Interface_Name} = $Lib_SoName;
6988
$SoNames_All{$LibVersion}{$Lib_SoName} = 1;
6989
if(not $Language{$LibVersion}{$Lib_SoName})
6991
if($Interface_Name =~ /\A_Z[A-Z]*[0-9]+/)
6993
$Language{$LibVersion}{$Lib_SoName} = "C++";
7002
my $LibVersion = $_[0];
7004
foreach my $Dest (split("\n", $Descriptor{$LibVersion}{"Libs"}))
7006
$Dest =~ s/\A\s+|\s+\Z//g;
7010
print "ERROR: can't access \'$Dest\'\n";
7012
my @SoPaths_Dest = getSOPaths_Dest($Dest);
7013
foreach (@SoPaths_Dest)
7021
sub getSOPaths_Dest($)
7028
my @AllObjects = cmd_find($Dest,"f","*\.so*");
7030
foreach my $SharedObject (@AllObjects)
7032
if(cmd_file($SharedObject) =~ /shared object/)
7034
@SOPaths = (@SOPaths, $SharedObject);
7040
sub genDescriptorTemplate()
7042
writeFile("library-descriptor.xml", $Descriptor_Template."\n");
7043
print "descriptor template named 'library-descriptor.xml' has been generated in the current directory\n";
7046
sub detectPointerSize()
7049
writeFile("temp/get_pointer_size.c", "#include <stdio.h>
7052
printf(\"\%d\", sizeof(int*));
7055
system("gcc temp/get_pointer_size.c -o temp/get_pointer_size");
7056
$POINTER_SIZE = `./temp/get_pointer_size`;
7060
sub data_Preparation($)
7062
my $LibVersion = $_[0];
7063
if($Descriptor{$LibVersion}{"Path"} =~ /\.abi\.tar\.gz/)
7065
my $FileName = cmd_tar($Descriptor{$LibVersion}{"Path"});
7066
if($FileName =~ /\.abi/)
7069
my $LibraryABI = eval readFile($FileName);
7070
system("rm", "-f", $FileName);
7071
$TypeDescr{$LibVersion} = $LibraryABI->{"TypeDescr"};
7072
$FuncDescr{$LibVersion} = $LibraryABI->{"FuncDescr"};
7073
$Library_Interface{$LibVersion} = $LibraryABI->{"Interfaces"};
7074
$SymVer{$LibVersion} = $LibraryABI->{"SymVer"};
7075
$Tid_TDid{$LibVersion} = $LibraryABI->{"Tid_TDid"};
7076
$Descriptor{$LibVersion}{"Version"} = $LibraryABI->{"LibraryVersion"};
7077
$OpaqueTypes{$LibVersion} = $LibraryABI->{"OpaqueTypes"};
7078
$InternalInterfaces{$LibVersion} = $LibraryABI->{"InternalInterfaces"};
7079
$Headers{$LibVersion} = $LibraryABI->{"Headers"};
7080
$SoNames_All{$LibVersion} = $LibraryABI->{"SharedObjects"};
7081
$Constants{$LibVersion} = $LibraryABI->{"Constants"};
7082
if($LibraryABI->{"ABI_COMPLIANCE_CHECKER_VERSION"} ne $ABI_COMPLIANCE_CHECKER_VERSION)
7084
print "ERROR: incompatible version of specified ABI dump (allowed only $ABI_COMPLIANCE_CHECKER_VERSION)\n";
7087
foreach my $Destination (keys(%{$Headers{$LibVersion}}))
7089
my $Header = get_FileName($Destination);
7090
$HeaderName_Destinations{$LibVersion}{$Header}{$Destination} = 1;
7092
symbols_Preparation($LibVersion);
7095
elsif($Descriptor{$LibVersion}{"Path"} =~ /\.tar\.gz\Z/)
7097
print "ERROR: descriptor must be an XML file or '*.abi.tar.gz' ABI dump\n";
7102
readDescriptor($LibVersion);
7103
if(not $CheckHeadersOnly)
7105
getSymbols($LibVersion);
7107
headerSearch($LibVersion);
7114
if((keys(%{$hash}))[0] =~ /\A[0-9]+\Z/)
7116
return [sort {int($a) <=> int($b)} keys %{$hash}];
7120
return [sort {$a cmp $b} keys %{$hash}];
7124
sub get_solib_default_paths()
7126
foreach my $Line (split("\n", `ldconfig -p`))
7128
if($Line=~/\A[ \t]*([^ \t]+) .* \=\> (.+)\Z/)
7130
$SoLib_DefaultPath{$1} = $2;
7142
if(defined $ShowVersion)
7144
print "ABI Compliance Checker $ABI_COMPLIANCE_CHECKER_VERSION\nCopyright (C) The Linux Foundation\nCopyright (C) Institute for System Programming, RAS\nLicense GPLv2: GNU GPL version 2 <http://www.gnu.org/licenses/>\nThis program is free software: you can redistribute it and/or modify it.\n\nWritten by Andrey Ponomarenko.\n";
7147
$Data::Dumper::Sortkeys = \&dump_sorting;
7148
if(defined $TestSystem)
7154
if($GenerateDescriptor)
7156
genDescriptorTemplate();
7159
if(not defined $TargetLibraryName)
7161
print "select library name (option -l <name>)\n";
7164
if(defined $InterfacesListPath)
7166
if(not -f $InterfacesListPath)
7168
print "ERROR: can't access file $InterfacesListPath\n";
7171
foreach my $Interface (split("\n", readFile($InterfacesListPath)))
7173
$InterfacesList{$Interface} = 1;
7180
foreach my $Interface (getSymbols_App($AppPath))
7182
$InterfacesList_App{$Interface} = 1;
7187
print "ERROR: can't access file \'$AppPath\'\n";
7191
get_solib_default_paths();
7192
if($DumpInfo_DescriptorPath)
7194
if(not -f $DumpInfo_DescriptorPath)
7196
print "ERROR: can't access file \'$DumpInfo_DescriptorPath\'\n";
7199
$Descriptor{1}{"Path"} = $DumpInfo_DescriptorPath;
7201
detectPointerSize();
7203
translateSymbols(1);
7205
parseHeaders_AllInOne(1);
7207
my %LibraryABI = ();
7208
print "creating library ABI info dump ...\n";
7209
$LibraryABI{"TypeDescr"} = $TypeDescr{1};
7210
$LibraryABI{"FuncDescr"} = $FuncDescr{1};
7211
$LibraryABI{"Interfaces"} = $Library_Interface{1};
7212
$LibraryABI{"SymVer"} = $SymVer{1};
7213
$LibraryABI{"LibraryVersion"} = $Descriptor{1}{"Version"};
7214
$LibraryABI{"Library"} = $TargetLibraryName;
7215
$LibraryABI{"SharedObjects"} = $SoNames_All{1};
7216
$LibraryABI{"Tid_TDid"} = $Tid_TDid{1};
7217
$LibraryABI{"OpaqueTypes"} = $OpaqueTypes{1};
7218
$LibraryABI{"InternalInterfaces"} = $InternalInterfaces{1};
7219
$LibraryABI{"Headers"} = $Headers{1};
7220
$LibraryABI{"Constants"} = $Constants{1};
7221
$LibraryABI{"ABI_COMPLIANCE_CHECKER_VERSION"} = $ABI_COMPLIANCE_CHECKER_VERSION;
7222
my $InfoDump_FilePath = "abi_dumps/$TargetLibraryName";
7223
my $InfoDump_FileName = $TargetLibraryName."_".$Descriptor{1}{"Version"}.".abi";
7224
system("mkdir", "-p", $InfoDump_FilePath);
7225
system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName.".tar.gz");
7226
writeFile("$InfoDump_FilePath/$InfoDump_FileName", Dumper(\%LibraryABI));
7227
system("cd ".esc($InfoDump_FilePath)." && tar -cf ".esc($InfoDump_FileName).".tar ".esc($InfoDump_FileName));
7228
system("cd ".esc($InfoDump_FilePath)." && gzip ".esc($InfoDump_FileName).".tar --best");
7229
system("rm", "-f", $InfoDump_FilePath."/".$InfoDump_FileName);
7232
print "ERROR: can't create library ABI info dump\n";
7237
print "see library ABI info dump in \'$InfoDump_FilePath/$InfoDump_FileName\.tar\.gz\': use it instead of library version descriptor on other machine\n";
7241
if(not $Descriptor{1}{"Path"})
7243
print "select 1st library descriptor (option -d1 <path>)\n";
7246
if(not -f $Descriptor{1}{"Path"})
7248
print "ERROR: descriptor d1 does not exist, incorrect file path '".$Descriptor{1}{"Path"}."'\n";
7251
if(not $Descriptor{2}{"Path"})
7253
print "select 2nd library descriptor (option -d2 <path>)\n";
7256
if(not -f $Descriptor{2}{"Path"})
7258
print "ERROR: descriptor d2 does not exist, incorrect file path '".$Descriptor{2}{"Path"}."'\n";
7261
$StartTime = localtime time;
7262
print "preparation...\n";
7263
data_Preparation(1);
7264
data_Preparation(2);
7265
if($AppPath and not keys(%{$Interface_Library{1}}))
7267
print "WARNING: symbols from the specified application were not found in the specified library shared objects\n";
7269
$REPORT_PATH = "compat_reports/$TargetLibraryName/".$Descriptor{1}{"Version"}."_to_".$Descriptor{2}{"Version"};
7270
system("mkdir", "-p", $REPORT_PATH);
7271
system("rm", "-f", $REPORT_PATH."/abi_compat_report.html");
7272
detectPointerSize();
7273
translateSymbols(1);
7274
translateSymbols(2);
7275
if(not $CheckHeadersOnly)
7281
if($HeaderCheckingMode_Separately and $Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/ and $Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
7283
mergeHeaders_Separately();
7287
if($Descriptor{1}{"Path"} !~ /\.abi\.tar\.gz/)
7289
parseHeaders_AllInOne(1);
7291
if($Descriptor{2}{"Path"} !~ /\.abi\.tar\.gz/)
7293
parseHeaders_AllInOne(2);
7295
print "comparing headers ...\n";
7300
if(not $CheckHeadersOnly)
7302
print "comparing shared objects ...\n";
7305
print "creating ABI compliance report ...\n";
7306
create_HtmlReport();
7307
if($HeaderCheckingMode_Separately)
7309
if(keys(%HeaderCompileError))
7311
print "\nWARNING: compilation errors in following headers:\n";
7312
foreach my $Header (keys(%HeaderCompileError))
7316
print "\nyou can see compilation errors in the following files:\n '$ERR_PATH{1}'\n '$ERR_PATH{2}'\n";
7320
print "\nstarted: $StartTime, finished: ".(localtime time)."\n" if($ShowExpendTime);
7321
print "see the ABI compliance report in the file '$REPORT_PATH/abi_compat_report.html'\n";