blob: 5ea1fad9bc8532036f90d6f633f512ec7ec157e2 [file] [log] [blame]
Ted Kremenekf7ffd662008-07-19 06:11:04 +00001#!/usr/bin/env perl
Ted Kremenek5efdf842008-03-25 22:35:32 +00002#
3# The LLVM Compiler Infrastructure
4#
5# This file is distributed under the University of Illinois Open Source
6# License. See LICENSE.TXT for details.
7#
8##===----------------------------------------------------------------------===##
9#
Ted Kremenekf7ffd662008-07-19 06:11:04 +000010# A script designed to interpose between the build system and gcc. It invokes
11# both gcc and the static analyzer.
Ted Kremenek5efdf842008-03-25 22:35:32 +000012#
13##===----------------------------------------------------------------------===##
14
Ted Kremenekf7ffd662008-07-19 06:11:04 +000015use strict;
16use warnings;
Ted Kremenekf65a0c62009-12-15 02:35:54 +000017use FindBin;
Ted Kremenek23432d42008-09-21 19:56:14 +000018use Cwd qw/ getcwd abs_path /;
Ted Kremenek994c8e32008-08-08 20:46:42 +000019use File::Temp qw/ tempfile /;
20use File::Path qw / mkpath /;
Ted Kremenek13747162009-01-21 00:42:24 +000021use File::Basename;
Ted Kremenek25421bb2009-05-11 23:29:51 +000022use Text::ParseWords;
Ted Kremenek6aa1ad02008-08-25 20:44:31 +000023
Ted Kremenekf65a0c62009-12-15 02:35:54 +000024##===----------------------------------------------------------------------===##
Anton Yartsev84f90422015-07-01 22:35:29 +000025# List form 'system' with STDOUT and STDERR captured.
26##===----------------------------------------------------------------------===##
27
28sub silent_system {
29 my $HtmlDir = shift;
30 my $Command = shift;
31
32 # Save STDOUT and STDERR and redirect to a temporary file.
33 open OLDOUT, ">&", \*STDOUT;
34 open OLDERR, ">&", \*STDERR;
35 my ($TmpFH, $TmpFile) = tempfile("temp_buf_XXXXXX",
36 DIR => $HtmlDir,
37 UNLINK => 1);
38 open(STDOUT, ">$TmpFile");
39 open(STDERR, ">&", \*STDOUT);
40
41 # Invoke 'system', STDOUT and STDERR are output to a temporary file.
42 system $Command, @_;
43
44 # Restore STDOUT and STDERR.
45 open STDOUT, ">&", \*OLDOUT;
46 open STDERR, ">&", \*OLDERR;
47
48 return $TmpFH;
49}
50
51##===----------------------------------------------------------------------===##
Ted Kremenekf65a0c62009-12-15 02:35:54 +000052# Compiler command setup.
53##===----------------------------------------------------------------------===##
54
Sylvestre Ledru9e075292014-08-08 17:15:13 +000055# Search in the PATH if the compiler exists
56sub SearchInPath {
57 my $file = shift;
58 foreach my $dir (split (':', $ENV{PATH})) {
59 if (-x "$dir/$file") {
60 return 1;
61 }
62 }
63 return 0;
64}
65
Ted Kremenekf65a0c62009-12-15 02:35:54 +000066my $Compiler;
67my $Clang;
Anna Zaks1d391522012-01-06 01:54:05 +000068my $DefaultCCompiler;
69my $DefaultCXXCompiler;
Jordan Rosea63f2292014-01-07 21:39:51 +000070my $IsCXX;
Ted Kremenek0270a082015-08-08 17:58:47 +000071my $AnalyzerTarget;
Ted Kremenek67978552014-12-31 08:19:08 +000072
73# If on OSX, use xcrun to determine the SDK root.
Ted Kremenek398f46f2014-12-31 07:44:51 +000074my $UseXCRUN = 0;
Anna Zaks1d391522012-01-06 01:54:05 +000075
Sylvestre Ledru82e547e2014-02-18 17:21:45 +000076if (`uname -a` =~ m/Darwin/) {
Jordan Rose85ff8f22012-11-28 19:12:44 +000077 $DefaultCCompiler = 'clang';
78 $DefaultCXXCompiler = 'clang++';
Ted Kremenek67978552014-12-31 08:19:08 +000079 # Older versions of OSX do not have xcrun to
80 # query the SDK location.
Ted Kremenek398f46f2014-12-31 07:44:51 +000081 if (-x "/usr/bin/xcrun") {
82 $UseXCRUN = 1;
83 }
Anna Zaks1d391522012-01-06 01:54:05 +000084} else {
Jordan Rose85ff8f22012-11-28 19:12:44 +000085 $DefaultCCompiler = 'gcc';
86 $DefaultCXXCompiler = 'g++';
Anna Zaks1d391522012-01-06 01:54:05 +000087}
Ted Kremenekf65a0c62009-12-15 02:35:54 +000088
89if ($FindBin::Script =~ /c\+\+-analyzer/) {
90 $Compiler = $ENV{'CCC_CXX'};
Sylvestre Ledru9e075292014-08-08 17:15:13 +000091 if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCXXCompiler; }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +000092
Ted Kremenekf65a0c62009-12-15 02:35:54 +000093 $Clang = $ENV{'CLANG_CXX'};
Sylvestre Ledru3ea1dae2014-02-18 17:45:06 +000094 if (!defined $Clang || ! -x $Clang) { $Clang = 'clang++'; }
Jordan Rosea63f2292014-01-07 21:39:51 +000095
96 $IsCXX = 1
Ted Kremenekf65a0c62009-12-15 02:35:54 +000097}
98else {
99 $Compiler = $ENV{'CCC_CC'};
Sylvestre Ledru9e075292014-08-08 17:15:13 +0000100 if (!defined $Compiler || (! -x $Compiler && ! SearchInPath($Compiler))) { $Compiler = $DefaultCCompiler; }
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000101
102 $Clang = $ENV{'CLANG'};
Sylvestre Ledru3ea1dae2014-02-18 17:45:06 +0000103 if (!defined $Clang || ! -x $Clang) { $Clang = 'clang'; }
Jordan Rosea63f2292014-01-07 21:39:51 +0000104
105 $IsCXX = 0
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000106}
107
Ted Kremenek0270a082015-08-08 17:58:47 +0000108$AnalyzerTarget = $ENV{'CLANG_ANALYZER_TARGET'};
109
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000110##===----------------------------------------------------------------------===##
111# Cleanup.
112##===----------------------------------------------------------------------===##
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000113
114my $ReportFailures = $ENV{'CCC_REPORT_FAILURES'};
115if (!defined $ReportFailures) { $ReportFailures = 1; }
116
Ted Kremenek13747162009-01-21 00:42:24 +0000117my $CleanupFile;
118my $ResultFile;
119
120# Remove any stale files at exit.
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000121END {
Anna Zaks45ce1bf2011-09-09 18:43:53 +0000122 if (defined $ResultFile && -z $ResultFile) {
Sylvestre Ledrudf70a7b2014-05-23 16:10:00 +0000123 unlink($ResultFile);
Anna Zaks45ce1bf2011-09-09 18:43:53 +0000124 }
125 if (defined $CleanupFile) {
Sylvestre Ledrudf70a7b2014-05-23 16:10:00 +0000126 unlink($CleanupFile);
Ted Kremenek13747162009-01-21 00:42:24 +0000127 }
128}
129
Ted Kremenek994c8e32008-08-08 20:46:42 +0000130##----------------------------------------------------------------------------##
131# Process Clang Crashes.
132##----------------------------------------------------------------------------##
133
134sub GetPPExt {
135 my $Lang = shift;
Ted Kremenek22a8a4b2009-12-16 18:32:41 +0000136 if ($Lang =~ /objective-c\+\+/) { return ".mii" };
Ted Kremenek994c8e32008-08-08 20:46:42 +0000137 if ($Lang =~ /objective-c/) { return ".mi"; }
Ted Kremenekdca68162009-12-16 05:02:47 +0000138 if ($Lang =~ /c\+\+/) { return ".ii"; }
Ted Kremenek994c8e32008-08-08 20:46:42 +0000139 return ".i";
140}
141
Ted Kremenekce6b8652009-04-28 17:37:44 +0000142# Set this to 1 if we want to include 'parser rejects' files.
143my $IncludeParserRejects = 0;
Ted Kremenek725fb432009-01-27 01:19:08 +0000144my $ParserRejects = "Parser Rejects";
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000145my $AttributeIgnored = "Attribute Ignored";
Anna Zaks9fed0842011-11-07 22:38:10 +0000146my $OtherError = "Other Error";
Ted Kremenek725fb432009-01-27 01:19:08 +0000147
Ted Kremenek5abf5462008-08-18 18:38:29 +0000148sub ProcessClangFailure {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000149 my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000150 my $Dir = "$HtmlDir/failures";
Ted Kremenek994c8e32008-08-08 20:46:42 +0000151 mkpath $Dir;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000152
Ted Kremenek725fb432009-01-27 01:19:08 +0000153 my $prefix = "clang_crash";
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000154 if ($ErrorType eq $ParserRejects) {
155 $prefix = "clang_parser_rejects";
156 }
157 elsif ($ErrorType eq $AttributeIgnored) {
158 $prefix = "clang_attribute_ignored";
159 }
Anna Zaks9fed0842011-11-07 22:38:10 +0000160 elsif ($ErrorType eq $OtherError) {
161 $prefix = "clang_other_error";
162 }
Ted Kremenek72e4b0b2008-09-25 00:51:44 +0000163
Ted Kremenek0799d4f2009-07-28 00:14:21 +0000164 # Generate the preprocessed file with Clang.
Ted Kremenek725fb432009-01-27 01:19:08 +0000165 my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",
166 SUFFIX => GetPPExt($Lang),
167 DIR => $Dir);
Ted Kremenek994c8e32008-08-08 20:46:42 +0000168 close ($PPH);
Anton Yartsev321b1762015-06-17 23:12:33 +0000169 system $Clang, @$Args, "-E", "-o", $PPFile;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000170
Ted Kremenek72e4b0b2008-09-25 00:51:44 +0000171 # Create the info file.
Ted Kremenek1ad3b3d2008-09-25 00:25:16 +0000172 open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
Ted Kremenek32c11812008-09-21 18:04:49 +0000173 print OUT abs_path($file), "\n";
Ted Kremenek5abf5462008-08-18 18:38:29 +0000174 print OUT "$ErrorType\n";
Ted Kremenekb3c98d32008-08-18 20:55:25 +0000175 print OUT "@$Args\n";
Ted Kremenek994c8e32008-08-08 20:46:42 +0000176 close OUT;
Ted Kremenek1ad3b3d2008-09-25 00:25:16 +0000177 `uname -a >> $PPFile.info.txt 2>&1`;
Anton Yartsev84f90422015-07-01 22:35:29 +0000178 `"$Compiler" -v >> $PPFile.info.txt 2>&1`;
Sylvestre Ledrudf70a7b2014-05-23 16:10:00 +0000179 rename($ofile, "$PPFile.stderr.txt");
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000180 return (basename $PPFile);
Ted Kremenek994c8e32008-08-08 20:46:42 +0000181}
Ted Kremenek5efdf842008-03-25 22:35:32 +0000182
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000183##----------------------------------------------------------------------------##
184# Running the analyzer.
185##----------------------------------------------------------------------------##
Ted Kremenek5efdf842008-03-25 22:35:32 +0000186
Ted Kremenek1f991f02009-05-09 19:19:28 +0000187sub GetCCArgs {
Anton Yartsev84f90422015-07-01 22:35:29 +0000188 my $HtmlDir = shift;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000189 my $mode = shift;
Ted Kremenek1f991f02009-05-09 19:19:28 +0000190 my $Args = shift;
Ted Kremenek1f991f02009-05-09 19:19:28 +0000191 my $line;
Anton Yartsev84f90422015-07-01 22:35:29 +0000192 my $OutputStream = silent_system($HtmlDir, $Clang, "-###", $mode, @$Args);
193 while (<$OutputStream>) {
Jordan Rose0d7d09f2014-03-20 17:43:54 +0000194 next if (!/\s"?-cc1"?\s/);
Ted Kremenek1f991f02009-05-09 19:19:28 +0000195 $line = $_;
196 }
Ted Kremenekf92b4462009-12-11 23:12:52 +0000197 die "could not find clang line\n" if (!defined $line);
Anton Yartsev0cb7c8a2014-01-23 14:12:48 +0000198 # Strip leading and trailing whitespace characters.
199 $line =~ s/^\s+|\s+$//g;
Anton Yartsev22f61892015-05-05 19:43:37 +0000200 my @items = quotewords('\s+', 0, $line);
Ted Kremenek1f991f02009-05-09 19:19:28 +0000201 my $cmd = shift @items;
Ted Kremenekf92b4462009-12-11 23:12:52 +0000202 die "cannot find 'clang' in 'clang' command\n" if (!($cmd =~ /clang/));
Ted Kremenek1f991f02009-05-09 19:19:28 +0000203 return \@items;
204}
205
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000206sub Analyze {
Ted Kremenek339f7c32011-03-10 21:10:08 +0000207 my ($Clang, $OriginalArgs, $AnalyzeArgs, $Lang, $Output, $Verbose, $HtmlDir,
Ted Kremenek42ec9142011-02-17 02:28:30 +0000208 $file) = @_;
Seo Sanghyeonb7bf0f32008-04-04 11:02:21 +0000209
Ted Kremenek339f7c32011-03-10 21:10:08 +0000210 my @Args = @$OriginalArgs;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000211 my $Cmd;
212 my @CmdArgs;
Ted Kremenek994c8e32008-08-08 20:46:42 +0000213 my @CmdArgsSansAnalyses;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000214
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000215 if ($Lang =~ /header/) {
216 exit 0 if (!defined ($Output));
217 $Cmd = 'cp';
Ted Kremenek42ec9142011-02-17 02:28:30 +0000218 push @CmdArgs, $file;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000219 # Remove the PCH extension.
220 $Output =~ s/[.]gch$//;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000221 push @CmdArgs, $Output;
222 @CmdArgsSansAnalyses = @CmdArgs;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000223 }
224 else {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000225 $Cmd = $Clang;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000226
227 # Create arguments for doing regular parsing.
Anton Yartsev84f90422015-07-01 22:35:29 +0000228 my $SyntaxArgs = GetCCArgs($HtmlDir, "-fsyntax-only", \@Args);
Ted Kremenek339f7c32011-03-10 21:10:08 +0000229 @CmdArgsSansAnalyses = @$SyntaxArgs;
230
Ted Kremenek42ec9142011-02-17 02:28:30 +0000231 # Create arguments for doing static analysis.
232 if (defined $ResultFile) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000233 push @Args, '-o', $ResultFile;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000234 }
235 elsif (defined $HtmlDir) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000236 push @Args, '-o', $HtmlDir;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000237 }
Ted Kremenek9acb3462011-03-21 20:12:21 +0000238 if ($Verbose) {
239 push @Args, "-Xclang", "-analyzer-display-progress";
240 }
Ted Kremenek42ec9142011-02-17 02:28:30 +0000241
242 foreach my $arg (@$AnalyzeArgs) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000243 push @Args, "-Xclang", $arg;
Ted Kremenek4ef13f82009-11-13 18:46:29 +0000244 }
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000245
Ted Kremenek42ec9142011-02-17 02:28:30 +0000246 # Display Ubiviz graph?
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000247 if (defined $ENV{'CCC_UBI'}) {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000248 push @Args, "-Xclang", "-analyzer-viz-egraph-ubigraph";
Ted Kremenek42ec9142011-02-17 02:28:30 +0000249 }
250
Ted Kremenek0270a082015-08-08 17:58:47 +0000251 if (defined $AnalyzerTarget) {
252 push @Args, "-target", $AnalyzerTarget;
253 }
254
Anton Yartsev84f90422015-07-01 22:35:29 +0000255 my $AnalysisArgs = GetCCArgs($HtmlDir, "--analyze", \@Args);
Ted Kremenek339f7c32011-03-10 21:10:08 +0000256 @CmdArgs = @$AnalysisArgs;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000257 }
Ted Kremenek42ec9142011-02-17 02:28:30 +0000258
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000259 my @PrintArgs;
260 my $dir;
Ted Kremenek7ac29bb2009-08-02 05:42:46 +0000261
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000262 if ($Verbose) {
263 $dir = getcwd();
264 print STDERR "\n[LOCATION]: $dir\n";
265 push @PrintArgs,"'$Cmd'";
Ted Kremenek42ec9142011-02-17 02:28:30 +0000266 foreach my $arg (@CmdArgs) {
267 push @PrintArgs,"\'$arg\'";
268 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000269 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000270 if ($Verbose == 1) {
Ted Kremenekf18f4602008-05-24 15:58:54 +0000271 # We MUST print to stderr. Some clients use the stdout output of
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000272 # gcc for various purposes.
Ted Kremenek339f7c32011-03-10 21:10:08 +0000273 print STDERR join(' ', @PrintArgs);
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000274 print STDERR "\n";
275 }
276 elsif ($Verbose == 2) {
277 print STDERR "#SHELL (cd '$dir' && @PrintArgs)\n";
278 }
Ted Kremenek42ec9142011-02-17 02:28:30 +0000279
Anton Yartsev84f90422015-07-01 22:35:29 +0000280 # Save STDOUT and STDERR of clang to a temporary file and reroute
281 # all clang output to ccc-analyzer's STDERR.
Ted Kremenek370de842008-09-04 00:02:34 +0000282 # We save the output file in the 'crashes' directory if clang encounters
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000283 # any problems with the file.
Ted Kremenek4ab81cb2008-09-11 23:05:26 +0000284 my ($ofh, $ofile) = tempfile("clang_output_XXXXXX", DIR => $HtmlDir);
Ted Kremenek3a0678e2015-09-08 03:50:52 +0000285
Anton Yartsev84f90422015-07-01 22:35:29 +0000286 my $OutputStream = silent_system($HtmlDir, $Cmd, @CmdArgs);
287 while ( <$OutputStream> ) {
Ted Kremenek4ab81cb2008-09-11 23:05:26 +0000288 print $ofh $_;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000289 print STDERR $_;
Ted Kremenek4ab81cb2008-09-11 23:05:26 +0000290 }
Ted Kremenek370de842008-09-04 00:02:34 +0000291 my $Result = $?;
Anton Yartsev84f90422015-07-01 22:35:29 +0000292 close $ofh;
Ted Kremenek370de842008-09-04 00:02:34 +0000293
294 # Did the command die because of a signal?
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000295 if ($ReportFailures) {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000296 if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) {
297 ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000298 $HtmlDir, "Crash", $ofile);
Ted Kremenek078b8872009-02-27 06:17:38 +0000299 }
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000300 elsif ($Result) {
301 if ($IncludeParserRejects && !($file =~/conftest/)) {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000302 ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000303 $HtmlDir, $ParserRejects, $ofile);
Anna Zaks9fed0842011-11-07 22:38:10 +0000304 } else {
305 ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses,
Jordan Rose85ff8f22012-11-28 19:12:44 +0000306 $HtmlDir, $OtherError, $ofile);
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000307 }
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000308 }
309 else {
310 # Check if there were any unhandled attributes.
311 if (open(CHILD, $ofile)) {
312 my %attributes_not_handled;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000313
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000314 # Don't flag warnings about the following attributes that we
315 # know are currently not supported by Clang.
316 $attributes_not_handled{"cdecl"} = 1;
Ted Kremenek42ec9142011-02-17 02:28:30 +0000317
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000318 my $ppfile;
319 while (<CHILD>) {
320 next if (! /warning: '([^\']+)' attribute ignored/);
321
322 # Have we already spotted this unhandled attribute?
323 next if (defined $attributes_not_handled{$1});
324 $attributes_not_handled{$1} = 1;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000325
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000326 # Get the name of the attribute file.
327 my $dir = "$HtmlDir/failures";
328 my $afile = "$dir/attribute_ignored_$1.txt";
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000329
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000330 # Only create another preprocessed file if the attribute file
331 # doesn't exist yet.
332 next if (-e $afile);
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000333
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000334 # Add this file to the list of files that contained this attribute.
335 # Generate a preprocessed file if we haven't already.
336 if (!(defined $ppfile)) {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000337 $ppfile = ProcessClangFailure($Clang, $Lang, $file,
Ted Kremenekbfe393f2009-07-30 23:55:19 +0000338 \@CmdArgsSansAnalyses,
339 $HtmlDir, $AttributeIgnored, $ofile);
340 }
341
342 mkpath $dir;
343 open(AFILE, ">$afile");
344 print AFILE "$ppfile\n";
345 close(AFILE);
346 }
347 close CHILD;
348 }
Ted Kremenek13ed6f12009-02-17 23:31:05 +0000349 }
350 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000351
Ted Kremenek90fc8a42009-08-04 00:55:59 +0000352 unlink($ofile);
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000353}
Ted Kremenekf18f4602008-05-24 15:58:54 +0000354
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000355##----------------------------------------------------------------------------##
356# Lookup tables.
357##----------------------------------------------------------------------------##
358
359my %CompileOptionMap = (
360 '-nostdinc' => 0,
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000361 '-include' => 1,
362 '-idirafter' => 1,
Ted Kremeneke869a182010-06-08 18:27:55 +0000363 '-imacros' => 1,
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000364 '-iprefix' => 1,
365 '-iquote' => 1,
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000366 '-iwithprefix' => 1,
367 '-iwithprefixbefore' => 1
368);
369
370my %LinkerOptionMap = (
Ted Kremenek415287d2012-03-06 20:06:12 +0000371 '-framework' => 1,
372 '-fobjc-link-runtime' => 0
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000373);
374
375my %CompilerLinkerOptionMap = (
Jordan Rose525121f2013-07-12 16:07:33 +0000376 '-Wwrite-strings' => 0,
Jordan Rose05b3a8b2013-07-11 23:56:12 +0000377 '-ftrapv-handler' => 1, # specifically call out separated -f flag
Ted Kremenek7c88d2a2012-08-07 19:27:08 +0000378 '-mios-simulator-version-min' => 0, # This really has 1 argument, but always has '='
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000379 '-isysroot' => 1,
380 '-arch' => 1,
Charles Davisdde71b92010-03-02 15:26:41 +0000381 '-m32' => 0,
382 '-m64' => 0,
Benjamin Kramer75e4bb12012-09-19 22:56:24 +0000383 '-stdlib' => 0, # This is really a 1 argument, but always has '='
Jordan Rose57ee6d22014-05-12 17:04:44 +0000384 '--sysroot' => 1,
Jordan Rose687fc9a2013-08-08 16:06:26 +0000385 '-target' => 1,
Ted Kremenek6b2e07a2008-09-29 22:45:28 +0000386 '-v' => 0,
Daniel Dunbar497ff132009-04-10 19:52:24 +0000387 '-mmacosx-version-min' => 0, # This is really a 1 argument, but always has '='
388 '-miphoneos-version-min' => 0 # This is really a 1 argument, but always has '='
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000389);
390
391my %IgnoredOptionMap = (
Ted Kremenek4a154b22008-07-24 03:52:21 +0000392 '-MT' => 1, # Ignore these preprocessor options.
393 '-MF' => 1,
394
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000395 '-fsyntax-only' => 0,
396 '-save-temps' => 0,
397 '-install_name' => 1,
398 '-exported_symbols_list' => 1,
399 '-current_version' => 1,
400 '-compatibility_version' => 1,
401 '-init' => 1,
402 '-e' => 1,
403 '-seg1addr' => 1,
404 '-bundle_loader' => 1,
405 '-multiply_defined' => 1,
406 '-sectorder' => 3,
407 '--param' => 1,
Anna Zaks3a7f73d2012-01-06 01:54:02 +0000408 '-u' => 1,
409 '--serialize-diagnostics' => 1
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000410);
411
412my %LangMap = (
Jordan Rosea63f2292014-01-07 21:39:51 +0000413 'c' => $IsCXX ? 'c++' : 'c',
Shantonu Sendf44f742010-07-03 03:08:23 +0000414 'cp' => 'c++',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000415 'cpp' => 'c++',
Anna Zaksd6827412012-04-14 16:30:00 +0000416 'cxx' => 'c++',
417 'txx' => 'c++',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000418 'cc' => 'c++',
Jordan Rosedbbbf5512012-11-28 19:12:29 +0000419 'C' => 'c++',
Jordan Rosea63f2292014-01-07 21:39:51 +0000420 'ii' => 'c++-cpp-output',
421 'i' => $IsCXX ? 'c++-cpp-output' : 'c-cpp-output',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000422 'm' => 'objective-c',
Anna Zaks5efad632011-08-31 23:53:24 +0000423 'mi' => 'objective-c-cpp-output',
Jordan Rosea63f2292014-01-07 21:39:51 +0000424 'mm' => 'objective-c++',
425 'mii' => 'objective-c++-cpp-output',
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000426);
427
Ted Kremenek8b89a652008-09-29 16:15:20 +0000428my %UniqueOptions = (
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000429 '-isysroot' => 0
Ted Kremenek8b89a652008-09-29 16:15:20 +0000430);
431
Ted Kremenekadccbca2010-03-08 19:06:44 +0000432##----------------------------------------------------------------------------##
433# Languages accepted.
434##----------------------------------------------------------------------------##
435
Ted Kremenekdc99ec42009-05-11 21:08:34 +0000436my %LangsAccepted = (
437 "objective-c" => 1,
Ted Kremenekd33c4d32011-08-11 22:47:20 +0000438 "c" => 1,
439 "c++" => 1,
Ted Kremenek38d77472014-02-25 19:16:33 +0000440 "objective-c++" => 1,
441 "c-cpp-output" => 1,
442 "objective-c-cpp-output" => 1,
443 "c++-cpp-output" => 1
Ted Kremenekdc99ec42009-05-11 21:08:34 +0000444);
445
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000446##----------------------------------------------------------------------------##
447# Main Logic.
448##----------------------------------------------------------------------------##
449
450my $Action = 'link';
451my @CompileOpts;
452my @LinkOpts;
453my @Files;
454my $Lang;
455my $Output;
Ted Kremenek8b89a652008-09-29 16:15:20 +0000456my %Uniqued;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000457
458# Forward arguments to gcc.
Ted Kremenekf65a0c62009-12-15 02:35:54 +0000459my $Status = system($Compiler,@ARGV);
Jordan Rose1187b952013-07-03 16:42:02 +0000460if (defined $ENV{'CCC_ANALYZER_LOG'}) {
461 print STDERR "$Compiler @ARGV\n";
Tom Carea5f13c862010-09-29 23:48:31 +0000462}
Ted Kremenek1a422782008-08-28 01:18:44 +0000463if ($Status) { exit($Status >> 8); }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000464
465# Get the analysis options.
466my $Analyses = $ENV{'CCC_ANALYZER_ANALYSIS'};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000467
Anna Zaks268f1542012-05-25 01:13:50 +0000468# Get the plugins to load.
469my $Plugins = $ENV{'CCC_ANALYZER_PLUGINS'};
470
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000471# Get the store model.
472my $StoreModel = $ENV{'CCC_ANALYZER_STORE_MODEL'};
Ted Kremenekb5351812009-02-17 04:27:41 +0000473
474# Get the constraints engine.
475my $ConstraintsModel = $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'};
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000476
Anna Zaks7aa36872012-06-22 22:08:12 +0000477#Get the internal stats setting.
478my $InternalStats = $ENV{'CCC_ANALYZER_INTERNAL_STATS'};
479
Ted Kremenek90230552008-11-04 00:02:53 +0000480# Get the output format.
481my $OutputFormat = $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'};
Ted Kremenekd3d16aa2009-02-17 05:01:10 +0000482if (!defined $OutputFormat) { $OutputFormat = "html"; }
Ted Kremenek90230552008-11-04 00:02:53 +0000483
Jordan Rose3dcbca32013-12-13 17:16:28 +0000484# Get the config options.
485my $ConfigOptions = $ENV{'CCC_ANALYZER_CONFIG'};
486
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000487# Determine the level of verbosity.
488my $Verbose = 0;
Jordan Rose1187b952013-07-03 16:42:02 +0000489if (defined $ENV{'CCC_ANALYZER_VERBOSE'}) { $Verbose = 1; }
490if (defined $ENV{'CCC_ANALYZER_LOG'}) { $Verbose = 2; }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000491
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000492# Get the HTML output directory.
493my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
494
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000495my %DisabledArchs = ('ppc' => 1, 'ppc64' => 1);
Ted Kremenek15146a52008-09-25 20:17:57 +0000496my %ArchsSeen;
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000497my $HadArch = 0;
Ted Kremenek398f46f2014-12-31 07:44:51 +0000498my $HasSDK = 0;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000499
500# Process the arguments.
501foreach (my $i = 0; $i < scalar(@ARGV); ++$i) {
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000502 my $Arg = $ARGV[$i];
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000503 my ($ArgKey) = split /=/,$Arg,2;
504
Anna Zaks50b09562015-03-28 02:17:21 +0000505 # Be friendly to "" in the argument list.
506 if (!defined($ArgKey)) {
507 next;
508 }
509
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000510 # Modes ccc-analyzer supports
Ted Kremenekba8d7fc2009-08-04 00:57:12 +0000511 if ($Arg =~ /^-(E|MM?)$/) { $Action = 'preprocess'; }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000512 elsif ($Arg eq '-c') { $Action = 'compile'; }
513 elsif ($Arg =~ /^-print-prog-name/) { exit 0; }
Ted Kremenek15146a52008-09-25 20:17:57 +0000514
515 # Specially handle duplicate cases of -arch
516 if ($Arg eq "-arch") {
517 my $arch = $ARGV[$i+1];
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000518 # We don't want to process 'ppc' because of Clang's lack of support
519 # for Altivec (also some #defines won't likely be defined correctly, etc.)
520 if (!(defined $DisabledArchs{$arch})) { $ArchsSeen{$arch} = 1; }
521 $HadArch = 1;
Ted Kremenek15146a52008-09-25 20:17:57 +0000522 ++$i;
523 next;
524 }
525
Ted Kremenek398f46f2014-12-31 07:44:51 +0000526 # On OSX/iOS, record if an SDK path was specified. This
527 # is innocuous for other platforms, so the check just happens.
528 if ($Arg =~ /^-isysroot/) {
529 $HasSDK = 1;
530 }
531
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000532 # Options with possible arguments that should pass through to compiler.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000533 if (defined $CompileOptionMap{$ArgKey}) {
534 my $Cnt = $CompileOptionMap{$ArgKey};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000535 push @CompileOpts,$Arg;
536 while ($Cnt > 0) { ++$i; --$Cnt; push @CompileOpts, $ARGV[$i]; }
537 next;
538 }
Ted Kremenek3cfba5b2013-02-14 00:32:25 +0000539 # Handle the case where there isn't a space after -iquote
Jordan Rose69ab7262014-03-19 17:42:26 +0000540 if ($Arg =~ /^-iquote.*/) {
Ted Kremenek3cfba5b2013-02-14 00:32:25 +0000541 push @CompileOpts,$Arg;
542 next;
543 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000544
545 # Options with possible arguments that should pass through to linker.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000546 if (defined $LinkerOptionMap{$ArgKey}) {
547 my $Cnt = $LinkerOptionMap{$ArgKey};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000548 push @LinkOpts,$Arg;
549 while ($Cnt > 0) { ++$i; --$Cnt; push @LinkOpts, $ARGV[$i]; }
550 next;
551 }
552
553 # Options with possible arguments that should pass through to both compiler
554 # and the linker.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000555 if (defined $CompilerLinkerOptionMap{$ArgKey}) {
556 my $Cnt = $CompilerLinkerOptionMap{$ArgKey};
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000557
Ted Kremenek8b89a652008-09-29 16:15:20 +0000558 # Check if this is an option that should have a unique value, and if so
559 # determine if the value was checked before.
560 if ($UniqueOptions{$Arg}) {
561 if (defined $Uniqued{$Arg}) {
562 $i += $Cnt;
563 next;
564 }
565 $Uniqued{$Arg} = 1;
566 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000567
568 push @CompileOpts,$Arg;
Ted Kremenek887c49d2008-09-29 23:06:09 +0000569 push @LinkOpts,$Arg;
570
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000571 while ($Cnt > 0) {
572 ++$i; --$Cnt;
573 push @CompileOpts, $ARGV[$i];
574 push @LinkOpts, $ARGV[$i];
575 }
576 next;
577 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000578
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000579 # Ignored options.
Ted Kremenekad4a57d2008-10-19 06:42:38 +0000580 if (defined $IgnoredOptionMap{$ArgKey}) {
581 my $Cnt = $IgnoredOptionMap{$ArgKey};
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000582 while ($Cnt > 0) {
583 ++$i; --$Cnt;
584 }
585 next;
586 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000587
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000588 # Compile mode flags.
Ted Kremenek0f26d132015-02-03 06:23:36 +0000589 if ($Arg =~ /^-[D,I,U,isystem](.*)$/) {
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000590 my $Tmp = $Arg;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000591 if ($1 eq '') {
592 # FIXME: Check if we are going off the end.
593 ++$i;
594 $Tmp = $Arg . $ARGV[$i];
595 }
596 push @CompileOpts,$Tmp;
597 next;
598 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000599
Jordan Rose69ab7262014-03-19 17:42:26 +0000600 if ($Arg =~ /^-m.*/) {
Jordan Rose476bbb022013-10-22 18:55:18 +0000601 push @CompileOpts,$Arg;
602 next;
603 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000604
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000605 # Language.
606 if ($Arg eq '-x') {
607 $Lang = $ARGV[$i+1];
608 ++$i; next;
609 }
Ted Kremenekf18f4602008-05-24 15:58:54 +0000610
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000611 # Output file.
612 if ($Arg eq '-o') {
613 ++$i;
614 $Output = $ARGV[$i];
615 next;
616 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000617
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000618 # Get the link mode.
619 if ($Arg =~ /^-[l,L,O]/) {
620 if ($Arg eq '-O') { push @LinkOpts,'-O1'; }
621 elsif ($Arg eq '-Os') { push @LinkOpts,'-O2'; }
622 else { push @LinkOpts,$Arg; }
Jordan Rose05b3a8b2013-07-11 23:56:12 +0000623
624 # Must pass this along for the __OPTIMIZE__ macro
625 if ($Arg =~ /^-O/) { push @CompileOpts,$Arg; }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000626 next;
627 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000628
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000629 if ($Arg =~ /^-std=/) {
630 push @CompileOpts,$Arg;
631 next;
632 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000633
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000634 # Get the compiler/link mode.
635 if ($Arg =~ /^-F(.+)$/) {
636 my $Tmp = $Arg;
637 if ($1 eq '') {
638 # FIXME: Check if we are going off the end.
639 ++$i;
640 $Tmp = $Arg . $ARGV[$i];
641 }
642 push @CompileOpts,$Tmp;
643 push @LinkOpts,$Tmp;
644 next;
645 }
Ted Kremenekf18f4602008-05-24 15:58:54 +0000646
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000647 # Input files.
648 if ($Arg eq '-filelist') {
649 # FIXME: Make sure we aren't walking off the end.
650 open(IN, $ARGV[$i+1]);
651 while (<IN>) { s/\015?\012//; push @Files,$_; }
652 close(IN);
Ted Kremenekd0d72562009-08-14 18:20:50 +0000653 ++$i;
654 next;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000655 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000656
Jordan Rose05b3a8b2013-07-11 23:56:12 +0000657 if ($Arg =~ /^-f/) {
658 push @CompileOpts,$Arg;
659 push @LinkOpts,$Arg;
660 next;
661 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000662
Ted Kremenekd0d72562009-08-14 18:20:50 +0000663 # Handle -Wno-. We don't care about extra warnings, but
664 # we should suppress ones that we don't want to see.
665 if ($Arg =~ /^-Wno-/) {
666 push @CompileOpts, $Arg;
667 next;
668 }
669
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000670 if (!($Arg =~ /^-/)) {
Ted Kremenekd0d72562009-08-14 18:20:50 +0000671 push @Files, $Arg;
672 next;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000673 }
674}
Ted Kremenekf18f4602008-05-24 15:58:54 +0000675
Ted Kremenek398f46f2014-12-31 07:44:51 +0000676# If we are on OSX and have an installation where the
677# default SDK is inferred by xcrun use xcrun to infer
678# the SDK.
679if (not $HasSDK and $UseXCRUN) {
680 my $sdk = `/usr/bin/xcrun --show-sdk-path -sdk macosx`;
681 chomp $sdk;
682 push @CompileOpts, "-isysroot", $sdk;
683}
684
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000685if ($Action eq 'compile' or $Action eq 'link') {
Ted Kremenek9b15eff2009-02-24 22:07:12 +0000686 my @Archs = keys %ArchsSeen;
687 # Skip the file if we don't support the architectures specified.
Ted Kremenek86cb75a2009-02-25 00:10:37 +0000688 exit 0 if ($HadArch && scalar(@Archs) == 0);
Jordan Rose85ff8f22012-11-28 19:12:44 +0000689
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000690 foreach my $file (@Files) {
691 # Determine the language for the file.
692 my $FileLang = $Lang;
693
694 if (!defined($FileLang)) {
695 # Infer the language from the extension.
696 if ($file =~ /[.]([^.]+)$/) {
697 $FileLang = $LangMap{$1};
698 }
699 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000700
Ted Kremenek14015de2010-02-12 00:10:34 +0000701 # FileLang still not defined? Skip the file.
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000702 next if (!defined $FileLang);
Ted Kremenek14015de2010-02-12 00:10:34 +0000703
704 # Language not accepted?
Ted Kremenekdc99ec42009-05-11 21:08:34 +0000705 next if (!defined $LangsAccepted{$FileLang});
Ted Kremenek14015de2010-02-12 00:10:34 +0000706
Ted Kremenek46727df2009-05-15 04:20:31 +0000707 my @CmdArgs;
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000708 my @AnalyzeArgs;
709
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000710 if ($FileLang ne 'unknown') {
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000711 push @CmdArgs, '-x', $FileLang;
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000712 }
Ted Kremenek5efdf842008-03-25 22:35:32 +0000713
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000714 if (defined $StoreModel) {
Ted Kremenekb5351812009-02-17 04:27:41 +0000715 push @AnalyzeArgs, "-analyzer-store=$StoreModel";
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000716 }
Ted Kremenekb5351812009-02-17 04:27:41 +0000717
718 if (defined $ConstraintsModel) {
719 push @AnalyzeArgs, "-analyzer-constraints=$ConstraintsModel";
720 }
Anna Zaks7aa36872012-06-22 22:08:12 +0000721
722 if (defined $InternalStats) {
723 push @AnalyzeArgs, "-analyzer-stats";
724 }
Sylvestre Ledru82e547e2014-02-18 17:21:45 +0000725
Anna Zaks5efad632011-08-31 23:53:24 +0000726 if (defined $Analyses) {
727 push @AnalyzeArgs, split '\s+', $Analyses;
728 }
Ted Kremenekb5351812009-02-17 04:27:41 +0000729
Anna Zaks268f1542012-05-25 01:13:50 +0000730 if (defined $Plugins) {
731 push @AnalyzeArgs, split '\s+', $Plugins;
732 }
733
Ted Kremenek90230552008-11-04 00:02:53 +0000734 if (defined $OutputFormat) {
Ted Kremenekb5351812009-02-17 04:27:41 +0000735 push @AnalyzeArgs, "-analyzer-output=" . $OutputFormat;
Ted Kremenek5cc54862009-07-27 22:10:34 +0000736 if ($OutputFormat =~ /plist/) {
Ted Kremenek13747162009-01-21 00:42:24 +0000737 # Change "Output" to be a file.
738 my ($h, $f) = tempfile("report-XXXXXX", SUFFIX => ".plist",
739 DIR => $HtmlDir);
740 $ResultFile = $f;
Alp Tokerf6a24ce2013-12-05 16:25:25 +0000741 # If the HtmlDir is not set, we should clean up the plist files.
Anna Zaks45ce1bf2011-09-09 18:43:53 +0000742 if (!defined $HtmlDir || -z $HtmlDir) {
Jordan Rose85ff8f22012-11-28 19:12:44 +0000743 $CleanupFile = $f;
Anna Zaks45ce1bf2011-09-09 18:43:53 +0000744 }
Ted Kremenek13747162009-01-21 00:42:24 +0000745 }
Ted Kremenek90230552008-11-04 00:02:53 +0000746 }
Jordan Rose3dcbca32013-12-13 17:16:28 +0000747 if (defined $ConfigOptions) {
748 push @AnalyzeArgs, split '\s+', $ConfigOptions;
749 }
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000750
Ted Kremenek42ec9142011-02-17 02:28:30 +0000751 push @CmdArgs, @CompileOpts;
752 push @CmdArgs, $file;
Zhongxing Xuad4c3de2008-10-27 14:26:32 +0000753
Ted Kremenek15146a52008-09-25 20:17:57 +0000754 if (scalar @Archs) {
755 foreach my $arch (@Archs) {
756 my @NewArgs;
Ted Kremenekd4bcb4f2011-03-16 21:10:42 +0000757 push @NewArgs, '-arch', $arch;
Ted Kremenek46727df2009-05-15 04:20:31 +0000758 push @NewArgs, @CmdArgs;
Ted Kremenek5c512e62009-12-11 22:44:53 +0000759 Analyze($Clang, \@NewArgs, \@AnalyzeArgs, $FileLang, $Output,
Ted Kremenek42ec9142011-02-17 02:28:30 +0000760 $Verbose, $HtmlDir, $file);
Ted Kremenek15146a52008-09-25 20:17:57 +0000761 }
762 }
763 else {
Ted Kremenek5c512e62009-12-11 22:44:53 +0000764 Analyze($Clang, \@CmdArgs, \@AnalyzeArgs, $FileLang, $Output,
Ted Kremenek42ec9142011-02-17 02:28:30 +0000765 $Verbose, $HtmlDir, $file);
Ted Kremenek15146a52008-09-25 20:17:57 +0000766 }
Ted Kremenekf7ffd662008-07-19 06:11:04 +0000767 }
768}