#!/usr/bin/env perl
#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
#
# A script designed to wrap a build so that all calls to gcc are intercepted
# and piped to the static analyzer.
#
##===----------------------------------------------------------------------===##
use strict;
use warnings;
use FindBin qw($RealBin);
use Digest::MD5;
use File::Basename;
use Term::ANSIColor;
use Term::ANSIColor qw(:constants);
use Cwd qw/ getcwd abs_path /;
use Sys::Hostname;
my $Verbose = 0; # Verbose output from this script.
my $Prog = "scan-build";
my $BuildName;
my $BuildDate;
my $CXX; # Leave undefined initially.
my $TERM = $ENV{'TERM'};
my $UseColor = (defined $TERM and $TERM eq 'xterm-color' and -t STDOUT
and defined $ENV{'SCAN_BUILD_COLOR'});
my $UserName = HtmlEscape(getpwuid($<) || 'unknown');
my $HostName = HtmlEscape(hostname() || 'unknown');
my $CurrentDir = HtmlEscape(getcwd());
my $CurrentDirSuffix = basename($CurrentDir);
my $CmdArgs;
my $HtmlTitle;
my $Date = localtime();
##----------------------------------------------------------------------------##
# Diagnostics
##----------------------------------------------------------------------------##
sub Diag {
if ($UseColor) {
print BOLD, MAGENTA "$Prog: @_";
print RESET;
}
else {
print "$Prog: @_";
}
}
sub DiagCrashes {
my $Dir = shift;
Diag ("The analyzer crashed on some source files.\n");
Diag ("Preprocessed versions of crashed files were deposited in '$Dir/crashes'.\n");
Diag ("Please consider submitting a bug report using these files:\n");
Diag (" http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\n")
}
sub DieDiag {
if ($UseColor) {
print BOLD, RED "$Prog: ";
print RESET, RED @_;
print RESET;
}
else {
print "$Prog: ", @_;
}
exit(0);
}
##----------------------------------------------------------------------------##
# Some initial preprocessing of Clang options.
##----------------------------------------------------------------------------##
my $ClangSB = Cwd::realpath("$RealBin/clang");
my $Clang = $ClangSB;
if (! -x $ClangSB) {
$Clang = "clang";
}
my %AvailableAnalyses;
# Query clang for analysis options.
open(PIPE, "-|", $Clang, "--help") or
DieDiag("Cannot execute '$Clang'\n");
my $FoundAnalysis = 0;
while(<PIPE>) {
if ($FoundAnalysis == 0) {
if (/SCA Checks\/Analyses/) {
$FoundAnalysis = 1;
}
next;
}
if (/^\s\s\s\s([^\s]+)\s(.+)$/) {
next if ($1 =~ /-dump/ or $1 =~ /-view/
or $1 =~ /-checker-simple/ or $1 =~ /-warn-uninit/);
$AvailableAnalyses{$1} = $2;
next;
}
last;
}
close (PIPE);
my %AnalysesDefaultEnabled = (
'-warn-dead-stores' => 1,
'-checker-cfref' => 1,
'-warn-objc-methodsigs' => 1,
'-warn-objc-missing-dealloc' =>