clang  13.0.0git
AnyCall.h
Go to the documentation of this file.
1 //=== AnyCall.h - Abstraction over different callables --------*- C++ -*--//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A utility class for performing generic operations over different callables.
10 //
11 //===----------------------------------------------------------------------===//
12 //
13 #ifndef LLVM_CLANG_ANALYSIS_ANY_CALL_H
14 #define LLVM_CLANG_ANALYSIS_ANY_CALL_H
15 
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/ExprCXX.h"
18 #include "clang/AST/ExprObjC.h"
19 
20 namespace clang {
21 
22 /// An instance of this class corresponds to a call.
23 /// It might be a syntactically-concrete call, done as a part of evaluating an
24 /// expression, or it may be an abstract callee with no associated expression.
25 class AnyCall {
26 public:
27  enum Kind {
28  /// A function, function pointer, or a C++ method call
30 
31  /// A call to an Objective-C method
33 
34  /// A call to an Objective-C block
36 
37  /// An implicit C++ destructor call (called implicitly
38  /// or by operator 'delete')
40 
41  /// An implicit or explicit C++ constructor call
43 
44  /// A C++ inherited constructor produced by a "using T::T" directive
46 
47  /// A C++ allocation function call (operator `new`), via C++ new-expression
49 
50  /// A C++ deallocation function call (operator `delete`), via C++
51  /// delete-expression
53  };
54 
55 private:
56  /// Either expression or declaration (but not both at the same time)
57  /// can be null.
58 
59  /// Call expression, is null when is not known (then declaration is non-null),
60  /// or for implicit destructor calls (when no expression exists.)
61  const Expr *E = nullptr;
62 
63  /// Corresponds to a statically known declaration of the called function,
64  /// or null if it is not known (e.g. for a function pointer).
65  const Decl *D = nullptr;
66  Kind K;
67 
68 public:
69  AnyCall(const CallExpr *CE) : E(CE) {
70  D = CE->getCalleeDecl();
71  K = (CE->getCallee()->getType()->getAs<BlockPointerType>()) ? Block
72  : Function;
73  if (D && ((K == Function && !isa<FunctionDecl>(D)) ||
74  (K == Block && !isa<BlockDecl>(D))))
75  D = nullptr;
76  }
77 
79  : E(ME), D(ME->getMethodDecl()), K(ObjCMethod) {}
80 
82  : E(NE), D(NE->getOperatorNew()), K(Allocator) {}
83 
85  : E(NE), D(NE->getOperatorDelete()), K(Deallocator) {}
86 
88  : E(NE), D(NE->getConstructor()), K(Constructor) {}
89 
91  : E(CIE), D(CIE->getConstructor()), K(InheritedConstructor) {}
92 
93  AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {}
94 
95  AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {}
96 
97  AnyCall(const ObjCMethodDecl *D) : E(nullptr), D(D), K(ObjCMethod) {}
98 
99  AnyCall(const FunctionDecl *D) : E(nullptr), D(D) {
100  if (isa<CXXConstructorDecl>(D)) {
101  K = Constructor;
102  } else if (isa <CXXDestructorDecl>(D)) {
103  K = Destructor;
104  } else {
105  K = Function;
106  }
107 
108  }
109 
110  /// If @c E is a generic call (to ObjC method /function/block/etc),
111  /// return a constructed @c AnyCall object. Return None otherwise.
112  static Optional<AnyCall> forExpr(const Expr *E) {
113  if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
114  return AnyCall(ME);
115  } else if (const auto *CE = dyn_cast<CallExpr>(E)) {
116  return AnyCall(CE);
117  } else if (const auto *CXNE = dyn_cast<CXXNewExpr>(E)) {
118  return AnyCall(CXNE);
119  } else if (const auto *CXDE = dyn_cast<CXXDeleteExpr>(E)) {
120  return AnyCall(CXDE);
121  } else if (const auto *CXCE = dyn_cast<CXXConstructExpr>(E)) {
122  return AnyCall(CXCE);
123  } else if (const auto *CXCIE = dyn_cast<CXXInheritedCtorInitExpr>(E)) {
124  return AnyCall(CXCIE);
125  } else {
126  return None;
127  }
128  }
129 
130  /// If @c D is a callable (Objective-C method or a function), return
131  /// a constructed @c AnyCall object. Return None otherwise.
132  // FIXME: block support.
133  static Optional<AnyCall> forDecl(const Decl *D) {
134  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
135  return AnyCall(FD);
136  } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
137  return AnyCall(MD);
138  }
139  return None;
140  }
141 
142  /// \returns formal parameters for direct calls (including virtual calls)
144  if (!D)
145  return None;
146 
147  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
148  return FD->parameters();
149  } else if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
150  return MD->parameters();
151  } else if (const auto *BD = dyn_cast<BlockDecl>(D)) {
152  return BD->parameters();
153  } else {
154  return None;
155  }
156  }
157 
159  param_const_iterator param_begin() const { return parameters().begin(); }
160  param_const_iterator param_end() const { return parameters().end(); }
161  size_t param_size() const { return parameters().size(); }
162  bool param_empty() const { return parameters().empty(); }
163 
165  switch (K) {
166  case Function:
167  if (E)
168  return cast<CallExpr>(E)->getCallReturnType(Ctx);
169  return cast<FunctionDecl>(D)->getReturnType();
170  case ObjCMethod:
171  if (E)
172  return cast<ObjCMessageExpr>(E)->getCallReturnType(Ctx);
173  return cast<ObjCMethodDecl>(D)->getReturnType();
174  case Block:
175  // FIXME: BlockDecl does not know its return type,
176  // hence the asymmetry with the function and method cases above.
177  return cast<CallExpr>(E)->getCallReturnType(Ctx);
178  case Destructor:
179  case Constructor:
181  case Allocator:
182  case Deallocator:
183  return cast<FunctionDecl>(D)->getReturnType();
184  }
185  llvm_unreachable("Unknown AnyCall::Kind");
186  }
187 
188  /// \returns Function identifier if it is a named declaration,
189  /// @c nullptr otherwise.
190  const IdentifierInfo *getIdentifier() const {
191  if (const auto *ND = dyn_cast_or_null<NamedDecl>(D))
192  return ND->getIdentifier();
193  return nullptr;
194  }
195 
196  const Decl *getDecl() const {
197  return D;
198  }
199 
200  const Expr *getExpr() const {
201  return E;
202  }
203 
204  Kind getKind() const {
205  return K;
206  }
207 
208  void dump() const {
209  if (E)
210  E->dump();
211  if (D)
212  D->dump();
213  }
214 };
215 
216 }
217 
218 #endif // LLVM_CLANG_ANALYSIS_ANY_CALL_H
clang::AnyCall::dump
void dump() const
Definition: AnyCall.h:208
clang::CXXConstructorDecl
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2402
clang::AnyCall::getKind
Kind getKind() const
Definition: AnyCall.h:204
clang::AnyCall::AnyCall
AnyCall(const ObjCMessageExpr *ME)
Definition: AnyCall.h:78
clang::QualType
A (possibly-)qualified type.
Definition: Type.h:668
clang::AnyCall::forDecl
static Optional< AnyCall > forDecl(const Decl *D)
If D is a callable (Objective-C method or a function), return a constructed AnyCall object.
Definition: AnyCall.h:133
clang::CXXNewExpr
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition: ExprCXX.h:2139
llvm::Optional
Definition: LLVM.h:40
clang::Stmt::dump
void dump() const
Dumps the specified AST fragment and all subtrees to llvm::errs().
Definition: ASTDumper.cpp:231
clang::CallExpr::getCalleeDecl
Decl * getCalleeDecl()
Definition: Expr.h:2954
clang::AnyCall::AnyCall
AnyCall(const FunctionDecl *D)
Definition: AnyCall.h:99
Decl.h
clang::AnyCall::Allocator
@ Allocator
A C++ allocation function call (operator new), via C++ new-expression.
Definition: AnyCall.h:48
clang::AnyCall::AnyCall
AnyCall(const CallExpr *CE)
Definition: AnyCall.h:69
clang::CallExpr::getCallee
Expr * getCallee()
Definition: Expr.h:2940
clang::AnyCall::Function
@ Function
A function, function pointer, or a C++ method call.
Definition: AnyCall.h:29
clang::AnyCall::getReturnType
QualType getReturnType(ASTContext &Ctx) const
Definition: AnyCall.h:164
clang::AnyCall
An instance of this class corresponds to a call.
Definition: AnyCall.h:25
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:189
clang::AnyCall::Deallocator
@ Deallocator
A C++ deallocation function call (operator delete), via C++ delete-expression.
Definition: AnyCall.h:52
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7160
clang::AnyCall::AnyCall
AnyCall(const ObjCMethodDecl *D)
Definition: AnyCall.h:97
clang::CXXDestructorDecl
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2668
clang::AnyCall::AnyCall
AnyCall(const CXXConstructorDecl *D)
Definition: AnyCall.h:95
clang::AnyCall::Block
@ Block
A call to an Objective-C block.
Definition: AnyCall.h:35
ExprObjC.h
clang::Decl::dump
void dump() const
Definition: ASTDumper.cpp:186
ExprCXX.h
clang::CXXInheritedCtorInitExpr
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1651
clang::AnyCall::AnyCall
AnyCall(const CXXDeleteExpr *NE)
Definition: AnyCall.h:84
clang::AnyCall::forExpr
static Optional< AnyCall > forExpr(const Expr *E)
If E is a generic call (to ObjC method /function/block/etc), return a constructed AnyCall object.
Definition: AnyCall.h:112
clang::BlockPointerType
Pointer to a block type.
Definition: Type.h:2714
clang::AnyCall::AnyCall
AnyCall(const CXXDestructorDecl *D)
Definition: AnyCall.h:93
clang::AnyCall::getIdentifier
const IdentifierInfo * getIdentifier() const
Definition: AnyCall.h:190
clang::ObjCMessageExpr
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:940
clang::AnyCall::AnyCall
AnyCall(const CXXNewExpr *NE)
Definition: AnyCall.h:81
clang::AnyCall::getDecl
const Decl * getDecl() const
Definition: AnyCall.h:196
clang::CXXDeleteExpr
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition: ExprCXX.h:2398
llvm::ArrayRef
Definition: LLVM.h:34
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::AnyCall::AnyCall
AnyCall(const CXXInheritedCtorInitExpr *CIE)
Definition: AnyCall.h:90
clang::AnyCall::AnyCall
AnyCall(const CXXConstructExpr *NE)
Definition: AnyCall.h:87
clang::AnyCall::parameters
ArrayRef< ParmVarDecl * > parameters() const
Definition: AnyCall.h:143
clang::AnyCall::InheritedConstructor
@ InheritedConstructor
A C++ inherited constructor produced by a "using T::T" directive.
Definition: AnyCall.h:45
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:67
clang::AnyCall::param_end
param_const_iterator param_end() const
Definition: AnyCall.h:160
clang::AnyCall::Destructor
@ Destructor
An implicit C++ destructor call (called implicitly or by operator 'delete')
Definition: AnyCall.h:39
clang::ObjCMethodDecl
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
clang::interp::NE
bool NE(InterpState &S, CodePtr OpPC)
Definition: Interp.h:223
clang
Definition: CalledOnceCheck.h:17
clang::AnyCall::param_size
size_t param_size() const
Definition: AnyCall.h:161
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::AnyCall::param_const_iterator
ArrayRef< ParmVarDecl * >::const_iterator param_const_iterator
Definition: AnyCall.h:158
clang::InheritedConstructor
Description of a constructor that was inherited from a base class.
Definition: DeclCXX.h:2376
clang::AnyCall::ObjCMethod
@ ObjCMethod
A call to an Objective-C method.
Definition: AnyCall.h:32
clang::AnyCall::Constructor
@ Constructor
An implicit or explicit C++ constructor call.
Definition: AnyCall.h:42
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::AnyCall::param_begin
param_const_iterator param_begin() const
Definition: AnyCall.h:159
clang::AnyCall::Kind
Kind
Definition: AnyCall.h:27
clang::FunctionDecl
Represents a function declaration or definition.
Definition: Decl.h:1825
clang::CallExpr
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2790
clang::AnyCall::getExpr
const Expr * getExpr() const
Definition: AnyCall.h:200
clang::CXXConstructExpr
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1460
clang::AnyCall::param_empty
bool param_empty() const
Definition: AnyCall.h:162