r278018 - [analyzer] Change -analyze-function to accept qualified names.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 8 09:01:02 PDT 2016


Author: dergachev
Date: Mon Aug  8 11:01:02 2016
New Revision: 278018

URL: http://llvm.org/viewvc/llvm-project?rev=278018&view=rev
Log:
[analyzer] Change -analyze-function to accept qualified names.

Both -analyze-function and -analyzer-display-progress now share the same
convention for naming functions, which allows discriminating between
methods with the same name in different classes, C++ overloads, and also
presents Objective-C instance and class methods in the convenient notation.

This also allows looking up the name for the particular function you're trying
to restrict analysis to in the -analyzer-display-progress output,
in case it was not instantly obvious.

Differential Revision: https://reviews.llvm.org/D22856

Added:
    cfe/trunk/test/Analysis/analyzer-display-progress.cpp
    cfe/trunk/test/Analysis/analyzer-display-progress.m
Removed:
    cfe/trunk/test/Analysis/analyze_display_progress.cpp
Modified:
    cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    cfe/trunk/test/Analysis/analyzeOneFunction.m

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=278018&r1=278017&r2=278018&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Mon Aug  8 11:01:02 2016
@@ -265,19 +265,8 @@ public:
       else
         assert(Mode == (AM_Syntax | AM_Path) && "Unexpected mode!");
 
-      llvm::errs() << ": " << Loc.getFilename();
-      if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
-        const NamedDecl *ND = cast<NamedDecl>(D);
-        llvm::errs() << ' ' << ND->getQualifiedNameAsString() << '\n';
-      }
-      else if (isa<BlockDecl>(D)) {
-        llvm::errs() << ' ' << "block(line:" << Loc.getLine() << ",col:"
-                     << Loc.getColumn() << '\n';
-      }
-      else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
-        Selector S = MD->getSelector();
-        llvm::errs() << ' ' << S.getAsString();
-      }
+      llvm::errs() << ": " << Loc.getFilename() << ' '
+                           << getFunctionName(D) << '\n';
     }
   }
 
@@ -377,6 +366,7 @@ public:
 
 private:
   void storeTopLevelDecls(DeclGroupRef DG);
+  std::string getFunctionName(const Decl *D);
 
   /// \brief Check if we should skip (not analyze) the given function.
   AnalysisMode getModeForDecl(Decl *D, AnalysisMode Mode);
@@ -568,16 +558,64 @@ void AnalysisConsumer::HandleTranslation
 
 }
 
-static std::string getFunctionName(const Decl *D) {
-  if (const ObjCMethodDecl *ID = dyn_cast<ObjCMethodDecl>(D)) {
-    return ID->getSelector().getAsString();
-  }
-  if (const FunctionDecl *ND = dyn_cast<FunctionDecl>(D)) {
-    IdentifierInfo *II = ND->getIdentifier();
-    if (II)
-      return II->getName();
+std::string AnalysisConsumer::getFunctionName(const Decl *D) {
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    OS << FD->getQualifiedNameAsString();
+
+    // In C++, there are overloads.
+    if (Ctx->getLangOpts().CPlusPlus) {
+      OS << '(';
+      for (const auto &P : FD->parameters()) {
+        if (P != *FD->param_begin())
+          OS << ", ";
+        OS << P->getType().getAsString();
+      }
+      OS << ')';
+    }
+
+  } else if (isa<BlockDecl>(D)) {
+    PresumedLoc Loc = Ctx->getSourceManager().getPresumedLoc(D->getLocation());
+
+    if (Loc.isValid()) {
+      OS << "block (line: " << Loc.getLine() << ", col: " << Loc.getColumn()
+         << ')';
+    }
+
+  } else if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(D)) {
+
+    // FIXME: copy-pasted from CGDebugInfo.cpp.
+    OS << (OMD->isInstanceMethod() ? '-' : '+') << '[';
+    const DeclContext *DC = OMD->getDeclContext();
+    if (const auto *OID = dyn_cast<ObjCImplementationDecl>(DC)) {
+      OS << OID->getName();
+    } else if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(DC)) {
+      OS << OID->getName();
+    } else if (const auto *OC = dyn_cast<ObjCCategoryDecl>(DC)) {
+      if (OC->IsClassExtension()) {
+        OS << OC->getClassInterface()->getName();
+      } else {
+        OS << OC->getIdentifier()->getNameStart() << '('
+           << OC->getIdentifier()->getNameStart() << ')';
+      }
+    } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
+      OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
+         << OCD->getIdentifier()->getNameStart() << ')';
+    } else if (isa<ObjCProtocolDecl>(DC)) {
+      // We can extract the type of the class from the self pointer.
+      if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
+        QualType ClassTy =
+            cast<ObjCObjectPointerType>(SelfDecl->getType())->getPointeeType();
+        ClassTy.print(OS, PrintingPolicy(LangOptions()));
+      }
+    }
+    OS << ' ' << OMD->getSelector().getAsString() << ']';
+
   }
