//===--- ExceptionSpecAnalyzer.h - clang-tidy -------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_SPEC_ANALYZER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_SPEC_ANALYZER_H #include "clang/AST/DeclCXX.h" #include "llvm/ADT/DenseMap.h" namespace clang::tidy::utils { /// This class analysis if a `FunctionDecl` has been declared implicitly through /// defaulting or explicitly as throwing or not and evaluates noexcept /// expressions if needed. Unlike the `ExceptionAnalyzer` however it can't tell /// you if the function will actually throw an exception or not. class ExceptionSpecAnalyzer { public: enum class State { Throwing, ///< This function has been declared as possibly throwing. NotThrowing, ///< This function has been declared as not throwing. Unknown, ///< We're unable to tell if this function is declared as throwing ///< or not. }; ExceptionSpecAnalyzer() = default; State analyze(const FunctionDecl *FuncDecl); private: enum class DefaultableMemberKind { DefaultConstructor, CopyConstructor, MoveConstructor, CopyAssignment, MoveAssignment, Destructor, CompareEqual, CompareNotEqual, CompareThreeWay, CompareRelational, None, }; State analyzeImpl(const FunctionDecl *FuncDecl); State analyzeUnresolvedOrDefaulted(const CXXMethodDecl *MethodDecl, const FunctionProtoType *FuncProto); State analyzeFieldDecl(const FieldDecl *FDecl, DefaultableMemberKind Kind); State analyzeBase(const CXXBaseSpecifier &Base, DefaultableMemberKind Kind); enum class SkipMethods : bool { Yes = true, No = false, }; State analyzeRecord(const CXXRecordDecl *RecordDecl, DefaultableMemberKind Kind, SkipMethods SkipMethods = SkipMethods::No); static State analyzeFunctionEST(const FunctionDecl *FuncDecl, const FunctionProtoType *FuncProto); static bool hasTrivialMemberKind(const CXXRecordDecl *RecDecl, DefaultableMemberKind Kind); static bool isConstructor(DefaultableMemberKind Kind); static bool isSpecialMember(DefaultableMemberKind Kind); static bool isComparison(DefaultableMemberKind Kind); static DefaultableMemberKind getDefaultableMemberKind(const FunctionDecl *FuncDecl); llvm::DenseMap FunctionCache{32U}; }; } // namespace clang::tidy::utils #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_SPEC_ANALYZER_H