10#include "clang/AST/ASTContext.h"
11#include "clang/Lex/Lexer.h"
23 NoexceptMacro(Options.get(
"ReplacementString",
"")),
24 UseNoexceptFalse(Options.get(
"UseNoexceptFalse", true)) {}
28 Options.
store(Opts,
"UseNoexceptFalse", UseNoexceptFalse);
35 hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
36 optionally(cxxMethodDecl(anyOf(hasAnyOverloadedOperatorName(
37 "delete[]",
"delete"),
44 parmVarDecl(anyOf(hasType(pointerType(pointee(parenType(innerType(
45 functionProtoType(hasDynamicExceptionSpec())))))),
46 hasType(memberPointerType(pointee(parenType(innerType(
47 functionProtoType(hasDynamicExceptionSpec()))))))))
53 const FunctionProtoType *FnTy =
nullptr;
54 bool DtorOrOperatorDel =
false;
57 if (
const auto *
FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"funcDecl")) {
58 DtorOrOperatorDel = Result.Nodes.getNodeAs<FunctionDecl>(
"del-dtor");
59 FnTy =
FuncDecl->getType()->getAs<FunctionProtoType>();
60 if (
const auto *TSI =
FuncDecl->getTypeSourceInfo())
62 TSI->getTypeLoc().castAs<FunctionTypeLoc>().getExceptionSpecRange();
63 }
else if (
const auto *ParmDecl =
64 Result.Nodes.getNodeAs<ParmVarDecl>(
"parmVarDecl")) {
65 FnTy = ParmDecl->getType()
68 ->getAs<FunctionProtoType>();
70 if (
const auto *TSI = ParmDecl->getTypeSourceInfo())
71 Range = TSI->getTypeLoc()
74 .castAs<FunctionProtoTypeLoc>()
75 .getExceptionSpecRange();
78 assert(FnTy &&
"FunctionProtoType is null.");
79 if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
82 assert(
Range.isValid() &&
"Exception Source Range is invalid.");
84 CharSourceRange CRange = Lexer::makeFileCharRange(
85 CharSourceRange::getTokenRange(
Range), *Result.SourceManager,
86 Result.Context->getLangOpts());
88 bool IsNoThrow = FnTy->isNothrow();
89 StringRef ReplacementStr =
90 IsNoThrow ? NoexceptMacro.empty() ?
"noexcept" : NoexceptMacro
91 : NoexceptMacro.empty()
92 ? (DtorOrOperatorDel || UseNoexceptFalse) ?
"noexcept(false)" :
""
96 if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())
97 FixIt = FixItHint::CreateReplacement(CRange, ReplacementStr);
99 diag(
Range.getBegin(),
"dynamic exception specification '%0' is deprecated; "
100 "consider %select{using '%2'|removing it}1 instead")
101 << Lexer::getSourceText(CRange, *Result.SourceManager,
102 Result.Context->getLangOpts())
103 << ReplacementStr.empty() << ReplacementStr <<
FixIt;
llvm::SmallString< 256U > Name
CharSourceRange Range
SourceRange for the file name.
::clang::DynTypedNode Node
std::optional< FixItHint > FixIt
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
Base class for all clang-tidy checks.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
UseNoexceptCheck(StringRef Name, ClangTidyContext *Context)
AST_MATCHER(Decl, declHasNoReturnAttr)
matches a Decl if it has a "no return" attribute of any kind
static bool isValid(SourceRange Range)
llvm::StringMap< ClangTidyValue > OptionMap
static constexpr const char FuncDecl[]