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