1 //=======- PtrTypesSemantics.cpp ---------------------------------*- 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_PTRTYPESEMANTICS_H 10 #define LLVM_CLANG_ANALYZER_WEBKIT_PTRTYPESEMANTICS_H 11 12 #include "llvm/ADT/APInt.h" 13 #include "llvm/ADT/DenseMap.h" 14 #include "llvm/ADT/PointerUnion.h" 15 #include <optional> 16 17 namespace clang { 18 class CXXBaseSpecifier; 19 class CXXMethodDecl; 20 class CXXRecordDecl; 21 class Decl; 22 class FunctionDecl; 23 class Stmt; 24 class Type; 25 26 // Ref-countability of a type is implicitly defined by Ref<T> and RefPtr<T> 27 // implementation. It can be modeled as: type T having public methods ref() and 28 // deref() 29 30 // In WebKit there are two ref-counted templated smart pointers: RefPtr<T> and 31 // Ref<T>. 32 33 /// \returns CXXRecordDecl of the base if the type has ref as a public method, 34 /// nullptr if not, std::nullopt if inconclusive. 35 std::optional<const clang::CXXRecordDecl *> 36 hasPublicMethodInBase(const CXXBaseSpecifier *Base, const char *NameToMatch); 37 38 /// \returns true if \p Class is ref-countable, false if not, std::nullopt if 39 /// inconclusive. 40 std::optional<bool> isRefCountable(const clang::CXXRecordDecl* Class); 41 42 /// \returns true if \p Class is ref-counted, false if not. 43 bool isRefCounted(const clang::CXXRecordDecl *Class); 44 45 /// \returns true if \p Class is ref-countable AND not ref-counted, false if 46 /// not, std::nullopt if inconclusive. 47 std::optional<bool> isUncounted(const clang::CXXRecordDecl* Class); 48 49 /// \returns true if \p T is either a raw pointer or reference to an uncounted 50 /// class, false if not, std::nullopt if inconclusive. 51 std::optional<bool> isUncountedPtr(const clang::Type* T); 52 53 /// \returns true if Name is a RefPtr, Ref, or its variant, false if not. 54 bool isRefType(const std::string &Name); 55 56 /// \returns true if \p F creates ref-countable object from uncounted parameter, 57 /// false if not. 58 bool isCtorOfRefCounted(const clang::FunctionDecl *F); 59 60 /// \returns true if \p F returns a ref-counted object, false if not. 61 bool isReturnValueRefCounted(const clang::FunctionDecl *F); 62 63 /// \returns true if \p M is getter of a ref-counted class, false if not. 64 std::optional<bool> isGetterOfRefCounted(const clang::CXXMethodDecl* Method); 65 66 /// \returns true if \p F is a conversion between ref-countable or ref-counted 67 /// pointer types. 68 bool isPtrConversion(const FunctionDecl *F); 69 70 /// \returns true if \p F is a static singleton function. 71 bool isSingleton(const FunctionDecl *F); 72 73 /// An inter-procedural analysis facility that detects functions with "trivial" 74 /// behavior with respect to reference counting, such as simple field getters. 75 class TrivialFunctionAnalysis { 76 public: 77 /// \returns true if \p D is a "trivial" function. isTrivial(const Decl * D)78 bool isTrivial(const Decl *D) const { return isTrivialImpl(D, TheCache); } isTrivial(const Stmt * S)79 bool isTrivial(const Stmt *S) const { return isTrivialImpl(S, TheCache); } 80 81 private: 82 friend class TrivialFunctionAnalysisVisitor; 83 84 using CacheTy = 85 llvm::DenseMap<llvm::PointerUnion<const Decl *, const Stmt *>, bool>; 86 mutable CacheTy TheCache{}; 87 88 static bool isTrivialImpl(const Decl *D, CacheTy &Cache); 89 static bool isTrivialImpl(const Stmt *S, CacheTy &Cache); 90 }; 91 92 } // namespace clang 93 94 #endif 95