ccc-analyzer:
- now logs which source files had "ignored attributes".
- disable-free is enabled

scan-build:
- now displays a table of ignored attributes under "Analyzer Failures".



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64853 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/ccc-analyzer b/utils/ccc-analyzer
index 1fa0779..57dab8d 100755
--- a/utils/ccc-analyzer
+++ b/utils/ccc-analyzer
@@ -42,14 +42,20 @@
 }
 
 my $ParserRejects = "Parser Rejects";
+my $AttributeIgnored = "Attribute Ignored";
 
 sub ProcessClangFailure {
   my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_;
-  my $Dir = "$HtmlDir/crashes";
+  my $Dir = "$HtmlDir/failures";
   mkpath $Dir;
   
   my $prefix = "clang_crash";
-  if ($ErrorType eq $ParserRejects) { $prefix = "clang_parser_rejects"; }
+  if ($ErrorType eq $ParserRejects) {
+    $prefix = "clang_parser_rejects";
+  }
+  elsif ($ErrorType eq $AttributeIgnored) {
+    $prefix = "clang_attribute_ignored";
+  }
 
   # Generate the preprocessed file with cc (i.e., gcc).
   my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX",
@@ -73,6 +79,7 @@
   `uname -a >> $PPFile.info.txt 2>&1`;
   `$CC -v >> $PPFile.info.txt 2>&1`;
   system 'mv',$ofile,"$PPFile.stderr.txt";
+  return (basename $PPFile);
 }
 
 ##----------------------------------------------------------------------------##
@@ -104,8 +111,9 @@
     push @CmdArgs,'-DIBOutlet=__attribute__((iboutlet))';
     push @CmdArgs,@$Args;
     @CmdArgsSansAnalyses = @CmdArgs;
-    push @CmdArgs,'--analyze';
-    push @CmdArgs,"--analyzer-display-progress";
+    push @CmdArgs,'-analyze';
+    push @CmdArgs,"-analyzer-display-progress";
+    push @CmdArgs,"-disable-free";
     push @CmdArgs,(split /\s/,$Analyses);
     $RunAnalyzer = 1;
   }
@@ -178,6 +186,36 @@
     ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir,
                         $ParserRejects, $ofile);
   }
+  else {
+    # Check if there were any unhandled attributes.
+    if (open(CHILD, $ofile)) {
+      my %attributes_not_handled;
+      my $ppfile;
+      while (<CHILD>) {
+        next if (! /warning: '([^\']+)' attribute ignored/);
+
+        # Have we already spotted this unhandled attribute?
+        next if (defined $attributes_not_handled{$1});
+        $attributes_not_handled{$1} = 1;
+        
+        # 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,
+                                        \@CmdArgsSansAnalyses,
+                                        $HtmlDir, $AttributeIgnored, $ofile);
+        }
+
+        my $dir = "$HtmlDir/failures";
+        mkpath $dir;
+        my $afile = "$dir/attribute_ignored_$1.txt";
+        open(AFILE, ">>$afile");
+        print AFILE "$ppfile\n";
+        close(AFILE);
+      }
+      close CHILD;
+    }
+  }
   
   `rm -f $ofile`;
 }
diff --git a/utils/scan-build b/utils/scan-build
index bc690d5..0e377b8 100755
--- a/utils/scan-build
+++ b/utils/scan-build
@@ -59,8 +59,8 @@
 
 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 ("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.llvm.org/StaticAnalysisUsage.html#filingbugs\n")
 }
@@ -98,10 +98,9 @@
 
 while(<PIPE>) {
   if ($FoundAnalysis == 0) {
-    if (/SCA Checks\/Analyses/) {
+    if (/Checks and Analyses/) {
       $FoundAnalysis = 1;
     }
-
     next;
   }
     
@@ -111,8 +110,7 @@
              
     $AvailableAnalyses{$1} = $2;
     next;
-  }
-  
+  }  
   last;
 }
 
@@ -440,12 +438,10 @@
   }
   
   opendir(DIR, $Dir);
-  my $Crashes = 0;
-  my @files = grep { if ($_ eq "crashes") { $Crashes++; }
-                     /^report-.*\.html$/; } readdir(DIR);
+  my @files = grep { /^report-.*\.html$/ } readdir(DIR);
   closedir(DIR);
 
