]> granicus.if.org Git - clang/commitdiff
Add total hack to get scan-build working again. ccc-analyzer calls
authorTed Kremenek <kremenek@apple.com>
Sat, 9 May 2009 19:19:28 +0000 (19:19 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 9 May 2009 19:19:28 +0000 (19:19 +0000)
'clang -###' to get the appropriate arguments to pass to clang-cc.
This isn't a permanent solution.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71364 91177308-0d34-0410-b5e6-96231b3b80d8

utils/ccc-analyzer
utils/scan-build

index 28e4ad182b2c6f3c2cde069e6a95c359f39dbf01..8c0e119c30c3b8507cdccf0903348667811b2a8e 100755 (executable)
@@ -48,7 +48,7 @@ my $ParserRejects = "Parser Rejects";
 my $AttributeIgnored = "Attribute Ignored";
 
 sub ProcessClangFailure {
-  my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
+  my ($ClangCC, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
   my $Dir = "$HtmlDir/failures";
   mkpath $Dir;
   
@@ -71,7 +71,7 @@ sub ProcessClangFailure {
   # Generate the preprocessed file with clang.
   my $PPFile_Clang = $PPFile;
   $PPFile_Clang =~ s/[.](.+)$/.clang.$1/;  
-  system $Clang, @$Args, "-E", "-o", "$PPFile_Clang";
+  system $ClangCC, @$Args, "-E", "-o", "$PPFile_Clang";
   
   # Create the info file.
   open (OUT, ">", "$PPFile.info.txt") or die "Cannot open $PPFile.info.txt\n";
@@ -89,8 +89,49 @@ sub ProcessClangFailure {
 #  Running the analyzer.
 ##----------------------------------------------------------------------------##
 
+# Determine what clang executable to use.
+my $Clang = $ENV{'CLANG'};
+if (!defined $Clang) { $Clang = 'clang'; }
+
+sub GetCCArgs {
+  my $Args = shift;
+  
+  pipe (FROM_CHILD, TO_PARENT);
+  my $pid = fork();
+  if ($pid == 0) {
+    close FROM_CHILD;
+    open(STDOUT,">&", \*TO_PARENT);
+    open(STDERR,">&", \*TO_PARENT);
+    exec $Clang, "-###", "-fsyntax-only", @$Args;
+  }  
+  close(TO_PARENT);
+  my $line;
+  while (<FROM_CHILD>) {
+    next if (!/clang-cc/);
+    $line = $_;
+  }
+
+  waitpid($pid,0);
+  close(FROM_CHILD);
+  
+  die "could not find clang-cc line\n" if (!defined $line);
+  my @items = ($line =~ /(".*?"|\S+)/g);
+  
+  for (my $i = 0; $i < scalar(@items); ++$i) {
+    my $x = $items[$i];
+    $x =~ s/^"//;
+    $x =~ s/"$//;
+    $items[$i] = $x;
+  }
+
+  my $cmd = shift @items;
+  die "cannot find 'clang-cc' in 'clang' command\n" if (!($cmd =~ /clang-cc/));
+  return \@items;
+}
+
 sub Analyze {
-  my ($Clang, $Args, $Lang, $Output, $Verbose, $HtmlDir, $file, $Analyses) = @_;
+  my ($ClangCC, $Args, $Lang, $Output, $Verbose, $HtmlDir, $file, $Analyses) = @_;
+  $Args = GetCCArgs($Args);
 
   # Skip anything related to C++.
   return if ($Lang =~ /c[+][+]/);
@@ -110,13 +151,12 @@ sub Analyze {
     @CmdArgsSansAnalyses = @CmdArgs;    
   }
   else {
-    $Cmd = $Clang;
+    $Cmd = $ClangCC;
     push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))';
     push @CmdArgs,@$Args;
     @CmdArgsSansAnalyses = @CmdArgs;
     push @CmdArgs,'-analyze';
     push @CmdArgs,"-analyzer-display-progress";
-    push @CmdArgs,"-disable-free";
     push @CmdArgs,"-analyzer-eagerly-assume";
     push @CmdArgs,(split /\s/,$Analyses);
     $RunAnalyzer = 1;
@@ -156,7 +196,7 @@ sub Analyze {
   if (defined $ENV{'CCC_UBI'}) {   
     push @CmdArgs,"--analyzer-viz-egraph-ubigraph";
   }
-
+  
   # Capture the STDERR of clang and send it to a temporary file.
   # Capture the STDOUT of clang and reroute it to ccc-analyzer's STDERR.
   # We save the output file in the 'crashes' directory if clang encounters
@@ -179,16 +219,17 @@ sub Analyze {
   }
 
   waitpid($pid,0);
+  close(FROM_CHILD);
   my $Result = $?;
 
   # Did the command die because of a signal?
-  if ($Result & 127 and $Cmd eq $Clang and defined $HtmlDir) {
-    ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
+  if ($Result & 127 and $Cmd eq $ClangCC and defined $HtmlDir) {
+    ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
                         "Crash", $ofile);
   }
   elsif ($Result) {
     if ($IncludeParserRejects && !($file =~/conftest/)) {
-      ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
+      ProcessClangFailure($ClangCC, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
                           $ParserRejects, $ofile);
     }
   }
@@ -220,7 +261,7 @@ sub Analyze {
         # Add this file to the list of files that contained this attribute.
         # Generate a preprocessed file if we haven't already.
         if (!(defined $ppfile)) {
-          $ppfile = ProcessClangFailure($Clang, $Lang, $file,
+          $ppfile = ProcessClangFailure($ClangCC, $Lang, $file,
                                         \@CmdArgsSansAnalyses,
                                         $HtmlDir, $AttributeIgnored, $ofile);
         }
@@ -339,9 +380,9 @@ my $Verbose = 0;
 if (defined $ENV{CCC_ANALYZER_VERBOSE}) { $Verbose = 1; }
 if (defined $ENV{CCC_ANALYZER_LOG}) { $Verbose = 2; }
 
-# Determine what clang executable to use.
-my $Clang = $ENV{'CLANG'};
-if (!defined $Clang) { $Clang = 'clang-cc'; }
+# Determine what clang-cc executable to use.
+my $ClangCC = $ENV{'CLANG_CC'};
+if (!defined $ClangCC) { $ClangCC = 'clang-cc'; }
 
 # Get the HTML output directory.
 my $HtmlDir = $ENV{'CCC_ANALYZER_HTML'};
@@ -546,12 +587,12 @@ if ($Action eq 'compile' or $Action eq 'link') {
         push @NewArgs, '-arch';
         push @NewArgs, $arch;
         push @NewArgs, @AnalyzeArgs;
-        Analyze($Clang, \@NewArgs, $FileLang, $Output,
+        Analyze($ClangCC, \@NewArgs, $FileLang, $Output,
                 $Verbose, $HtmlDir, $file, $Analyses);
       }
     }
     else {
-      Analyze($Clang, \@AnalyzeArgs, $FileLang, $Output,
+      Analyze($ClangCC, \@AnalyzeArgs, $FileLang, $Output,
               $Verbose, $HtmlDir, $file, $Analyses);
     }
   }
index 27883f0d86458cbc4eddf0455d70a879ab520705..74249f7031edc1dd326acb26b2060a3bc32ca346 100755 (executable)
@@ -82,26 +82,42 @@ sub DieDiag {
 ##----------------------------------------------------------------------------##
 
 # First, look for 'clang-cc' in libexec.
-my $ClangSB = Cwd::realpath("$RealBin/libexec/clang-cc");
+my $ClangCCSB = Cwd::realpath("$RealBin/libexec/clang-cc");
 # Second, look for 'clang-cc' in the same directory as scan-build.
-if (!defined $ClangSB || ! -x $ClangSB) {
-  $ClangSB = Cwd::realpath("$RealBin/clang-cc");
+if (!defined $ClangCCSB || ! -x $ClangCCSB) {
+  $ClangCCSB = Cwd::realpath("$RealBin/clang-cc");
 }
 # Third, look for 'clang-cc' in ../libexec
+if (!defined $ClangCCSB || ! -x $ClangCCSB) {
+  $ClangCCSB = Cwd::realpath("$RealBin/../libexec/clang-cc");
+}
+# Finally, default to looking for 'clang-cc' in the path.
+if (!defined $ClangCCSB || ! -x $ClangCCSB) {
+  $ClangCCSB = "clang-cc";
+}
+my $ClangCC = $ClangCCSB;
+
+# Now find 'clang'
+my $ClangSB = Cwd::realpath("$RealBin/bin/clang");
 if (!defined $ClangSB || ! -x $ClangSB) {
-  $ClangSB = Cwd::realpath("$RealBin/../libexec/clang-cc");
+  $ClangSB = Cwd::realpath("$RealBin/clang");
+}
+# Third, look for 'clang' in ../bin
+if (!defined $ClangSB || ! -x $ClangSB) {
+  $ClangSB = Cwd::realpath("$RealBin/../bin/clang");
 }
 # Finally, default to looking for 'clang-cc' in the path.
 if (!defined $ClangSB || ! -x $ClangSB) {
-  $ClangSB = "clang-cc";
+  $ClangSB = "clang";
 }
 my $Clang = $ClangSB;
 
+
 my %AvailableAnalyses;
 
 # Query clang for analysis options.
-open(PIPE, "-|", $Clang, "--help") or
-  DieDiag("Cannot execute '$Clang'\n");
+open(PIPE, "-|", $ClangCC, "--help") or
+  DieDiag("Cannot execute '$ClangCC'\n");
 
 my $FoundAnalysis = 0;
 
@@ -1167,10 +1183,14 @@ if (!defined $Cmd || ! -x $Cmd) {
   DieDiag("Executable 'ccc-analyzer' does not exist at '$Cmd'\n") if(! -x $Cmd);
 }
 
-if (!defined $ClangSB || ! -x $ClangSB) {
+if (!defined $ClangCCSB || ! -x $ClangCCSB) {
   Diag("'clang-cc' executable not found in '$RealBin/libexec'.\n");
   Diag("Using 'clang-cc' from path.\n");
 }
+if (!defined $ClangSB || ! -x $ClangSB) {
+  Diag("'clang' executable not found in '$RealBin/bin'.\n");
+  Diag("Using 'clang' from path.\n");
+}
 
 if (defined $CXX) {
   $ENV{'CXX'} = $CXX;
@@ -1181,6 +1201,7 @@ else {
 }
   
 $ENV{'CC'} = $Cmd;
+$ENV{'CLANG_CC'} = $ClangCC;
 $ENV{'CLANG'} = $Clang;
 
 if ($Verbose >= 2) {