forked from OSchip/llvm-project
scan-build/ccc-analyzer: start analyzing C++ FTW.
llvm-svn: 91398
This commit is contained in:
parent
4ea24f19f5
commit
f65a0c6768
|
@ -14,14 +14,38 @@
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
use FindBin;
|
||||||
use Cwd qw/ getcwd abs_path /;
|
use Cwd qw/ getcwd abs_path /;
|
||||||
use File::Temp qw/ tempfile /;
|
use File::Temp qw/ tempfile /;
|
||||||
use File::Path qw / mkpath /;
|
use File::Path qw / mkpath /;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
use Text::ParseWords;
|
use Text::ParseWords;
|
||||||
|
|
||||||
my $CC = $ENV{'CCC_CC'};
|
##===----------------------------------------------------------------------===##
|
||||||
if (!defined $CC) { $CC = "gcc"; }
|
# Compiler command setup.
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
|
my $Compiler;
|
||||||
|
my $Clang;
|
||||||
|
|
||||||
|
if ($FindBin::Script =~ /c\+\+-analyzer/) {
|
||||||
|
$Compiler = $ENV{'CCC_CXX'};
|
||||||
|
if (!defined $Compiler) { $Compiler = "g++"; }
|
||||||
|
|
||||||
|
$Clang = $ENV{'CLANG_CXX'};
|
||||||
|
if (!defined $Clang) { $Clang = 'clang++'; }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$Compiler = $ENV{'CCC_CC'};
|
||||||
|
if (!defined $Compiler) { $Compiler = "gcc"; }
|
||||||
|
|
||||||
|
$Clang = $ENV{'CLANG'};
|
||||||
|
if (!defined $Clang) { $Clang = 'clang'; }
|
||||||
|
}
|
||||||
|
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
# Cleanup.
|
||||||
|
##===----------------------------------------------------------------------===##
|
||||||
|
|
||||||
my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
|
my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
|
||||||
if (!defined $ReportFailures) { $ReportFailures = 1; }
|
if (!defined $ReportFailures) { $ReportFailures = 1; }
|
||||||
|
@ -79,7 +103,7 @@ sub ProcessClangFailure {
|
||||||
print OUT "@$Args\n";
|
print OUT "@$Args\n";
|
||||||
close OUT;
|
close OUT;
|
||||||
`uname -a >> $PPFile.info.txt 2>&1`;
|
`uname -a >> $PPFile.info.txt 2>&1`;
|
||||||
`$CC -v >> $PPFile.info.txt 2>&1`;
|
`$Compiler -v >> $PPFile.info.txt 2>&1`;
|
||||||
system 'mv',$ofile,"$PPFile.stderr.txt";
|
system 'mv',$ofile,"$PPFile.stderr.txt";
|
||||||
return (basename $PPFile);
|
return (basename $PPFile);
|
||||||
}
|
}
|
||||||
|
@ -88,10 +112,6 @@ sub ProcessClangFailure {
|
||||||
# Running the analyzer.
|
# Running the analyzer.
|
||||||
##----------------------------------------------------------------------------##
|
##----------------------------------------------------------------------------##
|
||||||
|
|
||||||
# Determine what clang executable to use.
|
|
||||||
my $Clang = $ENV{'CLANG'};
|
|
||||||
if (!defined $Clang) { $Clang = 'clang'; }
|
|
||||||
|
|
||||||
sub GetCCArgs {
|
sub GetCCArgs {
|
||||||
my $Args = shift;
|
my $Args = shift;
|
||||||
|
|
||||||
|
@ -134,9 +154,6 @@ sub Analyze {
|
||||||
|
|
||||||
$Args = GetCCArgs($Args);
|
$Args = GetCCArgs($Args);
|
||||||
|
|
||||||
# Skip anything related to C++.
|
|
||||||
return if ($Lang =~ /c[+][+]/);
|
|
||||||
|
|
||||||
my $RunAnalyzer = 0;
|
my $RunAnalyzer = 0;
|
||||||
my $Cmd;
|
my $Cmd;
|
||||||
my @CmdArgs;
|
my @CmdArgs;
|
||||||
|
@ -361,7 +378,9 @@ my %UniqueOptions = (
|
||||||
|
|
||||||
my %LangsAccepted = (
|
my %LangsAccepted = (
|
||||||
"objective-c" => 1,
|
"objective-c" => 1,
|
||||||
"c" => 1
|
"c" => 1,
|
||||||
|
"c++" => 1,
|
||||||
|
"objective-c++" => 1
|
||||||
);
|
);
|
||||||
|
|
||||||
##----------------------------------------------------------------------------##
|
##----------------------------------------------------------------------------##
|
||||||
|
@ -377,7 +396,7 @@ my $Output;
|
||||||
my %Uniqued;
|
my %Uniqued;
|
||||||
|
|
||||||
# Forward arguments to gcc.
|
# Forward arguments to gcc.
|
||||||
my $Status = system($CC,@ARGV);
|
my $Status = system($Compiler,@ARGV);
|
||||||
if ($Status) { exit($Status >> 8); }
|
if ($Status) { exit($Status >> 8); }
|
||||||
|
|
||||||
# Get the analysis options.
|
# Get the analysis options.
|
||||||
|
|
|
@ -26,7 +26,6 @@ my $Verbose = 0; # Verbose output from this script.
|
||||||
my $Prog = "scan-build";
|
my $Prog = "scan-build";
|
||||||
my $BuildName;
|
my $BuildName;
|
||||||
my $BuildDate;
|
my $BuildDate;
|
||||||
my $CXX; # Leave undefined initially.
|
|
||||||
|
|
||||||
my $TERM = $ENV{'TERM'};
|
my $TERM = $ENV{'TERM'};
|
||||||
my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
|
my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
|
||||||
|
@ -83,13 +82,17 @@ sub DieDiag {
|
||||||
|
|
||||||
# Find 'clang'
|
# Find 'clang'
|
||||||
my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
|
my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
|
||||||
|
my $ClangCXXSB;
|
||||||
if (!defined $ClangSB || ! -x $ClangSB) {
|
if (!defined $ClangSB || ! -x $ClangSB) {
|
||||||
$ClangSB = Cwd::realpath("$RealBin/clang");
|
$ClangSB = Cwd::realpath("$RealBin/clang");
|
||||||
|
if (defined $ClangSB) { $ClangCXXSB = $ClangSB . "++"; }
|
||||||
}
|
}
|
||||||
my $Clang = $ClangSB;
|
my $Clang = $ClangSB;
|
||||||
|
my $ClangCXX = $ClangCXXSB;
|
||||||
# Default to looking for 'clang' in the path.
|
# Default to looking for 'clang' in the path.
|
||||||
if (!defined $Clang || ! -x $Clang) {
|
if (!defined $Clang || ! -x $Clang) {
|
||||||
$Clang = "clang";
|
$Clang = "clang";
|
||||||
|
$ClangCXX = "clang++";
|
||||||
}
|
}
|
||||||
|
|
||||||
my %AvailableAnalyses;
|
my %AvailableAnalyses;
|
||||||
|
@ -799,12 +802,22 @@ sub RunBuildCommand {
|
||||||
$Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
|
$Cmd =~ /(.*\/?ccc-analyzer[^\/]*$)/) {
|
||||||
|
|
||||||
if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
|
if (!($Cmd =~ /ccc-analyzer/) and !defined $ENV{"CCC_CC"}) {
|
||||||
$ENV{"CCC_CC"} = $1;
|
$ENV{"CCC_CC"} = $1;
|
||||||
}
|
}
|
||||||
|
|
||||||
shift @$Args;
|
shift @$Args;
|
||||||
unshift @$Args, $CCAnalyzer;
|
unshift @$Args, $CCAnalyzer;
|
||||||
}
|
}
|
||||||
|
elsif ($Cmd =~ /(.*\/?g\+\+[^\/]*$)/ or
|
||||||
|
$Cmd =~ /(.*\/?c\+\+[^\/]*$)/ or
|
||||||
|
$Cmd =~ /(.*\/?llvm-g\+\+[^\/]*$)/ or
|
||||||
|
$Cmd =~ /(.*\/?c\+\+-analyzer[^\/]*$)/) {
|
||||||
|
if (!($Cmd =~ /c\+\+-analyzer/) and !defined $ENV{"CCC_CXX"}) {
|
||||||
|
$ENV{"CCC_CXX"} = $1;
|
||||||
|
}
|
||||||
|
shift @$Args;
|
||||||
|
unshift @$Args, $CCAnalyzer;
|
||||||
|
}
|
||||||
elsif ($IgnoreErrors) {
|
elsif ($IgnoreErrors) {
|
||||||
if ($Cmd eq "make" or $Cmd eq "gmake") {
|
if ($Cmd eq "make" or $Cmd eq "gmake") {
|
||||||
AddIfNotPresent($Args, "CC=$CCAnalyzer");
|
AddIfNotPresent($Args, "CC=$CCAnalyzer");
|
||||||
|
@ -825,6 +838,7 @@ sub RunBuildCommand {
|
||||||
if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
|
if ($Args->[$i] eq "-sdk" && $i + 1 < scalar(@$Args)) {
|
||||||
if (@$Args[$i+1] =~ /^iphonesimulator3/) {
|
if (@$Args[$i+1] =~ /^iphonesimulator3/) {
|
||||||
$ENV{"CCC_CC"} = "gcc-4.2";
|
$ENV{"CCC_CC"} = "gcc-4.2";
|
||||||
|
$ENV{"CCC_CXX"} = "g++-4.2";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -839,10 +853,10 @@ sub RunBuildCommand {
|
||||||
# When 'CC' is set, xcodebuild uses it to do all linking, even if we are
|
# When 'CC' is set, xcodebuild uses it to do all linking, even if we are
|
||||||
# linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
|
# linking C++ object files. Set 'LDPLUSPLUS' so that xcodebuild uses 'g++'
|
||||||
# when linking such files.
|
# when linking such files.
|
||||||
die if (!defined $CXX);
|
if (!defined $ENV{'CCC_CXX'}) {
|
||||||
my $LDPLUSPLUS = `which $CXX`;
|
$ENV{'CCC_CXX'} = 'g++';
|
||||||
$LDPLUSPLUS =~ s/\015?\012//; # strip newlines
|
}
|
||||||
$ENV{'LDPLUSPLUS'} = $LDPLUSPLUS;
|
$ENV{'LDPLUSPLUS'} = $ENV{'CCC_CXX'};
|
||||||
}
|
}
|
||||||
|
|
||||||
return (system(@$Args) >> 8);
|
return (system(@$Args) >> 8);
|
||||||
|
@ -1090,16 +1104,19 @@ while (@ARGV) {
|
||||||
|
|
||||||
if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
|
if ($arg =~ /^--use-c\+\+(=(.+))?$/) {
|
||||||
shift @ARGV;
|
shift @ARGV;
|
||||||
|
my $cxx;
|
||||||
|
|
||||||
if (!defined $2 || $2 eq "") {
|
if (!defined $2 || $2 eq "") {
|
||||||
if (!@ARGV) {
|
if (!@ARGV) {
|
||||||
DieDiag("'--use-c++' option requires a compiler executable name.\n");
|
DieDiag("'--use-c++' option requires a compiler executable name.\n");
|
||||||
}
|
}
|
||||||
$CXX = shift @ARGV;
|
$cxx = shift @ARGV;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$CXX = $2;
|
$cxx = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ENV{"CCC_CXX"} = $cxx;
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,27 +1188,28 @@ $HtmlDir = GetHTMLRunDir($HtmlDir);
|
||||||
# Set the appropriate environment variables.
|
# Set the appropriate environment variables.
|
||||||
SetHtmlEnv(\@ARGV, $HtmlDir);
|
SetHtmlEnv(\@ARGV, $HtmlDir);
|
||||||
|
|
||||||
my $Cmd = Cwd::realpath("$RealBin/libexec/ccc-analyzer");
|
my $AbsRealBin = Cwd::realpath($RealBin);
|
||||||
|
my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
|
||||||
|
my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";
|
||||||
|
|
||||||
if (!defined $Cmd || ! -x $Cmd) {
|
if (!defined $Cmd || ! -x $Cmd) {
|
||||||
$Cmd = Cwd::realpath("$RealBin/ccc-analyzer");
|
$Cmd = "$AbsRealBin/ccc-analyzer";
|
||||||
DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);
|
DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);
|
||||||
}
|
}
|
||||||
|
if (!defined $CmdCXX || ! -x $CmdCXX) {
|
||||||
|
$CmdCXX = "$AbsRealBin/c++-analyzer";
|
||||||
|
DieDiag("Executable 'c++-analyzer' does not exist at '$CmdCXX'\n") if(! -x $CmdCXX);
|
||||||
|
}
|
||||||
|
|
||||||
if (!defined $ClangSB || ! -x $ClangSB) {
|
if (!defined $ClangSB || ! -x $ClangSB) {
|
||||||
Diag("'clang' executable not found in '$RealBin/bin'.\n");
|
Diag("'clang' executable not found in '$RealBin/bin'.\n");
|
||||||
Diag("Using 'clang' from path.\n");
|
Diag("Using 'clang' from path.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined $CXX) {
|
|
||||||
$ENV{'CXX'} = $CXX;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$CXX = 'g++'; # This variable is used by other parts of scan-build
|
|
||||||
# that need to know a default C++ compiler to fall back to.
|
|
||||||
}
|
|
||||||
|
|
||||||
$ENV{'CC'} = $Cmd;
|
$ENV{'CC'} = $Cmd;
|
||||||
|
$ENV{'CXX'} = $CmdCXX;
|
||||||
$ENV{'CLANG'} = $Clang;
|
$ENV{'CLANG'} = $Clang;
|
||||||
|
$ENV{'CLANG_CXX'} = $ClangCXX;
|
||||||
|
|
||||||
if ($Verbose >= 2) {
|
if ($Verbose >= 2) {
|
||||||
$ENV{'CCC_ANALYZER_VERBOSE'} = 1;
|
$ENV{'CCC_ANALYZER_VERBOSE'} = 1;
|
||||||
|
|
Loading…
Reference in New Issue