10 #include "clang/AST/ASTContext.h"
11 #include "clang/Lex/Lexer.h"
20 AST_MATCHER(NamedDecl, isValid) {
return !Node.isInvalidDecl(); }
25 NoexceptMacro(Options.get(
"ReplacementString",
"")),
26 UseNoexceptFalse(Options.get(
"UseNoexceptFalse", true)) {}
30 Options.
store(Opts,
"UseNoexceptFalse", UseNoexceptFalse);
37 hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
38 optionally(cxxMethodDecl(anyOf(hasAnyOverloadedOperatorName(
39 "delete[]",
"delete"),
46 parmVarDecl(anyOf(hasType(pointerType(pointee(parenType(innerType(
47 functionProtoType(hasDynamicExceptionSpec())))))),
48 hasType(memberPointerType(pointee(parenType(innerType(
49 functionProtoType(hasDynamicExceptionSpec()))))))))
55 const FunctionProtoType *FnTy =
nullptr;
56 bool DtorOrOperatorDel =
false;
59 if (
const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"funcDecl")) {
60 DtorOrOperatorDel = Result.Nodes.getNodeAs<FunctionDecl>(
"del-dtor");
61 FnTy = FuncDecl->getType()->getAs<FunctionProtoType>();
62 if (
const auto *TSI = FuncDecl->getTypeSourceInfo())
64 TSI->getTypeLoc().castAs<FunctionTypeLoc>().getExceptionSpecRange();
65 }
else if (
const auto *ParmDecl =
66 Result.Nodes.getNodeAs<ParmVarDecl>(
"parmVarDecl")) {
67 FnTy = ParmDecl->getType()
70 ->getAs<FunctionProtoType>();
72 if (
const auto *TSI = ParmDecl->getTypeSourceInfo())
73 Range = TSI->getTypeLoc()
76 .castAs<FunctionProtoTypeLoc>()
77 .getExceptionSpecRange();
80 assert(
Range.isValid() &&
"Exception Source Range is invalid.");
82 CharSourceRange CRange = Lexer::makeFileCharRange(
83 CharSourceRange::getTokenRange(
Range), *Result.SourceManager,
84 Result.Context->getLangOpts());
86 assert(FnTy &&
"FunctionProtoType is null.");
87 bool IsNoThrow = FnTy->isNothrow();
88 StringRef ReplacementStr =
90 ? NoexceptMacro.empty() ?
"noexcept" : NoexceptMacro.c_str()
91 : NoexceptMacro.empty()
92 ? (DtorOrOperatorDel || UseNoexceptFalse) ?
"noexcept(false)"
97 if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())
98 FixIt = FixItHint::CreateReplacement(CRange, ReplacementStr);
100 diag(
Range.getBegin(),
"dynamic exception specification '%0' is deprecated; "
101 "consider %select{using '%2'|removing it}1 instead")
102 << Lexer::getSourceText(CRange, *Result.SourceManager,
103 Result.Context->getLangOpts())
104 << ReplacementStr.empty() << ReplacementStr <<
FixIt;