This revision was automatically updated to reflect the committed changes.
Closed by commit rC352531: Extend AnyCall to handle callable declarations 
without the call expressions (authored by george.karpenkov, committed by ).
Herald added a subscriber: cfe-commits.

Changed prior to commit:
  https://reviews.llvm.org/D57344?vs=183975&id=184138#toc

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57344/new/

https://reviews.llvm.org/D57344

Files:
  include/clang/Analysis/AnyCall.h
  lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp

Index: lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
+++ lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp
@@ -347,7 +347,7 @@
   const Expr *CE = Call.getOriginExpr();
   AnyCall C =
       CE ? *AnyCall::forExpr(CE)
-         : AnyCall::forDestructorCall(cast<CXXDestructorDecl>(Call.getDecl()));
+         : AnyCall(cast<CXXDestructorDecl>(Call.getDecl()));
   return Summaries.getSummary(C, Call.hasNonZeroCallbackArg(),
                               isReceiverUnconsumedSelf(Call), ReceiverType);
 }
Index: include/clang/Analysis/AnyCall.h
===================================================================
--- include/clang/Analysis/AnyCall.h
+++ include/clang/Analysis/AnyCall.h
@@ -19,7 +19,9 @@
 
 namespace clang {
 
-/// An instance of this class corresponds to a 'callable' call.
+/// An instance of this class corresponds to a call.
+/// It might be a syntactically-concrete call, done as a part of evaluating an
+/// expression, or it may be an abstract callee with no associated expression.
 class AnyCall {
 public:
   enum Kind {
@@ -48,7 +50,11 @@
   };
 
 private:
-  /// Call expression, remains null iff the call is an implicit destructor call.
+  /// Either expression or declaration (but not both at the same time)
+  /// can be null.
+
+  /// Call expression, is null when is not known (then declaration is non-null),
+  /// or for implicit destructor calls (when no expression exists.)
   const Expr *E = nullptr;
 
   /// Corresponds to a statically known declaration of the called function,
@@ -56,8 +62,6 @@
   const Decl *D = nullptr;
   Kind K;
 
-  AnyCall(const Expr *E, const Decl *D, Kind K) : E(E), D(D), K(K) {}
-
 public:
   AnyCall(const CallExpr *CE) : E(CE) {
     D = CE->getCalleeDecl();
@@ -80,6 +84,23 @@
   AnyCall(const CXXConstructExpr *NE)
       : E(NE), D(NE->getConstructor()), K(Constructor) {}
 
+  AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {}
+
+  AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {}
+
+  AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {}
+
+  AnyCall(const FunctionDecl *D) : E(nullptr), D(D) {
+    if (isa<CXXConstructorDecl>(D)) {
+      K = Constructor;
+    } else if (isa <CXXDestructorDecl>(D)) {
+      K = Destructor;
+    } else {
+      K = Function;
+    }
+
+  }
+
   /// If {@code E} is a generic call (to ObjC method /function/block/etc),
   /// return a constructed {@code AnyCall} object. Return None otherwise.
   static Optional<AnyCall> forExpr(const Expr *E) {
@@ -98,8 +119,16 @@
     }
   }
 
-  static AnyCall forDestructorCall(const CXXDestructorDecl *D) {
-    return AnyCall(/*E=*/nullptr, D, Destructor);
+  /// If {@code D} is a callable (Objective-C method or a function), return
+  /// a constructed {@code AnyCall} object. Return None otherwise.
+  // FIXME: block support.
+  static Optional<AnyCall> forDecl(const Decl *D) {
+    if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+      return AnyCall(FD);
+    } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
+      return AnyCall(MD);
+    }
+    return None;
   }
 
   /// \returns formal parameters for direct calls (including virtual calls)
@@ -111,8 +140,6 @@
       return FD->parameters();
     } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
       return MD->parameters();
-    } else if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
-      return CD->parameters();
     } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
       return BD->parameters();
     } else {
@@ -129,10 +156,17 @@
   QualType getReturnType(ASTContext &Ctx) const {
     switch (K) {
     case Function:
+      if (E)
+        return cast<CallExpr>(E)->getCallReturnType(Ctx);
+      return cast<FunctionDecl>(D)->getReturnType();
+    case ObjCMethod:
+      if (E)
+        return cast<ObjCMessageExpr>(E)->getCallReturnType(Ctx);
+      return cast<ObjCMethodDecl>(D)->getReturnType();
     case Block:
+      // FIXME: BlockDecl does not know its return type,
+      // hence the asymmetry with the function and method cases above.
       return cast<CallExpr>(E)->getCallReturnType(Ctx);
-    case ObjCMethod:
-      return cast<ObjCMessageExpr>(E)->getCallReturnType(Ctx);
     case Destructor:
     case Constructor:
     case Allocator:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to