90 lines · c
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTIONSPECANALYZER_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTIONSPECANALYZER_H11 12#include "clang/AST/DeclCXX.h"13#include "llvm/ADT/DenseMap.h"14 15namespace clang::tidy::utils {16 17/// This class analysis if a `FunctionDecl` has been declared implicitly through18/// defaulting or explicitly as throwing or not and evaluates noexcept19/// expressions if needed. Unlike the `ExceptionAnalyzer` however it can't tell20/// you if the function will actually throw an exception or not.21class ExceptionSpecAnalyzer {22public:23 enum class State {24 Throwing, ///< This function has been declared as possibly throwing.25 NotThrowing, ///< This function has been declared as not throwing.26 Unknown, ///< We're unable to tell if this function is declared as throwing27 ///< or not.28 };29 30 ExceptionSpecAnalyzer() = default;31 32 State analyze(const FunctionDecl *FuncDecl);33 34private:35 enum class DefaultableMemberKind {36 DefaultConstructor,37 CopyConstructor,38 MoveConstructor,39 CopyAssignment,40 MoveAssignment,41 Destructor,42 43 CompareEqual,44 CompareNotEqual,45 CompareThreeWay,46 CompareRelational,47 48 None,49 };50 51 State analyzeImpl(const FunctionDecl *FuncDecl);52 53 State analyzeUnresolvedOrDefaulted(const CXXMethodDecl *MethodDecl,54 const FunctionProtoType *FuncProto);55 56 State analyzeFieldDecl(const FieldDecl *FDecl, DefaultableMemberKind Kind);57 58 State analyzeBase(const CXXBaseSpecifier &Base, DefaultableMemberKind Kind);59 60 enum class SkipMethods : bool {61 Yes = true,62 No = false,63 };64 65 State analyzeRecord(const CXXRecordDecl *RecordDecl,66 DefaultableMemberKind Kind,67 SkipMethods SkipMethods = SkipMethods::No);68 69 static State analyzeFunctionEST(const FunctionDecl *FuncDecl,70 const FunctionProtoType *FuncProto);71 72 static bool hasTrivialMemberKind(const CXXRecordDecl *RecDecl,73 DefaultableMemberKind Kind);74 75 static bool isConstructor(DefaultableMemberKind Kind);76 77 static bool isSpecialMember(DefaultableMemberKind Kind);78 79 static bool isComparison(DefaultableMemberKind Kind);80 81 static DefaultableMemberKind82 getDefaultableMemberKind(const FunctionDecl *FuncDecl);83 84 llvm::DenseMap<const FunctionDecl *, State> FunctionCache{32U};85};86 87} // namespace clang::tidy::utils88 89#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTIONSPECANALYZER_H90