1 //=======- ASTUtis.h ---------------------------------------------*- 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 #ifndef LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H 10 #define LLVM_CLANG_ANALYZER_WEBKIT_ASTUTILS_H 11 12 #include "clang/AST/Decl.h" 13 #include "llvm/ADT/APInt.h" 14 #include "llvm/Support/Casting.h" 15 16 #include <string> 17 #include <utility> 18 19 namespace clang { 20 class CXXRecordDecl; 21 class CXXBaseSpecifier; 22 class FunctionDecl; 23 class CXXMethodDecl; 24 class Expr; 25 26 /// If passed expression is of type uncounted pointer/reference we try to find 27 /// the origin of this pointer. Example: Origin can be a local variable, nullptr 28 /// constant or this-pointer. 29 /// 30 /// Certain subexpression nodes represent transformations that don't affect 31 /// where the memory address originates from. We try to traverse such 32 /// subexpressions to get to the relevant child nodes. Whenever we encounter a 33 /// subexpression that either can't be ignored, we don't model its semantics or 34 /// that has multiple children we stop. 35 /// 36 /// \p E is an expression of uncounted pointer/reference type. 37 /// If \p StopAtFirstRefCountedObj is true and we encounter a subexpression that 38 /// represents ref-counted object during the traversal we return relevant 39 /// sub-expression and true. 40 /// 41 /// \returns subexpression that we traversed to and if \p 42 /// StopAtFirstRefCountedObj is true we also return whether we stopped early. 43 std::pair<const clang::Expr *, bool> 44 tryToFindPtrOrigin(const clang::Expr *E, bool StopAtFirstRefCountedObj); 45 46 /// For \p E referring to a ref-countable/-counted pointer/reference we return 47 /// whether it's a safe call argument. Examples: function parameter or 48 /// this-pointer. The logic relies on the set of recursive rules we enforce for 49 /// WebKit codebase. 50 /// 51 /// \returns Whether \p E is a safe call arugment. 52 bool isASafeCallArg(const clang::Expr *E); 53 54 /// \returns name of AST node or empty string. 55 template <typename T> std::string safeGetName(const T *ASTNode) { 56 const auto *const ND = llvm::dyn_cast_or_null<clang::NamedDecl>(ASTNode); 57 if (!ND) 58 return ""; 59 60 // In case F is for example "operator|" the getName() method below would 61 // assert. 62 if (!ND->getDeclName().isIdentifier()) 63 return ""; 64 65 return ND->getName().str(); 66 } 67 68 } // namespace clang 69 70 #endif 71