scan-build/ccc-analyzer: start analyzing C++ FTW.

llvm-svn: 91398
This commit is contained in:
Ted Kremenek 2009-12-15 02:35:54 +00:00
parent 4ea24f19f5
commit f65a0c6768
2 changed files with 67 additions and 30 deletions

View File

@ -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.

View File

@ -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;