From owner-svn-ports-head@freebsd.org Tue Jan 12 18:57:43 2016 Return-Path: Delivered-To: svn-ports-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 04E2AA80DF0; Tue, 12 Jan 2016 18:57:43 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 963711D01; Tue, 12 Jan 2016 18:57:42 +0000 (UTC) (envelope-from brooks@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u0CIvf5M024482; Tue, 12 Jan 2016 18:57:41 GMT (envelope-from brooks@FreeBSD.org) Received: (from brooks@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u0CIvfrs024478; Tue, 12 Jan 2016 18:57:41 GMT (envelope-from brooks@FreeBSD.org) Message-Id: <201601121857.u0CIvfrs024478@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: brooks set sender to brooks@FreeBSD.org using -f From: Brooks Davis Date: Tue, 12 Jan 2016 18:57:41 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r405902 - in head/devel/llvm37: . files X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the ports tree for head List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 12 Jan 2016 18:57:43 -0000 Author: brooks Date: Tue Jan 12 18:57:41 2016 New Revision: 405902 URL: https://svnweb.freebsd.org/changeset/ports/405902 Log: Upgrade to 3.7.1 release. Bring in the clang static analyzer install bits from clang trunk. Added: head/devel/llvm37/files/clang-patch-static-analizer.diff (contents, props changed) Modified: head/devel/llvm37/Makefile head/devel/llvm37/distinfo head/devel/llvm37/pkg-plist Modified: head/devel/llvm37/Makefile ============================================================================== --- head/devel/llvm37/Makefile Tue Jan 12 18:22:26 2016 (r405901) +++ head/devel/llvm37/Makefile Tue Jan 12 18:57:41 2016 (r405902) @@ -1,8 +1,7 @@ # $FreeBSD$ PORTNAME= llvm -DISTVERSION= 3.7.0 -PORTREVISION= 6 +DISTVERSION= 3.7.1 CATEGORIES= devel lang MASTER_SITES= http://llvm.org/${PRE_}releases/${LLVM_RELEASE}/${RCDIR} DISTNAME= ${PORTNAME}-${DISTVERSION}.src @@ -40,6 +39,7 @@ OPTIONS_SUB= yes CLANG_DESC= Build clang CLANG_EXTRA_PATCHES= \ ${PATCHDIR}/clang-patch-fformat_extensions.diff \ + ${PATCHDIR}/clang-patch-static-analizer.diff \ ${PATCHDIR}/clang-patch-tools_clang_lib_Headers_CMakeLists.txt \ ${PATCHDIR}/clang-patch-tools_clang_tools_clang-format_clang-format.py \ ${PATCHDIR}/clang-patch-svn-250416 @@ -144,8 +144,12 @@ COMMANDS+= clang \ clang-check \ clang-cpp \ clang-format \ - clang-tblgen -MAN1SRCS+= clang.1 + clang-tblgen \ + scan-build \ + scan-view +MAN1SRCS+= clang.1 \ + scan-build.1 +CLANG_PATTERN= (c-index-test|clang|scan-|Reporter.py|ScanView.py|scanview.css|sorttable.js|startfile.py|-analyzer) .endif .if ${PORT_OPTIONS:MEXTRAS} @@ -256,6 +260,21 @@ EXTRA_PATCHES+= \ post-extract-CLANG-on: ${MV} ${WRKSRC_clang} ${PATCH_WRKSRC}/tools/clang + ${MKDIR} ${PATCH_WRKSRC}/tools/clang/tools/scan-view/share + cd ${PATCH_WRKSRC}/tools/clang/tools/scan-view && \ + ${MV} Resources/bugcatcher.ico Resources/FileRadar.scpt \ + Resources/GetRadarVersion.scpt share + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/sorttable.js + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/scanview.css + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/set-xcode-analyzer + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/scan-build.1 + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/scan-build.* + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/ccc-analyzer.* + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-build/c++-analyzer.* + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-view/Reporter.py + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-view/ScanView.py + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-view/scan-view + ${RM} ${PATCH_WRKSRC}/tools/clang/tools/scan-view/startfile.py post-extract-EXTRAS-on: ${MV} ${WRKSRC_extras} ${PATCH_WRKSRC}/tools/clang/tools/extra @@ -359,7 +378,7 @@ build-plist: ${SED} -e 's|${STAGEDIR}${PYTHON_SITELIBDIR}|%%LIT%%%%PYTHON_SITELIBDIR%%|' | \ ${SORT} >> ${PLIST}.tmp awk '{ \ - if ($$0 ~ /clang/ && $$0 !~ /(omp.h|libclang_rt|sanitizer|blacklist.txt|${EXTRAS_PATTERN})/) {printf "%%%%CLANG%%%%"} \ + if ($$0 ~ /${CLANG_PATTERN}/ && $$0 !~ /(omp.h|libclang_rt|sanitizer|blacklist.txt|${EXTRAS_PATTERN})/) {printf "%%%%CLANG%%%%"} \ if ($$0 ~ /(sanitizer|blacklist.txt)/) {printf "%%%%COMPILER_RT%%%%"} \ if ($$0 ~ /(${EXTRAS_PATTERN})/) {printf "%%%%EXTRAS%%%%"} \ if ($$0 ~ /lld/ && $$0 !~ /lldb/) {printf "%%%%LLD%%%%"} \ Modified: head/devel/llvm37/distinfo ============================================================================== --- head/devel/llvm37/distinfo Tue Jan 12 18:22:26 2016 (r405901) +++ head/devel/llvm37/distinfo Tue Jan 12 18:57:41 2016 (r405902) @@ -1,14 +1,14 @@ -SHA256 (llvm-3.7.0.src.tar.xz) = ab45895f9dcdad1e140a3a79fd709f64b05ad7364e308c0e582c5b02e9cc3153 -SIZE (llvm-3.7.0.src.tar.xz) = 14636252 -SHA256 (cfe-3.7.0.src.tar.xz) = 4ed740c5a91df1c90a4118c5154851d6a475f39a91346bdf268c1c29c13aa1cc -SIZE (cfe-3.7.0.src.tar.xz) = 9147204 -SHA256 (clang-tools-extra-3.7.0.src.tar.xz) = 8ae8a0a3a96b7a700412d67df0af172cb2fc1326beec575fcc0f71d2e72709cd -SIZE (clang-tools-extra-3.7.0.src.tar.xz) = 276628 -SHA256 (compiler-rt-3.7.0.src.tar.xz) = 227fa998520bc94974a428dc8e7654d9bdf277e5bc70d4064ebc05691bd62b0b -SIZE (compiler-rt-3.7.0.src.tar.xz) = 1192832 -SHA256 (lld-3.7.0.src.tar.xz) = ddb658b789c501efbe4f54ff8ced2c07cd9ff686c92445d8a1ab2cd5dbd837ed -SIZE (lld-3.7.0.src.tar.xz) = 586440 -SHA256 (lldb-3.7.0.src.tar.xz) = f4d7505bc111044eaa4033af012221e492938405b62522b8e3e354c20c4b71e9 -SIZE (lldb-3.7.0.src.tar.xz) = 10649660 -SHA256 (openmp-3.7.0.src.tar.xz) = 8d8a224e5689596a35652fda87e4be29853c4b85fbc7a6562019badfad779f2a -SIZE (openmp-3.7.0.src.tar.xz) = 2251108 +SHA256 (llvm-3.7.1.src.tar.xz) = be7794ed0cec42d6c682ca8e3517535b54555a3defabec83554dbc74db545ad5 +SIZE (llvm-3.7.1.src.tar.xz) = 14592544 +SHA256 (cfe-3.7.1.src.tar.xz) = 56e2164c7c2a1772d5ed2a3e57485ff73ff06c97dff12edbeea1acc4412b0674 +SIZE (cfe-3.7.1.src.tar.xz) = 9110616 +SHA256 (compiler-rt-3.7.1.src.tar.xz) = 9d4769e4a927d3824bcb7a9c82b01e307c68588e6de4e7f04ab82d82c5af8181 +SIZE (compiler-rt-3.7.1.src.tar.xz) = 1181772 +SHA256 (clang-tools-extra-3.7.1.src.tar.xz) = 4a91edaccad1ce984c7c49a4a87db186b7f7b21267b2b03bcf4bd7820715bc6b +SIZE (clang-tools-extra-3.7.1.src.tar.xz) = 277476 +SHA256 (lld-3.7.1.src.tar.xz) = a929cb44b45e3181a0ad02d8c9df1d3fc71e001139455c6805f3abf2835ef3ac +SIZE (lld-3.7.1.src.tar.xz) = 586008 +SHA256 (lldb-3.7.1.src.tar.xz) = 9a0bc315ef55f44c98cdf92d064df0847f453ed156dd0ef6a87e04f5fd6a0e01 +SIZE (lldb-3.7.1.src.tar.xz) = 10650524 +SHA256 (openmp-3.7.1.src.tar.xz) = 9a702e20c247014f6de8c45b738c6ea586eca0559304520f565ac9a7cba4bf9a +SIZE (openmp-3.7.1.src.tar.xz) = 2026988 Added: head/devel/llvm37/files/clang-patch-static-analizer.diff ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/devel/llvm37/files/clang-patch-static-analizer.diff Tue Jan 12 18:57:41 2016 (r405902) @@ -0,0 +1,5332 @@ +diff --git tools/clang/tools/CMakeLists.txt tools/clang/tools/CMakeLists.txt.orig +index 891bf84..dba676a 100644 +--- tools/clang/tools/CMakeLists.txt.orig ++++ tools/clang/tools/CMakeLists.txt +@@ -5,6 +5,8 @@ add_clang_subdirectory(driver) + add_subdirectory(clang-format) + add_subdirectory(clang-format-vs) + add_subdirectory(clang-fuzzer) ++add_subdirectory(scan-build) ++add_subdirectory(scan-view) + + add_subdirectory(c-index-test) + add_subdirectory(libclang) +diff --git tools/clang/tools/scan-build/CMakeLists.txt tools/clang/tools/scan-build/CMakeLists.txt.orig +new file mode 100644 +index 0000000..78c243d +--- /dev/null ++++ tools/clang/tools/scan-build/CMakeLists.txt +@@ -0,0 +1,82 @@ ++option(CLANG_INSTALL_SCANBUILD "Install the scan-build tool" ON) ++ ++include(GNUInstallDirs) ++ ++if (WIN32 AND NOT CYGWIN) ++ set(BinFiles ++ scan-build.bat) ++ set(LibexecFiles ++ ccc-analyzer.bat ++ c++-analyzer.bat) ++else() ++ set(BinFiles ++ scan-build) ++ set(LibexecFiles ++ ccc-analyzer ++ c++-analyzer) ++ if (APPLE) ++ list(APPEND BinFiles ++ set-xcode-analyzer) ++ endif() ++endif() ++ ++set(ManPages ++ scan-build.1) ++ ++set(ShareFiles ++ scanview.css ++ sorttable.js) ++ ++ ++if(CLANG_INSTALL_SCANBUILD) ++ foreach(BinFile ${BinFiles}) ++ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/bin/${BinFile} ++ COMMAND ${CMAKE_COMMAND} -E make_directory ++ ${CMAKE_BINARY_DIR}/bin ++ COMMAND ${CMAKE_COMMAND} -E copy ++ ${CMAKE_CURRENT_SOURCE_DIR}/bin/${BinFile} ++ ${CMAKE_BINARY_DIR}/bin/ ++ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bin/${BinFile}) ++ list(APPEND Depends ${CMAKE_BINARY_DIR}/bin/${BinFile}) ++ install(PROGRAMS bin/${BinFile} DESTINATION bin) ++ endforeach() ++ ++ foreach(LibexecFile ${LibexecFiles}) ++ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/libexec/${LibexecFile} ++ COMMAND ${CMAKE_COMMAND} -E make_directory ++ ${CMAKE_BINARY_DIR}/libexec ++ COMMAND ${CMAKE_COMMAND} -E copy ++ ${CMAKE_CURRENT_SOURCE_DIR}/libexec/${LibexecFile} ++ ${CMAKE_BINARY_DIR}/libexec/ ++ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/libexec/${LibexecFile}) ++ list(APPEND Depends ${CMAKE_BINARY_DIR}/libexec/${LibexecFile}) ++ install(PROGRAMS libexec/${LibexecFile} DESTINATION libexec) ++ endforeach() ++ ++ foreach(ManPage ${ManPages}) ++ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_MANDIR}/man1/${ManPage} ++ COMMAND ${CMAKE_COMMAND} -E make_directory ++ ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_MANDIR}/man1 ++ COMMAND ${CMAKE_COMMAND} -E copy ++ ${CMAKE_CURRENT_SOURCE_DIR}/man/${ManPage} ++ ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_MANDIR}/man1/ ++ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/man/${ManPage}) ++ list(APPEND Depends ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_MANDIR}/man1/${ManPage}) ++ install(PROGRAMS man/${ManPage} DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) ++ endforeach() ++ ++ foreach(ShareFile ${ShareFiles}) ++ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/share/scan-build/${ShareFile} ++ COMMAND ${CMAKE_COMMAND} -E make_directory ++ ${CMAKE_BINARY_DIR}/share/scan-build ++ COMMAND ${CMAKE_COMMAND} -E copy ++ ${CMAKE_CURRENT_SOURCE_DIR}/share/scan-build/${ShareFile} ++ ${CMAKE_BINARY_DIR}/share/scan-build/ ++ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/share/scan-build/${ShareFile}) ++ list(APPEND Depends ${CMAKE_BINARY_DIR}/share/scan-build/${ShareFile}) ++ install(FILES share/scan-build/${ShareFile} DESTINATION share/scan-build) ++ endforeach() ++ ++ add_custom_target(scan-build ALL DEPENDS ${Depends}) ++ set_target_properties(scan-build PROPERTIES FOLDER "Misc") ++endif() +diff --git tools/clang/tools/scan-build/Makefile tools/clang/tools/scan-build/Makefile.orig +new file mode 100644 +index 0000000..23aa198 +--- /dev/null ++++ tools/clang/tools/scan-build/Makefile +@@ -0,0 +1,53 @@ ++##===- tools/scan-build/Makefile ---------------------------*- Makefile -*-===## ++# ++# The LLVM Compiler Infrastructure ++# ++# This file is distributed under the University of Illinois Open Source ++# License. See LICENSE.TXT for details. ++# ++##===----------------------------------------------------------------------===## ++ ++CLANG_LEVEL := ../.. ++ ++include $(CLANG_LEVEL)/../../Makefile.config ++include $(CLANG_LEVEL)/Makefile ++ ++ifeq ($(HOST_OS),MingW) ++ Suffix := .bat ++endif ++ ++CLANG_INSTALL_SCANBUILD ?= 1 ++ ++ifeq ($(CLANG_INSTALL_SCANBUILD), 1) ++ InstallTargets := $(ToolDir)/scan-build$(Suffix) \ ++ $(LibexecDir)/c++-analyzer$(Suffix) \ ++ $(LibexecDir)/ccc-analyzer$(Suffix) \ ++ $(ShareDir)/scan-build/scanview.css \ ++ $(ShareDir)/scan-build/sorttable.js \ ++ $(ShareDir)/man/man1/scan-build.1 ++ ++ ifeq ($(HOST_OS),Darwin) ++ InstallTargets := $(InstallTargets) $(ToolDir)/set-xcode-analyzer ++ endif ++endif ++ ++all:: $(InstallTargets) ++ ++$(ToolDir)/%: bin/% Makefile $(ToolDir)/.dir ++ $(Echo) "Copying $(notdir $<) to the 'bin' directory..." ++ $(Verb)cp $< $@ ++ $(Verb)chmod +x $@ ++ ++$(LibexecDir)/%: libexec/% Makefile $(LibexecDir)/.dir ++ $(Echo) "Copying $(notdir $<) to the 'libexec' directory..." ++ $(Verb)cp $< $@ ++ $(Verb)chmod +x $@ ++ ++$(ShareDir)/man/man1/%: man/% Makefile $(ShareDir)/man/man1/.dir ++ $(Echo) "Copying $(notdir $<) to the 'man' directory..." ++ $(Verb)cp $< $@ ++ ++$(ShareDir)/scan-build/%: share/scan-build/% Makefile $(ShareDir)/scan-build/.dir ++ $(Echo) "Copying $(notdir $<) to the 'share' directory..." ++ $(Verb)cp $< $@ ++ +diff --git tools/clang/tools/scan-build/bin/scan-build tools/clang/tools/scan-build/bin/scan-build.orig +new file mode 100755 +index 0000000..6a14484 +--- /dev/null ++++ tools/clang/tools/scan-build/bin/scan-build +@@ -0,0 +1,1832 @@ ++#!/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 File::Find; ++use File::Copy qw(copy); ++use File::Path qw( rmtree mkpath ); ++use Term::ANSIColor; ++use Term::ANSIColor qw(:constants); ++use Cwd qw/ getcwd abs_path /; ++use Sys::Hostname; ++use Hash::Util qw(lock_keys); ++ ++my $Prog = "scan-build"; ++my $BuildName; ++my $BuildDate; ++ ++my $TERM = $ENV{'TERM'}; ++my $UseColor = (defined $TERM and $TERM =~ 'xterm-.*color' and -t STDOUT ++ and defined $ENV{'SCAN_BUILD_COLOR'}); ++ ++# Portability: getpwuid is not implemented for Win32 (see Perl language ++# reference, perlport), use getlogin instead. ++my $UserName = HtmlEscape(getlogin() || getpwuid($<) || 'unknown'); ++my $HostName = HtmlEscape(hostname() || 'unknown'); ++my $CurrentDir = HtmlEscape(getcwd()); ++ ++my $CmdArgs; ++ ++my $Date = localtime(); ++ ++# Command-line/config arguments. ++my %Options = ( ++ Verbose => 0, # Verbose output from this script. ++ AnalyzeHeaders => 0, ++ OutputDir => undef, # Parent directory to store HTML files. ++ HtmlTitle => basename($CurrentDir)." - scan-build results", ++ IgnoreErrors => 0, # Ignore build errors. ++ ViewResults => 0, # View results when the build terminates. ++ ExitStatusFoundBugs => 0, # Exit status reflects whether bugs were found ++ KeepEmpty => 0, # Don't remove output directory even with 0 results. ++ EnableCheckers => {}, ++ DisableCheckers => {}, ++ UseCC => undef, # C compiler to use for compilation. ++ UseCXX => undef, # C++ compiler to use for compilation. ++ AnalyzerTarget => undef, ++ StoreModel => undef, ++ ConstraintsModel => undef, ++ InternalStats => undef, ++ OutputFormat => "html", ++ ConfigOptions => [], # Options to pass through to the analyzer's -analyzer-config flag. ++ ReportFailures => undef, ++ AnalyzerStats => 0, ++ MaxLoop => 0, ++ PluginsToLoad => [], ++ AnalyzerDiscoveryMethod => undef, ++ OverrideCompiler => 0 # The flag corresponding to the --override-compiler command line option. ++); ++lock_keys(%Options); ++ ++##----------------------------------------------------------------------------## ++# Diagnostics ++##----------------------------------------------------------------------------## ++ ++sub Diag { ++ if ($UseColor) { ++ print BOLD, MAGENTA "$Prog: @_"; ++ print RESET; ++ } ++ else { ++ print "$Prog: @_"; ++ } ++} ++ ++sub ErrorDiag { ++ if ($UseColor) { ++ print STDERR BOLD, RED "$Prog: "; ++ print STDERR RESET, RED @_; ++ print STDERR RESET; ++ } else { ++ print STDERR "$Prog: @_"; ++ } ++} ++ ++sub DiagCrashes { ++ my $Dir = shift; ++ Diag ("The analyzer encountered problems on some source files.\n"); ++ Diag ("Preprocessed versions of these sources were deposited in '$Dir/failures'.\n"); ++ Diag ("Please consider submitting a bug report using these files:\n"); ++ Diag (" http://clang-analyzer.llvm.org/filing_bugs.html\n") ++} ++ ++sub DieDiag { ++ if ($UseColor) { ++ print STDERR BOLD, RED "$Prog: "; ++ print STDERR RESET, RED @_; ++ print STDERR RESET; ++ } ++ else { ++ print STDERR "$Prog: ", @_; ++ } ++ exit 1; ++} ++ ++##----------------------------------------------------------------------------## ++# Print default checker names ++##----------------------------------------------------------------------------## ++ ++if (grep /^--help-checkers$/, @ARGV) { ++ my @options = qx($0 -h); ++ foreach (@options) { ++ next unless /^ \+/; ++ s/^\s*//; ++ my ($sign, $name, @text) = split ' ', $_; ++ print $name, $/ if $sign eq '+'; ++ } ++ exit 0; ++} ++ ++##----------------------------------------------------------------------------## ++# Declaration of Clang options. Populated later. ++##----------------------------------------------------------------------------## ++ ++my $Clang; ++my $ClangSB; ++my $ClangCXX; ++my $ClangVersion; ++ ++##----------------------------------------------------------------------------## ++# GetHTMLRunDir - Construct an HTML directory name for the current sub-run. ++##----------------------------------------------------------------------------## ++ ++sub GetHTMLRunDir { ++ die "Not enough arguments." if (@_ == 0); ++ my $Dir = shift @_; ++ my $TmpMode = 0; ++ if (!defined $Dir) { ++ $Dir = $ENV{'TMPDIR'} || $ENV{'TEMP'} || $ENV{'TMP'} || "/tmp"; ++ $TmpMode = 1; ++ } ++ ++ # Chop off any trailing '/' characters. ++ while ($Dir =~ /\/$/) { chop $Dir; } ++ ++ # Get current date and time. ++ my @CurrentTime = localtime(); ++ my $year = $CurrentTime[5] + 1900; ++ my $day = $CurrentTime[3]; ++ my $month = $CurrentTime[4] + 1; ++ my $hour = $CurrentTime[2]; ++ my $min = $CurrentTime[1]; ++ my $sec = $CurrentTime[0]; ++ ++ my $TimeString = sprintf("%02d%02d%02d", $hour, $min, $sec); ++ my $DateString = sprintf("%d-%02d-%02d-%s-$$", ++ $year, $month, $day, $TimeString); ++ ++ # Determine the run number. ++ my $RunNumber; ++ ++ if (-d $Dir) { ++ if (! -r $Dir) { ++ DieDiag("directory '$Dir' exists but is not readable.\n"); ++ } ++ # Iterate over all files in the specified directory. ++ my $max = 0; ++ opendir(DIR, $Dir); ++ my @FILES = grep { -d "$Dir/$_" } readdir(DIR); ++ closedir(DIR); ++ ++ foreach my $f (@FILES) { ++ # Strip the prefix '$Prog-' if we are dumping files to /tmp. ++ if ($TmpMode) { ++ next if (!($f =~ /^$Prog-(.+)/)); ++ $f = $1; ++ } ++ ++ my @x = split/-/, $f; ++ next if (scalar(@x) != 4); ++ next if ($x[0] != $year); ++ next if ($x[1] != $month); ++ next if ($x[2] != $day); ++ next if ($x[3] != $TimeString); ++ next if ($x[4] != $$); ++ ++ if ($x[5] > $max) { ++ $max = $x[5]; ++ } ++ } ++ ++ $RunNumber = $max + 1; ++ } ++ else { ++ ++ if (-x $Dir) { ++ DieDiag("'$Dir' exists but is not a directory.\n"); ++ } ++ ++ if ($TmpMode) { ++ DieDiag("The directory '/tmp' does not exist or cannot be accessed.\n"); ++ } ++ ++ # $Dir does not exist. It will be automatically created by the ++ # clang driver. Set the run number to 1. ++ ++ $RunNumber = 1; ++ } ++ ++ die "RunNumber must be defined!" if (!defined $RunNumber); ++ ++ # Append the run number. ++ my $NewDir; ++ if ($TmpMode) { ++ $NewDir = "$Dir/$Prog-$DateString-$RunNumber"; ++ } ++ else { ++ $NewDir = "$Dir/$DateString-$RunNumber"; ++ } ++ ++ # Make sure that the directory does not exist in order to avoid hijack. ++ if (-e $NewDir) { ++ DieDiag("The directory '$NewDir' already exists.\n"); ++ } ++ ++ mkpath($NewDir); ++ return $NewDir; ++} ++ ++sub SetHtmlEnv { ++ ++ die "Wrong number of arguments." if (scalar(@_) != 2); ++ ++ my $Args = shift; ++ my $Dir = shift; ++ ++ die "No build command." if (scalar(@$Args) == 0); ++ ++ my $Cmd = $$Args[0]; ++ ++ if ($Cmd =~ /configure/ || $Cmd =~ /autogen/) { ++ return; ++ } ++ ++ if ($Options{Verbose}) { ++ Diag("Emitting reports for this run to '$Dir'.\n"); ++ } ++ ++ $ENV{'CCC_ANALYZER_HTML'} = $Dir; ++} ++ ++##----------------------------------------------------------------------------## ++# ComputeDigest - Compute a digest of the specified file. ++##----------------------------------------------------------------------------## ++ ++sub ComputeDigest { ++ my $FName = shift; ++ DieDiag("Cannot read $FName to compute Digest.\n") if (! -r $FName); ++ ++ # Use Digest::MD5. We don't have to be cryptographically secure. We're ++ # just looking for duplicate files that come from a non-malicious source. ++ # We use Digest::MD5 because it is a standard Perl module that should ++ # come bundled on most systems. ++ open(FILE, $FName) or DieDiag("Cannot open $FName when computing Digest.\n"); ++ binmode FILE; ++ my $Result = Digest::MD5->new->addfile(*FILE)->hexdigest; ++ close(FILE); ++ ++ # Return the digest. ++ return $Result; ++} ++ ++##----------------------------------------------------------------------------## ++# UpdatePrefix - Compute the common prefix of files. ++##----------------------------------------------------------------------------## ++ ++my $Prefix; ++ ++sub UpdatePrefix { ++ my $x = shift; ++ my $y = basename($x); ++ $x =~ s/\Q$y\E$//; ++ ++ if (!defined $Prefix) { ++ $Prefix = $x; ++ return; ++ } ++ ++ chop $Prefix while (!($x =~ /^\Q$Prefix/)); ++} ++ ++sub GetPrefix { ++ return $Prefix; ++} ++ ++##----------------------------------------------------------------------------## ++# UpdateInFilePath - Update the path in the report file. ++##----------------------------------------------------------------------------## ++ ++sub UpdateInFilePath { ++ my $fname = shift; ++ my $regex = shift; ++ my $newtext = shift; ++ ++ open (RIN, $fname) or die "cannot open $fname"; ++ open (ROUT, ">", "$fname.tmp") or die "cannot open $fname.tmp"; ++ ++ while () { ++ s/$regex/$newtext/; ++ print ROUT $_; ++ } ++ ++ close (ROUT); ++ close (RIN); ++ rename("$fname.tmp", $fname) ++} ++ ++##----------------------------------------------------------------------------## ++# AddStatLine - Decode and insert a statistics line into the database. ++##----------------------------------------------------------------------------## ++ ++sub AddStatLine { ++ my $Line = shift; ++ my $Stats = shift; ++ my $File = shift; ++ ++ print $Line . "\n"; ++ ++ my $Regex = qr/(.*?)\ ->\ Total\ CFGBlocks:\ (\d+)\ \|\ Unreachable ++ \ CFGBlocks:\ (\d+)\ \|\ Exhausted\ Block:\ (yes|no)\ \|\ Empty\ WorkList: ++ \ (yes|no)/x; ++ ++ if ($Line !~ $Regex) { ++ return; ++ } ++ ++ # Create a hash of the interesting fields ++ my $Row = { ++ Filename => $File, ++ Function => $1, ++ Total => $2, ++ Unreachable => $3, ++ Aborted => $4, ++ Empty => $5 ++ }; ++ ++ # Add them to the stats array ++ push @$Stats, $Row; ++} ++ ++##----------------------------------------------------------------------------## ++# ScanFile - Scan a report file for various identifying attributes. ++##----------------------------------------------------------------------------## ++ ++# Sometimes a source file is scanned more than once, and thus produces ++# multiple error reports. We use a cache to solve this problem. ++ ++my %AlreadyScanned; ++ ++sub ScanFile { ++ ++ my $Index = shift; ++ my $Dir = shift; ++ my $FName = shift; ++ my $Stats = shift; ++ ++ # Compute a digest for the report file. Determine if we have already ++ # scanned a file that looks just like it. ++ ++ my $digest = ComputeDigest("$Dir/$FName"); ++ ++ if (defined $AlreadyScanned{$digest}) { ++ # Redundant file. Remove it. ++ unlink("$Dir/$FName"); ++ return; ++ } ++ ++ $AlreadyScanned{$digest} = 1; ++ ++ # At this point the report file is not world readable. Make it happen. ++ chmod(0644, "$Dir/$FName"); ++ ++ # Scan the report file for tags. ++ open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); ++ ++ my $BugType = ""; ++ my $BugFile = ""; ++ my $BugFunction = ""; ++ my $BugCategory = ""; ++ my $BugDescription = ""; ++ my $BugPathLength = 1; ++ my $BugLine = 0; ++ ++ while () { ++ last if (//); ++ ++ if (/$/) { ++ $BugType = $1; ++ } ++ elsif (/$/) { ++ $BugFile = abs_path($1); ++ if (!defined $BugFile) { ++ # The file no longer exists: use the original path. ++ $BugFile = $1; ++ } ++ UpdatePrefix($BugFile); ++ } ++ elsif (/$/) { ++ $BugPathLength = $1; ++ } ++ elsif (/$/) { ++ $BugLine = $1; ++ } ++ elsif (/$/) { ++ $BugCategory = $1; ++ } ++ elsif (/$/) { ++ $BugDescription = $1; ++ } ++ elsif (/$/) { ++ $BugFunction = $1; ++ } ++ ++ } ++ ++ ++ close(IN); ++ ++ if (!defined $BugCategory) { ++ $BugCategory = "Other"; ++ } ++ ++ # Don't add internal statistics to the bug reports ++ if ($BugCategory =~ /statistics/i) { ++ AddStatLine($BugDescription, $Stats, $BugFile); ++ return; ++ } ++ ++ push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugFunction, $BugLine, ++ $BugPathLength ]; ++} ++ ++##----------------------------------------------------------------------------## ++# CopyFiles - Copy resource files to target directory. ++##----------------------------------------------------------------------------## ++ ++sub CopyFiles { ++ ++ my $Dir = shift; ++ ++ my $JS = Cwd::realpath("$RealBin/../share/scan-build/sorttable.js"); ++ ++ DieDiag("Cannot find 'sorttable.js'.\n") ++ if (! -r $JS); ++ ++ copy($JS, "$Dir"); ++ ++ DieDiag("Could not copy 'sorttable.js' to '$Dir'.\n") ++ if (! -r "$Dir/sorttable.js"); ++ ++ my $CSS = Cwd::realpath("$RealBin/../share/scan-build/scanview.css"); ++ ++ DieDiag("Cannot find 'scanview.css'.\n") ++ if (! -r $CSS); ++ ++ copy($CSS, "$Dir"); ++ ++ DieDiag("Could not copy 'scanview.css' to '$Dir'.\n") ++ if (! -r $CSS); ++} ++ ++##----------------------------------------------------------------------------## ++# CalcStats - Calculates visitation statistics and returns the string. ++##----------------------------------------------------------------------------## ++ ++sub CalcStats { ++ my $Stats = shift; ++ ++ my $TotalBlocks = 0; ++ my $UnreachedBlocks = 0; ++ my $TotalFunctions = scalar(@$Stats); ++ my $BlockAborted = 0; ++ my $WorkListAborted = 0; ++ my $Aborted = 0; ++ ++ # Calculate the unique files ++ my $FilesHash = {}; ++ ++ foreach my $Row (@$Stats) { ++ $FilesHash->{$Row->{Filename}} = 1; ++ $TotalBlocks += $Row->{Total}; ++ $UnreachedBlocks += $Row->{Unreachable}; ++ $BlockAborted++ if $Row->{Aborted} eq 'yes'; ++ $WorkListAborted++ if $Row->{Empty} eq 'no'; ++ $Aborted++ if $Row->{Aborted} eq 'yes' || $Row->{Empty} eq 'no'; ++ } ++ ++ my $TotalFiles = scalar(keys(%$FilesHash)); ++ ++ # Calculations ++ my $PercentAborted = sprintf("%.2f", $Aborted / $TotalFunctions * 100); ++ my $PercentBlockAborted = sprintf("%.2f", $BlockAborted / $TotalFunctions ++ * 100); ++ my $PercentWorkListAborted = sprintf("%.2f", $WorkListAborted / ++ $TotalFunctions * 100); ++ my $PercentBlocksUnreached = sprintf("%.2f", $UnreachedBlocks / $TotalBlocks ++ * 100); ++ ++ my $StatsString = "Analyzed $TotalBlocks blocks in $TotalFunctions functions" ++ . " in $TotalFiles files\n" ++ . "$Aborted functions aborted early ($PercentAborted%)\n" ++ . "$BlockAborted had aborted blocks ($PercentBlockAborted%)\n" ++ . "$WorkListAborted had unfinished worklists ($PercentWorkListAborted%)\n" ++ . "$UnreachedBlocks blocks were never reached ($PercentBlocksUnreached%)\n"; ++ ++ return $StatsString; ++} ++ ++##----------------------------------------------------------------------------## ++# Postprocess - Postprocess the results of an analysis scan. ++##----------------------------------------------------------------------------## ++ ++my @filesFound; ++my $baseDir; ++sub FileWanted { ++ my $baseDirRegEx = quotemeta $baseDir; ++ my $file = $File::Find::name; ++ ++ # The name of the file is generated by clang binary (HTMLDiagnostics.cpp) ++ if ($file =~ /report-.*\.html$/) { ++ my $relative_file = $file; ++ $relative_file =~ s/$baseDirRegEx//g; ++ push @filesFound, $relative_file; ++ } ++} ++ ++sub Postprocess { ++ ++ my $Dir = shift; ++ my $BaseDir = shift; ++ my $AnalyzerStats = shift; ++ my $KeepEmpty = shift; ++ ++ die "No directory specified." if (!defined $Dir); ++ ++ if (! -d $Dir) { ++ Diag("No bugs found.\n"); ++ return 0; ++ } ++ ++ $baseDir = $Dir . "/"; ++ find({ wanted => \&FileWanted, follow => 0}, $Dir); ++ ++ if (scalar(@filesFound) == 0 and ! -e "$Dir/failures") { ++ if (! $KeepEmpty) { ++ Diag("Removing directory '$Dir' because it contains no reports.\n"); ++ rmtree($Dir) or die "Cannot rmtree '$Dir' : $!"; ++ } ++ Diag("No bugs found.\n"); ++ return 0; ++ } ++ ++ # Scan each report file and build an index. ++ my @Index; ++ my @Stats; ++ foreach my $file (@filesFound) { ScanFile(\@Index, $Dir, $file, \@Stats); } ++ ++ # Scan the failures directory and use the information in the .info files ++ # to update the common prefix directory. ++ my @failures; ++ my @attributes_ignored; ++ if (-d "$Dir/failures") { ++ opendir(DIR, "$Dir/failures"); ++ @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR); ++ closedir(DIR); ++ opendir(DIR, "$Dir/failures"); ++ @attributes_ignored = grep { /^attribute_ignored/; } readdir(DIR); ++ closedir(DIR); ++ foreach my $file (@failures) { ++ open IN, "$Dir/failures/$file" or DieDiag("cannot open $file\n"); ++ my $Path = ; ++ if (defined $Path) { UpdatePrefix($Path); } ++ close IN; ++ } ++ } ++ ++ # Generate an index.html file. ++ my $FName = "$Dir/index.html"; ++ open(OUT, ">", $FName) or DieDiag("Cannot create file '$FName'\n"); ++ ++ # Print out the header. ++ ++print OUT < ++ ++${Options{HtmlTitle}} ++ ++ ++ ++ ++ ++ ++

${Options{HtmlTitle}}

++ ++ ++ ++ ++ ++ ++ ++ENDTEXT ++ ++print OUT "\n" ++ if (defined($BuildName) && defined($BuildDate)); ++ ++print OUT < ++ENDTEXT ++ ++ if (scalar(@filesFound)) { ++ # Print out the summary table. ++ my %Totals; ++ ++ for my $row ( @Index ) { ++ my $bug_type = ($row->[2]); ++ my $bug_category = ($row->[1]); ++ my $key = "$bug_category:$bug_type"; ++ ++ if (!defined $Totals{$key}) { $Totals{$key} = [1,$bug_category,$bug_type]; } ++ else { $Totals{$key}->[0]++; } ++ } ++ ++ print OUT "

Bug Summary

"; ++ ++ if (defined $BuildName) { ++ print OUT "\n

Results in this analysis run are based on analyzer build $BuildName.

\n" ++ } ++ ++ my $TotalBugs = scalar(@Index); ++print OUT < ++
++ ++ENDTEXT ++ ++ my $last_category; ++ ++ for my $key ( ++ sort { ++ my $x = $Totals{$a}; ++ my $y = $Totals{$b}; ++ my $res = $x->[1] cmp $y->[1]; ++ $res = $x->[2] cmp $y->[2] if ($res == 0); ++ $res ++ } keys %Totals ) ++ { ++ my $val = $Totals{$key}; ++ my $category = $val->[1]; ++ if (!defined $last_category or $last_category ne $category) { ++ $last_category = $category; ++ print OUT "\n"; ++ } ++ my $x = lc $key; ++ $x =~ s/[ ,'":\/()]+/_/g; ++ print OUT "\n"; ++ } ++ ++ # Print out the table of errors. *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
User:${UserName}\@${HostName}
Working Directory:${CurrentDir}
Command Line:${CmdArgs}
Clang Version:${ClangVersion}
Date:${Date}
Version:${BuildName} (${BuildDate})
Bug TypeQuantityDisplay?
All Bugs$TotalBugs
$category
"; ++ print OUT $val->[2]; ++ print OUT ""; ++ print OUT $val->[0]; ++ print OUT "