[cfe-commits] r126521 - /cfe/trunk/tools/scan-build/scan-build

Ted Kremenek kremenek at apple.com
Fri Feb 25 14:00:40 PST 2011


Author: kremenek
Date: Fri Feb 25 16:00:40 2011
New Revision: 126521

URL: http://llvm.org/viewvc/llvm-project?rev=126521&view=rev
Log:
Enhance scan-build to print out available analyses using new checker registration model.

This isn't totally complete.  Right now scan-build uses some heuristics to determine
which checkers are enabled by default, but it cannot always tell which checkers
are not enabled.

Modified:
    cfe/trunk/tools/scan-build/scan-build

Modified: cfe/trunk/tools/scan-build/scan-build
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/scan-build/scan-build?rev=126521&r1=126520&r2=126521&view=diff
==============================================================================
--- cfe/trunk/tools/scan-build/scan-build (original)
+++ cfe/trunk/tools/scan-build/scan-build Fri Feb 25 16:00:40 2011
@@ -1005,12 +1005,95 @@
               cost of speed.
 ENDTEXT
 
-# FIXME: Print out available analyesis.
+# Query clang for list of checkers that are enabled.
+my %EnabledCheckers;
+foreach my $lang ("c", "objective-c", "objective-c++", "c++") {
+  pipe(FROM_CHILD, TO_PARENT);
+  my $pid = fork();
+  if ($pid == 0) {
+    close FROM_CHILD;
+    open(STDOUT,">&", \*TO_PARENT);
+    open(STDERR,">&", \*TO_PARENT);
+    exec $Clang, ('--analyze', '-x', $lang, '-', '-###');
+  }
+  close(TO_PARENT);
+  while(<FROM_CHILD>) {
+    foreach my $val (split /\s+/) {
+      $val =~ s/\"//g;
+      if ($val =~ /-analyzer-checker\=([^\s]+)/) {
+        $EnabledCheckers{$1} = 1;
+      }
+    }
+  }
+  waitpid($pid,0);
+  close(FROM_CHILD);
+}
+
+# Query clang for complete list of checkers.
+pipe(FROM_CHILD, TO_PARENT);
+my $pid = fork();
+if ($pid == 0) {
+  close FROM_CHILD;
+  open(STDOUT,">&", \*TO_PARENT);
+  open(STDERR,">&", \*TO_PARENT);
+  exec $Clang, ('-cc1', '-analyzer-checker-help');
+}
+close(TO_PARENT);
+my $foundCheckers = 0;
+while(<FROM_CHILD>) {
+  if (/CHECKERS:/) {
+    $foundCheckers = 1;
+    last;
+  }
+}
+if (!$foundCheckers) {
+  print "  *** Could not query Clang for the list of available checkers.";
+}
+else {
+  print("\nAVAILABLE CHECKERS:\n\n");
+  my $skip = 0;
+  while(<FROM_CHILD>) {
+    if (/core\.experimental/ or /debug\./ or /unix.experimental/ or /cocoa.experimental/) {
+      $skip = 1;
+      next;
+    }
+    if ($skip) {
+      next if (!/^\s\s[^\s]/);
+      $skip = 0;
+    }
+    s/^\s\s//;
+    if (/^([^\s]+)/) {
+      # Is the checker enabled?
+      my $checker = $1;
+      my $enabled = 0;
+      my $aggregate = "";
+      foreach my $domain (split /\./, $checker) {
+        $aggregate .= $domain;
+        if ($EnabledCheckers{$aggregate}) {
+          $enabled =1;
+          last;
+        }        
+      }
+      
+      if ($enabled) {
+        print " + ";
+      }
+      else {
+        print "   ";
+      }
+    }
+    else {
+      print "   ";
+    }
+    print $_;
+  } 
+}
+waitpid($pid,0);
+close(FROM_CHILD);
 
 print <<ENDTEXT
 
- NOTE: "(+)" indicates that an analysis is enabled by default unless one
-       or more analysis options are specified
+ NOTE: "+" indicates that an analysis is enabled by default.
 
 BUILD OPTIONS
 
@@ -1074,6 +1157,9 @@
   exit 1;
 }
 
+
+my $displayHelp = 0;
+
 while (@ARGV) {
   
   # Scan for options we recognize.
@@ -1081,8 +1167,9 @@
   my $arg = $ARGV[0];
 
   if ($arg eq "-h" or $arg eq "--help") {
-    DisplayHelp();
-    exit 0;
+    $displayHelp = 1;
+    shift @ARGV;
+    next;
   }
   
   if ($arg eq '-analyze-headers') {
@@ -1224,12 +1311,17 @@
   last;
 }
 
-if (!@ARGV) {
+if (!@ARGV and $displayHelp == 0) {
   Diag("No build command specified.\n\n");
+  $displayHelp = 1;
+}
+
+if ($displayHelp) {
   DisplayHelp();
   exit 1;
 }
 
+# Determine where results go.
 $CmdArgs = HtmlEscape(join(' ', map(ShellEscape($_), @ARGV)));
 $HtmlTitle = "${CurrentDirSuffix} - scan-build results"
   unless (defined($HtmlTitle));
@@ -1238,9 +1330,7 @@
 my $BaseDir = $HtmlDir;
 $HtmlDir = GetHTMLRunDir($HtmlDir);
 
-# Set the appropriate environment variables.
-SetHtmlEnv(\@ARGV, $HtmlDir);
-
+# Determine the location of ccc-analyzer.
 my $AbsRealBin = Cwd::realpath($RealBin);
 my $Cmd = "$AbsRealBin/libexec/ccc-analyzer";
 my $CmdCXX = "$AbsRealBin/libexec/c++-analyzer";
@@ -1259,27 +1349,24 @@
   Diag("Using 'clang' from path: $Clang\n");
 }
 
+# Set the appropriate environment variables.
+SetHtmlEnv(\@ARGV, $HtmlDir);
 $ENV{'CC'} = $Cmd;
 $ENV{'CXX'} = $CmdCXX;
 $ENV{'CLANG'} = $Clang;
 $ENV{'CLANG_CXX'} = $ClangCXX;
-
 if ($Verbose >= 2) {
   $ENV{'CCC_ANALYZER_VERBOSE'} = 1;
 }
-
 if ($Verbose >= 3) {
   $ENV{'CCC_ANALYZER_LOG'} = 1;
 }
-
 if ($AnalyzeHeaders) {
   push @AnalysesToRun,"-analyzer-opt-analyze-headers";  
 }
-
 if ($AnalyzerStats) {
   push @AnalysesToRun, '-analyzer-stats';
 }
-
 if ($MaxLoop > 0) {
   push @AnalysesToRun, '-analyzer-max-loop ' . $MaxLoop;
 }
@@ -1289,11 +1376,9 @@
 if (defined $StoreModel) {
   $ENV{'CCC_ANALYZER_STORE_MODEL'} = $StoreModel;
 }
-
 if (defined $ConstraintsModel) {
   $ENV{'CCC_ANALYZER_CONSTRAINTS_MODEL'} = $ConstraintsModel;
 }
-
 if (defined $OutputFormat) {
   $ENV{'CCC_ANALYZER_OUTPUT_FORMAT'} = $OutputFormat;
 }





More information about the cfe-commits mailing list