[cfe-commits] r102689 - in /cfe/trunk: include/clang/Frontend/Analyses.def lib/Frontend/AnalysisConsumer.cpp test/Analysis/inline.c test/Analysis/inline2.c test/Analysis/inline3.c test/Analysis/inline4.c test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m

Zhongxing Xu xuzhongxing at gmail.com
Thu Apr 29 21:14:20 PDT 2010


Author: zhongxingxu
Date: Thu Apr 29 23:14:20 2010
New Revision: 102689

URL: http://llvm.org/viewvc/llvm-project?rev=102689&view=rev
Log:
Refactor the AnalysisConsumer to analyze functions after the whole 
translation unit is parsed. This enables us to inline some calls when still
analyzing one function at a time.

Actions are classified into Function, CXXMethod, ObjCMethod, 
ObjCImplementation.

This does not hurt performance much. The analysis time for sqlite3.c:

before:
real    17m52.440s
user    17m49.460s
sys    0m2.010s

after:
real    18m0.500s
user    17m56.900s
sys    0m2.330s

DisplayProgress option is broken now. -inine-call action is removed. It
will be reenabled in another form, perhaps as an indenpendant option.

Modified:
    cfe/trunk/include/clang/Frontend/Analyses.def
    cfe/trunk/lib/Frontend/AnalysisConsumer.cpp
    cfe/trunk/test/Analysis/inline.c
    cfe/trunk/test/Analysis/inline2.c
    cfe/trunk/test/Analysis/inline3.c
    cfe/trunk/test/Analysis/inline4.c
    cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m

Modified: cfe/trunk/include/clang/Frontend/Analyses.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Analyses.def?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/Analyses.def (original)
+++ cfe/trunk/include/clang/Frontend/Analyses.def Thu Apr 29 23:14:20 2010
@@ -15,22 +15,21 @@
 #define ANALYSIS(NAME, CMDFLAG, DESC, SCOPE)
 #endif
 
-ANALYSIS(CFGDump, "cfg-dump",
+ANALYSIS(CFGDump, "cfg-dump", 
          "Display Control-Flow Graphs", Code)
 
-ANALYSIS(CFGView, "cfg-view",
+ANALYSIS(CFGView, "cfg-view", 
          "View Control-Flow Graphs using GraphViz", Code)
 
 ANALYSIS(DisplayLiveVariables, "dump-live-variables",
          "Print results of live variable analysis", Code)
 
 ANALYSIS(SecuritySyntacticChecks, "analyzer-check-security-syntactic",
-         "Perform quick security checks that require no data flow",
-         Code)
+         "Perform quick security checks that require no data flow", Code)
 
 ANALYSIS(LLVMConventionChecker, "analyzer-check-llvm-conventions",
-  "Check code for LLVM codebase conventions (domain-specific)",
-  TranslationUnit)
+         "Check code for LLVM codebase conventions (domain-specific)", 
+         TranslationUnit)
 
 ANALYSIS(WarnDeadStores, "analyzer-check-dead-stores",
          "Warn about stores to dead variables", Code)
@@ -39,15 +38,15 @@
          "Warn about uses of uninitialized variables", Code)
 
 ANALYSIS(WarnObjCMethSigs, "analyzer-check-objc-methodsigs",
- "Warn about Objective-C method signatures with type incompatibilities",
- ObjCImplementation)
+         "Warn about Objective-C method signatures with type incompatibilities",
+         ObjCImplementation)
 
 ANALYSIS(WarnObjCDealloc, "analyzer-check-objc-missing-dealloc",
- "Warn about Objective-C classes that lack a correct implementation of -dealloc",
- ObjCImplementation)
+"Warn about Objective-C classes that lack a correct implementation of -dealloc",
+         ObjCImplementation)
  
 ANALYSIS(WarnObjCUnusedIvars, "analyzer-check-objc-unused-ivars",
-  "Warn about private ivars that are never used", ObjCImplementation)
+         "Warn about private ivars that are never used", ObjCImplementation)
 
 ANALYSIS(ObjCMemChecker, "analyzer-check-objc-mem",
          "Run the [Core] Foundation reference count checker", Code)
@@ -55,10 +54,6 @@
 ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer",
          "Warn about unintended use of sizeof() on pointer expressions", Code)
 
-ANALYSIS(InlineCall, "inline-call",
-         "Experimental transfer function inling callees when its definition"
-         " is available.", TranslationUnit)
-
 #ifndef ANALYSIS_STORE
 #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN)
 #endif

