| // Part of the Crubit project, under the Apache License v2.0 with LLVM | |
| // Exceptions. See /LICENSE for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| #ifndef CRUBIT_NULLABILITY_POINTER_NULLABILITY_MATCHERS_H_ | |
| #define CRUBIT_NULLABILITY_POINTER_NULLABILITY_MATCHERS_H_ | |
| #include "nullability/type_nullability.h" | |
| #include "clang/AST/Decl.h" | |
| #include "clang/AST/DeclCXX.h" | |
| #include "clang/AST/Expr.h" | |
| #include "clang/AST/ExprCXX.h" | |
| #include "clang/AST/Stmt.h" | |
| #include "clang/AST/TypeBase.h" | |
| #include "clang/ASTMatchers/ASTMatchersInternal.h" | |
| #include "clang/ASTMatchers/ASTMatchersMacros.h" | |
| #include "clang/Basic/LLVM.h" | |
| #include "llvm/ADT/ArrayRef.h" | |
| #include "llvm/ADT/StringRef.h" | |
| namespace clang { | |
| namespace tidy { | |
| namespace nullability { | |
| namespace internal { | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerMethodCallFunc( | |
| llvm::ArrayRef<const llvm::StringRef*> NameRefs); | |
| } // namespace internal | |
| AST_MATCHER(QualType, isSupportedPointer) { | |
| return isSupportedPointerType(Node); | |
| } | |
| AST_MATCHER(QualType, isSupportedRawPointer) { | |
| return isSupportedRawPointerType(Node); | |
| } | |
| AST_MATCHER(QualType, isSupportedSmartPointer) { | |
| return isSupportedSmartPointerType(Node); | |
| } | |
| AST_MATCHER(Expr, isGLValue) { return Node.isGLValue(); } | |
| AST_MATCHER(Stmt, isRawPointerValueInit) { | |
| const auto* ValueInit = dyn_cast<CXXScalarValueInitExpr>(&Node); | |
| return ValueInit != nullptr && | |
| isSupportedRawPointerType(ValueInit->getType()); | |
| } | |
| AST_MATCHER(Stmt, isRawPointerImplicitValueInit) { | |
| const auto* ValueInit = dyn_cast<ImplicitValueInitExpr>(&Node); | |
| return ValueInit != nullptr && | |
| isSupportedRawPointerType(ValueInit->getType()); | |
| } | |
| AST_MATCHER(QualType, isNullPtrType) { return Node->isNullPtrType(); } | |
| ast_matchers::internal::Matcher<Stmt> isPointerExpr(); | |
| ast_matchers::internal::Matcher<Stmt> isMemberOfPointerType(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerArrow(); | |
| ast_matchers::internal::Matcher<Stmt> isNullPointerLiteral(); | |
| ast_matchers::internal::Matcher<Stmt> isAddrOf(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerDereference(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerSubscript(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerCheckBinOp(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerIncOrDec(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerAddOrSubAssign(); | |
| ast_matchers::internal::Matcher<Stmt> isImplicitCastPointerToBool(); | |
| ast_matchers::internal::Matcher<Stmt> isPointerReturn(); | |
| ast_matchers::internal::Matcher<CXXCtorInitializer> isCtorMemberInitializer(); | |
| ast_matchers::internal::Matcher<Stmt> isZeroParamConstMemberCall(); | |
| ast_matchers::internal::Matcher<Stmt> isZeroParamConstMemberOperatorCall(); | |
| ast_matchers::internal::Matcher<Stmt> isNonConstMemberCall(); | |
| ast_matchers::internal::Matcher<Stmt> isNonConstMemberOperatorCall(); | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerArrowMemberExpr(); | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerConstructor(); | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerOperatorCall( | |
| llvm::StringRef Name, int NumArgs); | |
| extern const ast_matchers::internal::VariadicFunction< | |
| ast_matchers::internal::Matcher<Stmt>, llvm::StringRef, | |
| internal::isSmartPointerMethodCallFunc> | |
| isSmartPointerMethodCall; | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerFreeSwapCall(); | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerBoolConversionCall(); | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerFactoryCall(); | |
| ast_matchers::internal::Matcher<Stmt> isWrapUniqueCall(); | |
| ast_matchers::internal::Matcher<Stmt> isSmartPointerComparisonOpCall(); | |
| ast_matchers::internal::Matcher<Stmt> isSharedPtrCastCall(); | |
| ast_matchers::internal::Matcher<Stmt> isWeakPtrLockCall(); | |
| ast_matchers::internal::Matcher<Stmt> isSupportedPointerAccessorCall(); | |
| ast_matchers::internal::Matcher<Stmt> isStatusOrValueOrCall(); | |
| AST_MATCHER(Stmt, isNullPointerDefaultInit) { | |
| const auto* DefaultInit = dyn_cast<CXXDefaultInitExpr>(&Node); | |
| return DefaultInit != nullptr && | |
| isNullPointerLiteral().matches(*DefaultInit->getExpr(), Finder, | |
| Builder); | |
| } | |
| // Checks if the given declaration is within the `absl` namespace. | |
| // Traverses the parent namespaces up to the top-level namespace. | |
| // For example, `absl::nested::f()` is considered within the `absl` namespace. | |
| // The logic is similar to `isDeclaredInAbseilOrUtil()` in the value transferer: | |
| // https://github.com/google/crubit/blob/55767d191778d2a421a229d3fe446a65912c9865/nullability/value_transferer.cc#L882 | |
| // This is unlike `Decl::isInStdNamespace()` | |
| // (https://clang.llvm.org/doxygen/classclang_1_1Decl.html#a066b012f94431b5bba21d19715a274f4), | |
| // which only traverses up inline namespaces | |
| // (https://en.cppreference.com/w/cpp/language/namespace.html#Inline_namespaces) | |
| // and "transparent contexts" such as those induced by unscoped enums | |
| // (https://clang.llvm.org/doxygen/classclang_1_1DeclContext.html#a1d3b0ef59e3e789890485aa141c4712e). | |
| AST_MATCHER(Decl, isInAbslNamespace) { | |
| const DeclContext* DC = Node.getDeclContext(); | |
| if (DC == nullptr || DC->isTranslationUnit()) { | |
| return false; | |
| } | |
| // Traverse the parent namespaces up to the top-level namespace. | |
| while (DC->getParent() != nullptr && !DC->getParent()->isTranslationUnit()) { | |
| DC = DC->getParent(); | |
| } | |
| if (!DC->isNamespace()) { | |
| return false; | |
| } | |
| const NamespaceDecl* ND = cast<NamespaceDecl>(DC); | |
| const IdentifierInfo* II = ND->getIdentifier(); | |
| return II != nullptr && II->isStr("absl"); | |
| } | |
| } // namespace nullability | |
| } // namespace tidy | |
| } // namespace clang | |
| #endif // CRUBIT_NULLABILITY_POINTER_NULLABILITY_MATCHERS_H_ |