[PATCH] D101788: [AST] AnyCall: Implement arguments().
Artem Dergachev via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Mon May 3 15:10:10 PDT 2021
NoQ created this revision.
NoQ added reviewers: vsavchenko, george.karpenkov, rjmccall.
Herald added a subscriber: martong.
NoQ requested review of this revision.
AnyCall is an interface provided by libAnalysis to polymorphically handle various call-like entities (function calls, Obj-C message expressions, block calls, constructor/destructor invocations, new/delete invocations, etc.) which aren't necessarily related in the AST class hierarchy.
This patch updates it to allow obtaining arguments of any call-like expression.
It also adds a couple of accessor functions in the AST in order to make this possible. The `CXXDeleteExpr`'s `getArgumentAddress()` looks a bit weird out of context but we do seem to have a precedent (`VarDecl::getInitAddress()`).
Repository:
rC Clang
https://reviews.llvm.org/D101788
Files:
clang/include/clang/AST/ExprCXX.h
clang/include/clang/Analysis/AnyCall.h
Index: clang/include/clang/Analysis/AnyCall.h
===================================================================
--- clang/include/clang/Analysis/AnyCall.h
+++ clang/include/clang/Analysis/AnyCall.h
@@ -109,7 +109,7 @@
/// If @c E is a generic call (to ObjC method /function/block/etc),
/// return a constructed @c AnyCall object. Return None otherwise.
- static Optional<AnyCall> forExpr(const Expr *E) {
+ static Optional<AnyCall> forExpr(const Stmt *E) {
if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
return AnyCall(ME);
} else if (const auto *CE = dyn_cast<CallExpr>(E)) {
@@ -161,6 +161,35 @@
size_t param_size() const { return parameters().size(); }
bool param_empty() const { return parameters().empty(); }
+ ArrayRef<const Expr *> arguments() const {
+ if (!E)
+ return None;
+
+ if (const auto *ME = dyn_cast<ObjCMessageExpr>(E)) {
+ return {ME->getArgs(), ME->getNumArgs()};
+ } else if (const auto *CE = dyn_cast<CallExpr>(E)) {
+ return {CE->getArgs(), CE->getNumArgs()};
+ } else if (const auto *CXNE = dyn_cast<CXXNewExpr>(E)) {
+ return {CXNE->getPlacementArgs(), CXNE->getNumPlacementArgs()};
+ } else if (const auto *CXDE = dyn_cast<CXXDeleteExpr>(E)) {
+ // The only argument is the object being deleted.
+ return {reinterpret_cast<Expr *const *>(CXDE->getArgumentAddress()), 1U};
+ } else if (const auto *CXCE = dyn_cast<CXXConstructExpr>(E)) {
+ return {CXCE->getArgs(), CXCE->getNumArgs()};
+ } else if (const auto *CXCIE = dyn_cast<CXXInheritedCtorInitExpr>(E)) {
+ // No argument expressions are synthesized in this case.
+ return None;
+ } else {
+ return None;
+ }
+ }
+
+ using arg_const_iterator = ArrayRef<const Expr *>::const_iterator;
+ arg_const_iterator arg_begin() const { return arguments().begin(); }
+ arg_const_iterator arg_end() const { return arguments().end(); }
+ size_t arg_size() const { return arguments().size(); }
+ bool arg_empty() const { return arguments().empty(); }
+
QualType getReturnType(ASTContext &Ctx) const {
switch (K) {
case Function:
Index: clang/include/clang/AST/ExprCXX.h
===================================================================
--- clang/include/clang/AST/ExprCXX.h
+++ clang/include/clang/AST/ExprCXX.h
@@ -2281,6 +2281,11 @@
placementNewArgsOffset());
}
+ Expr *const *getPlacementArgs() const {
+ return reinterpret_cast<Expr *const *>(getTrailingObjects<Stmt *>() +
+ placementNewArgsOffset());
+ }
+
Expr *getPlacementArg(unsigned I) {
assert((I < getNumPlacementArgs()) && "Index out of range!");
return getPlacementArgs()[I];
@@ -2439,6 +2444,9 @@
Expr *getArgument() { return cast<Expr>(Argument); }
const Expr *getArgument() const { return cast<Expr>(Argument); }
+ /// Retrieve the address of the argument expression.
+ Stmt *const *getArgumentAddress() const { return &Argument; }
+
/// Retrieve the type being destroyed.
///
/// If the type being destroyed is a dependent type which may or may not
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101788.342556.patch
Type: text/x-patch
Size: 3148 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210503/e8c426cb/attachment.bin>
More information about the cfe-commits
mailing list