-  if (scalar(@files) == 0 and $Crashes == 0) {
+  if (scalar(@files) == 0 and ! -e "$Dir/failures") {
     Diag("Removing directory '$Dir' because it contains no reports.\n");
     system ("rm", "-fR", $Dir);
     return 0;
@@ -455,14 +451,19 @@
   my @Index;    
   foreach my $file (@files) { ScanFile(\@Index, $Dir, $file); }
   
-  # Scan the crashes directory and use the information in the .info files
+  # Scan the failures directory and use the information in the .info files
   # to update the common prefix directory.
-  if (-d "$Dir/crashes") {
-    opendir(DIR, "$Dir/crashes");
-    my @files = grep { /[.]info.txt$/; } readdir(DIR);
+  my @failures;
+  my @attributes_ignored;
+  if (-d "$Dir/failures") {
+    opendir(DIR, "$Dir/failures");
+    @failures = grep { /[.]info.txt$/ && !/attribute_ignored/; } readdir(DIR);
     closedir(DIR);
-    foreach my $file (@files) {
-      open IN, "$Dir/crashes/$file" or DieDiag("cannot open $file\n");
+    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 = <IN>;
       if (defined $Path) { UpdatePrefix($Path); }
       close IN;
@@ -568,7 +569,6 @@
       print OUT "\n<p>Results in this analysis run are based on analyzer build <b>$BuildName</b>.</p>\n"
     }
   
-  
   my $TotalBugs = scalar(@Index);
 print OUT <<ENDTEXT;
 <table>
@@ -693,29 +693,50 @@
     print OUT "</tbody>\n</table>\n\n";
   }
 
-  if ($Crashes) {
-    # Read the crash directory for files.
-    opendir(DIR, "$Dir/crashes");
-    my @files = grep { /[.]info.txt$/ } readdir(DIR);
-    closedir(DIR);
-
-    if (scalar(@files)) {
-      print OUT <<ENDTEXT;
-<h2>Analyzer Failures</h2>
-
-<p>The analyzer had problems processing the following files:</p>
-
-<table>
-<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>
-ENDTEXT
-  
-      foreach my $file (sort @files) {
+  if (scalar (@failures) || scalar(@attributes_ignored)) {
+    print OUT "<h2>Analyzer Failures</h2>\n";
+    
+    if (scalar @attributes_ignored) {
+      print OUT "The analyzer's parser ignored the following attributes:<p>\n";
+      print OUT "<table>\n";
+      print OUT "<thead><tr><td>Attribute</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n";
+      foreach my $file (sort @attributes_ignored) {
+        die "cannot demangle attribute name\n" if (! ($file =~ /^attribute_ignored_(.+).txt/));
+        my $attribute = $1;
+        # Open the attribute file to get the first file that failed.
+        next if (!open (ATTR, "$Dir/failures/$file"));
+        my $ppfile = <ATTR>;
+        chomp $ppfile;
+        close ATTR;
+        next if (! -e "$Dir/failures/$ppfile");
+        # Open the info file and get the name of the source file.
+        open (INFO, "$Dir/failures/$ppfile.info.txt") or
+          die "Cannot open $Dir/failures/$ppfile.info.txt\n";
+        my $srcfile = <INFO>;
+        chomp $srcfile;
+        close (INFO);
+        # Print the information in the table.
+        my $prefix = GetPrefix();
+        if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
+        print OUT "<tr><td>$attribute</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
+        my $ppfile_clang = $ppfile;
+        $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
+        print OUT "  <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
+      }
+      print OUT "</table>\n";
+    }
+    
+    if (scalar @failures) {
+      print OUT "<p>The analyzer had problems processing the following files:</p>\n";
+      print OUT "<table>\n";
+      print OUT "<thead><tr><td>Problem</td><td>Source File</td><td>Preprocessed File</td><td>STDERR Output</td></tr></thead>\n";
+      foreach my $file (sort @failures) {
         $file =~ /(.+).info.txt$/;
         # Get the preprocessed file.
         my $ppfile = $1;
         # Open the info file and get the name of the source file.
-        open (INFO, "$Dir/crashes/$file") or
-          die "Cannot open $Dir/crashes/$file\n";
+        open (INFO, "$Dir/failures/$file") or
+          die "Cannot open $Dir/failures/$file\n";
         my $srcfile = <INFO>;
         chomp $srcfile;
         my $problem = <INFO>;
@@ -724,17 +745,14 @@
         # Print the information in the table.
         my $prefix = GetPrefix();
         if (defined $prefix) { $srcfile =~ s/^\Q$prefix//; }
-        print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"crashes/$ppfile\">$ppfile</a></td><td><a href=\"crashes/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
+        print OUT "<tr><td>$problem</td><td>$srcfile</td><td><a href=\"failures/$ppfile\">$ppfile</a></td><td><a href=\"failures/$ppfile.stderr.txt\">$ppfile.stderr.txt</a></td></tr>\n";
         my $ppfile_clang = $ppfile;
         $ppfile_clang =~ s/[.](.+)$/.clang.$1/;
-        print OUT "  <!-- REPORTPROBLEM src=\"$srcfile\" file=\"crashes/$ppfile\" clangfile=\"crashes/$ppfile_clang\" stderr=\"crashes/$ppfile.stderr.txt\" info=\"crashes/$ppfile.info.txt\" -->\n";
+        print OUT "  <!-- REPORTPROBLEM src=\"$srcfile\" file=\"failures/$ppfile\" clangfile=\"failures/$ppfile_clang\" stderr=\"failures/$ppfile.stderr.txt\" info=\"failures/$ppfile.info.txt\" -->\n";
       }
-
-      print OUT <<ENDTEXT;
-</table>
-<p>Please consider submitting preprocessed files as <a href="http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs">bug reports</a>. <!-- REPORTCRASHES --> </p>
-ENDTEXT
-    }
+      print OUT "</table>\n";
+    }    
+    print OUT "<p>Please consider submitting preprocessed files as <a href=\"http://clang.llvm.org/StaticAnalysisUsage.html#filingbugs\">bug reports</a>. <!-- REPORTCRASHES --> </p>\n";
   }
   
   print OUT "</body></html>\n";  
@@ -751,7 +769,7 @@
     Diag("Run 'scan-view $Dir' to examine bug reports.\n");
   }
   
-  DiagCrashes($Dir) if ($Crashes);
+  DiagCrashes($Dir) if (scalar @failures || scalar @attributes_ignored);
   
   return $Num;
 }