-  return "";
+
+  return OS.str();
 }
 
 AnalysisConsumer::AnalysisMode

Modified: cfe/trunk/test/Analysis/analyzeOneFunction.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzeOneFunction.m?rev=278018&r1=278017&r2=278018&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/analyzeOneFunction.m (original)
+++ cfe/trunk/test/Analysis/analyzeOneFunction.m Mon Aug  8 11:01:02 2016
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyze-function="myMethodWithY:withX:" -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
+// RUN: %clang_cc1 -analyze -analyze-function="-[Test1 myMethodWithY:withX:]" -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;

Removed: cfe/trunk/test/Analysis/analyze_display_progress.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyze_display_progress.cpp?rev=278017&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/analyze_display_progress.cpp (original)
+++ cfe/trunk/test/Analysis/analyze_display_progress.cpp (removed)
@@ -1,26 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
-
-void f() {};
-void g() {};
-void h() {}
-
-struct SomeStruct {
-  void f() {}
-};
-
-struct SomeOtherStruct {
-  void f() {}
-};
-
-namespace ns {
-  struct SomeStruct {
-    void f() {}
-  };
-}
-
-// CHECK: analyze_display_progress.cpp f
-// CHECK: analyze_display_progress.cpp g
-// CHECK: analyze_display_progress.cpp h
-// CHECK: analyze_display_progress.cpp SomeStruct::f
-// CHECK: analyze_display_progress.cpp SomeOtherStruct::f
-// CHECK: analyze_display_progress.cpp ns::SomeStruct::f

Added: cfe/trunk/test/Analysis/analyzer-display-progress.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-display-progress.cpp?rev=278018&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/analyzer-display-progress.cpp (added)
+++ cfe/trunk/test/Analysis/analyzer-display-progress.cpp Mon Aug  8 11:01:02 2016
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+
+void f() {};
+void g() {};
+void h() {}
+
+struct SomeStruct {
+  void f() {}
+};
+
+struct SomeOtherStruct {
+  void f() {}
+};
+
+namespace ns {
+  struct SomeStruct {
+    void f(int) {}
+    void f(float, ::SomeStruct) {}
+    void f(float, SomeStruct) {}
+  };
+}
+
+// CHECK: analyzer-display-progress.cpp f()
+// CHECK: analyzer-display-progress.cpp g()
+// CHECK: analyzer-display-progress.cpp h()
+// CHECK: analyzer-display-progress.cpp SomeStruct::f()
+// CHECK: analyzer-display-progress.cpp SomeOtherStruct::f()
+// CHECK: analyzer-display-progress.cpp ns::SomeStruct::f(int)
+// CHECK: analyzer-display-progress.cpp ns::SomeStruct::f(float, ::SomeStruct)
+// CHECK: analyzer-display-progress.cpp ns::SomeStruct::f(float, struct ns::SomeStruct)

Added: cfe/trunk/test/Analysis/analyzer-display-progress.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-display-progress.m?rev=278018&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/analyzer-display-progress.m (added)
+++ cfe/trunk/test/Analysis/analyzer-display-progress.m Mon Aug  8 11:01:02 2016
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fblocks -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+
+#include "Inputs/system-header-simulator-objc.h"
+
+static void f() {}
+
+ at interface I: NSObject
+-(void)instanceMethod:(int)arg1 with:(int)arg2;
++(void)classMethod;
+ at end
+
+ at implementation I
+-(void)instanceMethod:(int)arg1 with:(int)arg2 {}
++(void)classMethod {}
+ at end
+
+void g(I *i, int x, int y) {
+  [I classMethod];
+  [i instanceMethod: x with: y];
+
+  void (^block)(void);
+  block = ^{};
+  block();
+}
+
+// CHECK: analyzer-display-progress.m f
+// CHECK: analyzer-display-progress.m -[I instanceMethod:with:]
+// CHECK: analyzer-display-progress.m +[I classMethod]
+// CHECK: analyzer-display-progress.m g
+// CHECK: analyzer-display-progress.m block (line: 22, col: 11)




More information about the cfe-commits mailing list