]> granicus.if.org Git - clang/commitdiff
Add clang-cc option '-analyzer-opt-analyze-nested-blocks' to treat block literals...
authorTed Kremenek <kremenek@apple.com>
Mon, 7 Dec 2009 22:06:12 +0000 (22:06 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 7 Dec 2009 22:06:12 +0000 (22:06 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90810 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Driver/CC1Options.td
include/clang/Frontend/AnalysisConsumer.h
lib/Frontend/AnalysisConsumer.cpp
lib/Frontend/CompilerInvocation.cpp

index 582b9c28acc34b07e86bd0499b02b64253bba381..aa4d3bfadccb9fce9d866c857f6eb9d52b492138 100644 (file)
@@ -55,7 +55,7 @@ def analysis_CheckerCFRef : Flag<"-checker-cfref">,
 def analysis_WarnSizeofPointer : Flag<"-warn-sizeof-pointer">,
   HelpText<"Warn about unintended use of sizeof() on pointer expressions">;
 def analysis_InlineCall : Flag<"-inline-call">,
-  HelpText<"Experimental transfer function inling callees when its definition is available.">;
+  HelpText<"Experimental transfer function inlining callees when its definition is available.">;
 
 def analyzer_store : Separate<"-analyzer-store">,
   HelpText<"Source Code Analysis - Abstract Memory Store Models">;
@@ -73,6 +73,8 @@ def analyzer_output_EQ : Joined<"-analyzer-output=">,
 
 def analyzer_opt_analyze_headers : Flag<"-analyzer-opt-analyze-headers">,
   HelpText<"Force the static analyzer to analyze functions defined in header files">;
+def analyzer_opt_analyze_nested_blocks : Flag<"-analyzer-opt-analyze-nested-blocks">,
+  HelpText<"Analyze the definitions of blocks in addition to functions">;  
 def analyzer_display_progress : Flag<"-analyzer-display-progress">,
   HelpText<"Emit verbose output about the analyzer's progress">;
 def analyzer_experimental_checks : Flag<"-analyzer-experimental-checks">,
index 24fed6e76ac118ff3b97aa2a23ef13c9f6d6103f..f55e5dc040552d30e1be40e15ccb068da96197e7 100644 (file)
@@ -62,6 +62,7 @@ public:
   std::string AnalyzeSpecificFunction;
   unsigned AnalyzeAll : 1;
   unsigned AnalyzerDisplayProgress : 1;
+  unsigned AnalyzeNestedBlocks : 1;
   unsigned EagerlyAssume : 1;
   unsigned PurgeDead : 1;
   unsigned TrimGraph : 1;
@@ -76,6 +77,7 @@ public:
     AnalysisDiagOpt = PD_HTML;
     AnalyzeAll = 0;
     AnalyzerDisplayProgress = 0;
+    AnalyzeNestedBlocks = 0;
     EagerlyAssume = 0;
     PurgeDead = 1;
     TrimGraph = 0;
index 5df1eceb885017fb5f334f5cd6ff1cf3827090ec..92f34b21fedc4e87143373aca5b881898da1856e 100644 (file)
@@ -139,14 +139,21 @@ public:
       return;
       
     declDisplayed = true;
-    // FIXME: Is getCodeDecl() always a named decl?
-    if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
-      const NamedDecl *ND = cast<NamedDecl>(D);
-      SourceManager &SM = Mgr->getASTContext().getSourceManager();
-      llvm::errs() << "ANALYZE: "
-        << SM.getPresumedLoc(ND->getLocation()).getFilename()
-        << ' ' << ND->getNameAsString() << '\n';
+    SourceManager &SM = Mgr->getASTContext().getSourceManager();
+    PresumedLoc Loc = SM.getPresumedLoc(D->getLocation());
+    llvm::errs() << "ANALYZE: " << Loc.getFilename();
+
+    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+      assert(isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D));
+      llvm::errs() << ' ' << ND->getNameAsString();
+    }
+    else {
+      assert(isa<BlockDecl>(D));
+      llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
+                   << Loc.getColumn();
     }
+    
+    llvm::errs() << '\n';
   }
 
   void addCodeAction(CodeAction action) {
@@ -269,6 +276,16 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
   Mgr.reset(NULL);
 }
 
+static void FindBlocks(DeclContext *D, llvm::SmallVectorImpl<Decl*> &WL) {
+  if (BlockDecl *BD = dyn_cast<BlockDecl>(D))
+    WL.push_back(BD);
+  
+  for (DeclContext::decl_iterator I = D->decls_begin(), E = D->decls_end();
+       I!=E; ++I)
+    if (DeclContext *DC = dyn_cast<DeclContext>(*I))
+      FindBlocks(DC, WL);
+}
+
 void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
 
   // Don't run the actions if an error has occured with parsing the file.
@@ -285,8 +302,16 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {
   Mgr->ClearContexts();
   
   // Dispatch on the actions.
+  llvm::SmallVector<Decl*, 10> WL;
+  WL.push_back(D);
+  
+  if (Opts.AnalyzeNestedBlocks)
+    FindBlocks(cast<DeclContext>(D), WL);
+  
   for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)
-    (*I)(*this, *Mgr, D);  
+    for (llvm::SmallVectorImpl<Decl*>::iterator WI=WL.begin(), WE=WL.end();
+         WI != WE; ++WI)
+      (*I)(*this, *Mgr, *WI);
 }
 
 //===----------------------------------------------------------------------===//
index 2ecbcfe862e4aa332c5278dd7db4a6da14f5f4e4..1f64e1e7fa71d2a5d5e11c3580043fae10c8db0c 100644 (file)
@@ -31,7 +31,7 @@ using namespace clang;
 static const char *getAnalysisName(Analyses Kind) {
   switch (Kind) {
   default:
-    llvm::llvm_unreachable("Unknown analysis store!");
+    llvm::llvm_unreachable("Unknown analysis kind!");
 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)\
   case NAME: return "-" CMDFLAG;
 #include "clang/Frontend/Analyses.def"
@@ -96,6 +96,8 @@ static void AnalyzerOptsToArgs(const AnalyzerOptions &Opts,
     Res.push_back("-analyzer-opt-analyze-headers");
   if (Opts.AnalyzerDisplayProgress)
     Res.push_back("-analyzer-display-progress");
+  if (Opts.AnalyzeNestedBlocks)
+    Res.push_back("-analyzer-opt-analyze-nested-blocks");
   if (Opts.EagerlyAssume)
     Res.push_back("-analyzer-eagerly-assume");
   if (!Opts.PurgeDead)
@@ -709,6 +711,8 @@ static void ParseAnalyzerArgs(AnalyzerOptions &Opts, ArgList &Args,
   Opts.VisualizeEGUbi = Args.hasArg(OPT_analyzer_viz_egraph_ubigraph);
   Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
   Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
+  Opts.AnalyzeNestedBlocks =
+    Args.hasArg(OPT_analyzer_opt_analyze_nested_blocks);
   Opts.PurgeDead = !Args.hasArg(OPT_analyzer_no_purge_dead);
   Opts.EagerlyAssume = Args.hasArg(OPT_analyzer_eagerly_assume);
   Opts.AnalyzeSpecificFunction = getLastArgValue(Args, OPT_analyze_function);