Modified: cfe/trunk/lib/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/AnalysisConsumer.cpp?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/Frontend/AnalysisConsumer.cpp Thu Apr 29 23:14:20 2010
@@ -62,20 +62,21 @@
 
 namespace {
 
- class AnalysisConsumer : public ASTConsumer {
- public:
+class AnalysisConsumer : public ASTConsumer {
+public:
   typedef void (*CodeAction)(AnalysisConsumer &C, AnalysisManager &M, Decl *D);
   typedef void (*TUAction)(AnalysisConsumer &C, AnalysisManager &M,
                            TranslationUnitDecl &TU);
 
- private:
+private:
   typedef std::vector<CodeAction> Actions;
   typedef std::vector<TUAction> TUActions;
 
   Actions FunctionActions;
   Actions ObjCMethodActions;
   Actions ObjCImplementationActions;
-  TUActions TranslationUnitActions;
+  Actions CXXMethodActions;
+  TUActions TranslationUnitActions; // Remove this.
 
 public:
   ASTContext* Ctx;
@@ -161,16 +162,17 @@
   void addCodeAction(CodeAction action) {
     FunctionActions.push_back(action);
     ObjCMethodActions.push_back(action);
-  }
-
-  void addObjCImplementationAction(CodeAction action) {
-    ObjCImplementationActions.push_back(action);
+    CXXMethodActions.push_back(action);
   }
 
   void addTranslationUnitAction(TUAction action) {
     TranslationUnitActions.push_back(action);
   }
 
+  void addObjCImplementationAction(CodeAction action) {
+    ObjCImplementationActions.push_back(action);
+  }
+
   virtual void Initialize(ASTContext &Context) {
     Ctx = &Context;
     Mgr.reset(new AnalysisManager(*Ctx, PP.getDiagnostics(),
@@ -182,16 +184,8 @@
                                   Opts.TrimGraph));
   }
 
-  virtual void HandleTopLevelDecl(DeclGroupRef D) {
-    declDisplayed = false;
-    for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
-      HandleTopLevelSingleDecl(*I);
-  }
-
-  void HandleTopLevelSingleDecl(Decl *D);
   virtual void HandleTranslationUnit(ASTContext &C);
-
-  void HandleCode(Decl* D, Stmt* Body, Actions& actions);
+  void HandleCode(Decl *D, Stmt* Body, Actions& actions);
 };
 } // end anonymous namespace
 
@@ -208,57 +202,69 @@
 // AnalysisConsumer implementation.
 //===----------------------------------------------------------------------===//
 
-void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {
-  switch (D->getKind()) {
-  case Decl::CXXConstructor:
-  case Decl::CXXDestructor:
-  case Decl::CXXConversion:
-  case Decl::CXXMethod:
-  case Decl::Function: {
-    FunctionDecl* FD = cast<FunctionDecl>(D);
-    if (!Opts.AnalyzeSpecificFunction.empty() &&
-        FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
-        break;
-
-    if (Stmt *Body = FD->getBody())
-      HandleCode(FD, Body, FunctionActions);
-    break;
-  }
-
-  case Decl::ObjCMethod: {
-    ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
 
-    if (!Opts.AnalyzeSpecificFunction.empty() &&
-        Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
-      return;
+  TranslationUnitDecl *TU = C.getTranslationUnitDecl();
 
-    if (Stmt* Body = MD->getBody())
-      HandleCode(MD, Body, ObjCMethodActions);
-    break;
-  }
+  for (DeclContext::decl_iterator I = TU->decls_begin(), E = TU->decls_end();
+       I != E; ++I) {
+    Decl *D = *I;
+
+    switch (D->getKind()) {
+    case Decl::CXXConstructor:
+    case Decl::CXXDestructor:
+    case Decl::CXXConversion:
+    case Decl::CXXMethod:
+    case Decl::Function: {
+      FunctionDecl* FD = cast<FunctionDecl>(D);
+      
+      if (FD->isThisDeclarationADefinition()) {
+        if (!Opts.AnalyzeSpecificFunction.empty() &&
+            FD->getDeclName().getAsString() != Opts.AnalyzeSpecificFunction)
+          break;
+        HandleCode(FD, FD->getBody(), FunctionActions);
+      }
+      break;
+    }
 
-  default:
-    break;
-  }
-}
+    case Decl::ObjCMethod: {
+      ObjCMethodDecl* MD = cast<ObjCMethodDecl>(D);
+      
+      if (MD->isThisDeclarationADefinition()) {
+        if (!Opts.AnalyzeSpecificFunction.empty() &&
+            Opts.AnalyzeSpecificFunction != MD->getSelector().getAsString())
+          break;
+        HandleCode(MD, MD->getBody(), ObjCMethodActions);
+      }
+      break;
+    }
 
-void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
+    case Decl::ObjCImplementation: {
+      ObjCImplementationDecl* ID = cast<ObjCImplementationDecl>(*I);
+      HandleCode(ID, 0, ObjCImplementationActions);
+
+      for (ObjCImplementationDecl::method_iterator MI = ID->meth_begin(), 
+             ME = ID->meth_end(); MI != ME; ++MI) {
+        if ((*MI)->isThisDeclarationADefinition()) {
+          if (!Opts.AnalyzeSpecificFunction.empty() &&
+             Opts.AnalyzeSpecificFunction != (*MI)->getSelector().getAsString())
+            break;
+          HandleCode(*MI, (*MI)->getBody(), ObjCMethodActions);
+        }
+      }
+      break;
+    }
 
-  TranslationUnitDecl *TU = C.getTranslationUnitDecl();
+    default:
+      break;
+    }
+  }
 
   for (TUActions::iterator I = TranslationUnitActions.begin(),
                            E = TranslationUnitActions.end(); I != E; ++I) {
     (*I)(*this, *Mgr, *TU);
   }
 
-  if (!ObjCImplementationActions.empty()) {
-    for (DeclContext::decl_iterator I = TU->decls_begin(),
-                                    E = TU->decls_end();
-         I != E; ++I)
-      if (ObjCImplementationDecl* ID = dyn_cast<ObjCImplementationDecl>(*I))
-        HandleCode(ID, 0, ObjCImplementationActions);
-  }
-
   // Explicitly destroy the PathDiagnosticClient.  This will flush its output.
   // FIXME: This should be replaced with something that doesn't rely on
   // side-effects in PathDiagnosticClient's destructor. This is required when
@@ -311,7 +317,6 @@
 static void ActionWarnDeadStores(AnalysisConsumer &C, AnalysisManager& mgr,
                                  Decl *D) {
   if (LiveVariables *L = mgr.getLiveVariables(D)) {
-    C.DisplayFunction(D);
     BugReporter BR(mgr);
     CheckDeadStores(*mgr.getCFG(D), *L, mgr.getParentMap(D), BR);
   }
@@ -320,7 +325,6 @@
 static void ActionWarnUninitVals(AnalysisConsumer &C, AnalysisManager& mgr,
                                  Decl *D) {
   if (CFG* c = mgr.getCFG(D)) {
-    C.DisplayFunction(D);
     CheckUninitializedValues(*c, mgr.getASTContext(), mgr.getDiagnostic());
   }
 }
@@ -332,15 +336,11 @@
 
   llvm::OwningPtr<GRTransferFuncs> TF(tf);
 
-  // Display progress.
-  C.DisplayFunction(D);
-
   // Construct the analysis engine.  We first query for the LiveVariables
   // information to see if the CFG is valid.
   // FIXME: Inter-procedural analysis will need to handle invalid CFGs.
   if (!mgr.getLiveVariables(D))
     return;
-
   GRExprEngine Eng(mgr, TF.take());
 
   if (C.Opts.EnableExperimentalInternalChecks)
@@ -407,28 +407,24 @@
 static void ActionDisplayLiveVariables(AnalysisConsumer &C,
                                        AnalysisManager& mgr, Decl *D) {
   if (LiveVariables* L = mgr.getLiveVariables(D)) {
-    C.DisplayFunction(D);
     L->dumpBlockLiveness(mgr.getSourceManager());
   }
 }
 
 static void ActionCFGDump(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
   if (CFG *cfg = mgr.getCFG(D)) {
-    C.DisplayFunction(D);
     cfg->dump(mgr.getLangOptions());
   }
 }
 
 static void ActionCFGView(AnalysisConsumer &C, AnalysisManager& mgr, Decl *D) {
   if (CFG *cfg = mgr.getCFG(D)) {
-    C.DisplayFunction(D);
     cfg->viewCFG(mgr.getLangOptions());
   }
 }
 
 static void ActionSecuritySyntacticChecks(AnalysisConsumer &C,
                                           AnalysisManager &mgr, Decl *D) {
-  C.DisplayFunction(D);
   BugReporter BR(mgr);
   CheckSecuritySyntaxOnly(D, BR);
 }
@@ -444,86 +440,28 @@
                                   Decl *D) {
   if (mgr.getLangOptions().getGCMode() == LangOptions::GCOnly)
     return;
-
-  C.DisplayFunction(D);
   BugReporter BR(mgr);
   CheckObjCDealloc(cast<ObjCImplementationDecl>(D), mgr.getLangOptions(), BR);
 }
 
 static void ActionWarnObjCUnusedIvars(AnalysisConsumer &C, AnalysisManager& mgr,
                                       Decl *D) {
-  C.DisplayFunction(D);
   BugReporter BR(mgr);
   CheckObjCUnusedIvar(cast<ObjCImplementationDecl>(D), BR);
 }
 
 static void ActionWarnObjCMethSigs(AnalysisConsumer &C, AnalysisManager& mgr,
                                    Decl *D) {
-  C.DisplayFunction(D);
   BugReporter BR(mgr);
   CheckObjCInstMethSignature(cast<ObjCImplementationDecl>(D), BR);
 }
 
 static void ActionWarnSizeofPointer(AnalysisConsumer &C, AnalysisManager &mgr,
                                     Decl *D) {
-  C.DisplayFunction(D);
   BugReporter BR(mgr);
   CheckSizeofPointer(D, BR);
 }
 
-static void ActionInlineCall(AnalysisConsumer &C, AnalysisManager &mgr,
-                             TranslationUnitDecl &TU) {
-
-  // Find the entry function definition (if any).
-  FunctionDecl *D = 0;
-
-  // Must specify an entry function.
-  if (!C.Opts.AnalyzeSpecificFunction.empty()) {
-    for (DeclContext::decl_iterator I=TU.decls_begin(), E=TU.decls_end();
-         I != E; ++I) {
-      if (FunctionDecl *fd = dyn_cast<FunctionDecl>(*I))
-        if (fd->isThisDeclarationADefinition() &&
-            fd->getNameAsString() == C.Opts.AnalyzeSpecificFunction) {
-          D = fd;
-          break;
-        }
-    }
-  }
-
-  if (!D)
-    return;
-
-
-  // FIXME: This is largely copy of ActionGRExprEngine. Needs cleanup.
-  // Display progress.
-  C.DisplayFunction(D);
-
-  // FIXME: Make a fake transfer function. The GRTransferFunc interface
-  // eventually will be removed.
-  GRExprEngine Eng(mgr, new GRTransferFuncs());
-
-  if (C.Opts.EnableExperimentalInternalChecks)
-    RegisterExperimentalInternalChecks(Eng);
-
-  RegisterAppleChecks(Eng, *D);
-
-  if (C.Opts.EnableExperimentalChecks)
-    RegisterExperimentalChecks(Eng);
-
-  // Register call inliner as the last checker.
-  RegisterCallInliner(Eng);
-
-  // Execute the worklist algorithm.
-  Eng.ExecuteWorkList(mgr.getStackFrame(D));
-
-  // Visualize the exploded graph.
-  if (mgr.shouldVisualizeGraphviz())
-    Eng.ViewGraph(mgr.shouldTrimGraph());
-
-  // Display warnings.
-  Eng.getBugReporter().FlushReports();
-}
-
 //===----------------------------------------------------------------------===//
 // AnalysisConsumer creation.
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/test/Analysis/inline.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline.c?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline.c (original)
+++ cfe/trunk/test/Analysis/inline.c Thu Apr 29 23:14:20 2010
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
-
+// RUN: false
+// XFAIL: *
 int f1() {
   int y = 1;
   y++;

Modified: cfe/trunk/test/Analysis/inline2.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline2.c?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline2.c (original)
+++ cfe/trunk/test/Analysis/inline2.c Thu Apr 29 23:14:20 2010
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
+// RUN: false
+// XFAIL: *
 
 // Test parameter 'a' is registered to LiveVariables analysis data although it
 // is not referenced in the function body. 

Modified: cfe/trunk/test/Analysis/inline3.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline3.c?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline3.c (original)
+++ cfe/trunk/test/Analysis/inline3.c Thu Apr 29 23:14:20 2010
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f2 -verify %s
-
+// RUN: false
+// XFAIL: *
 
 // Test when entering f1(), we set the right AnalysisContext to Environment.
 // Otherwise, block-level expr '1 && a' would not be block-level.

Modified: cfe/trunk/test/Analysis/inline4.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inline4.c?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inline4.c (original)
+++ cfe/trunk/test/Analysis/inline4.c Thu Apr 29 23:14:20 2010
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -inline-call -analyzer-store region -analyze-function f -verify %s
-
+// RUN: false
+// XFAIL: *
 int g(int a) {    
   return a;
 }

Modified: cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m?rev=102689&r1=102688&r2=102689&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m (original)
+++ cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m Thu Apr 29 23:14:20 2010
@@ -72,11 +72,11 @@
 int marker(void) { // control reaches end of non-void function
 }
 
+// CHECK-darwin8: control reaches end of non-void function
 // CHECK-darwin8: warning: The receiver of message 'longDoubleM' is nil and returns a value of type 'long double' that will be garbage
 // CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
 // CHECK-darwin8: warning: The receiver of message 'doubleM' is nil and returns a value of type 'double' that will be garbage
 // CHECK-darwin8: warning: The receiver of message 'longlongM' is nil and returns a value of type 'long long' that will be garbage
-// CHECK-darwin8: control reaches end of non-void function
 // CHECK-darwin8: 5 warnings generated
 // CHECK-darwin9: control reaches end of non-void function
 // CHECK-darwin9: 1 warning generated





More information about the cfe-commits mailing list