clang-tools  11.0.0
UseNoexceptCheck.cpp
Go to the documentation of this file.
1 //===--- UseNoexceptCheck.cpp - clang-tidy---------------------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "UseNoexceptCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/Lex/Lexer.h"
12 
13 using namespace clang::ast_matchers;
14 
15 namespace clang {
16 namespace tidy {
17 namespace modernize {
18 
19 namespace {
20 AST_MATCHER(NamedDecl, isValid) { return !Node.isInvalidDecl(); }
21 } // namespace
22 
23 UseNoexceptCheck::UseNoexceptCheck(StringRef Name, ClangTidyContext *Context)
24  : ClangTidyCheck(Name, Context),
25  NoexceptMacro(Options.get("ReplacementString", "")),
26  UseNoexceptFalse(Options.get("UseNoexceptFalse", true)) {}
27 
29  Options.store(Opts, "ReplacementString", NoexceptMacro);
30  Options.store(Opts, "UseNoexceptFalse", UseNoexceptFalse);
31 }
32 
33 void UseNoexceptCheck::registerMatchers(MatchFinder *Finder) {
34  Finder->addMatcher(
35  functionDecl(
36  isValid(),
37  hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
38  optionally(cxxMethodDecl(anyOf(hasAnyOverloadedOperatorName(
39  "delete[]", "delete"),
40  cxxDestructorDecl()))
41  .bind("del-dtor")))
42  .bind("funcDecl"),
43  this);
44 
45  Finder->addMatcher(
46  parmVarDecl(anyOf(hasType(pointerType(pointee(parenType(innerType(
47  functionProtoType(hasDynamicExceptionSpec())))))),
48  hasType(memberPointerType(pointee(parenType(innerType(
49  functionProtoType(hasDynamicExceptionSpec()))))))))
50  .bind("parmVarDecl"),
51  this);
52 }
53 
54 void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
55  const FunctionProtoType *FnTy = nullptr;
56  bool DtorOrOperatorDel = false;
57  SourceRange Range;
58 
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())
63  Range =
64  TSI->getTypeLoc().castAs<FunctionTypeLoc>().getExceptionSpecRange();
65  } else if (const auto *ParmDecl =
66  Result.Nodes.getNodeAs<ParmVarDecl>("parmVarDecl")) {
67  FnTy = ParmDecl->getType()
68  ->getAs<Type>()
69  ->getPointeeType()
70  ->getAs<FunctionProtoType>();
71 
72  if (const auto *TSI = ParmDecl->getTypeSourceInfo())
73  Range = TSI->getTypeLoc()
74  .getNextTypeLoc()
75  .IgnoreParens()
76  .castAs<FunctionProtoTypeLoc>()
77  .getExceptionSpecRange();
78  }
79 
80  assert(Range.isValid() && "Exception Source Range is invalid.");
81 
82  CharSourceRange CRange = Lexer::makeFileCharRange(
83  CharSourceRange::getTokenRange(Range), *Result.SourceManager,
84  Result.Context->getLangOpts());
85 
86  assert(FnTy && "FunctionProtoType is null.");
87  bool IsNoThrow = FnTy->isNothrow();
88  StringRef ReplacementStr =
89  IsNoThrow
90  ? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro.c_str()
91  : NoexceptMacro.empty()
92  ? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)"
93  : ""
94  : "";
95 
96  FixItHint FixIt;
97  if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())
98  FixIt = FixItHint::CreateReplacement(CRange, ReplacementStr);
99 
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;
105 }
106 
107 } // namespace modernize
108 } // namespace tidy
109 } // namespace clang
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
UseNoexceptCheck.h
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:114
clang::ast_matchers
Definition: AbseilMatcher.h:14
FixIt
llvm::Optional< FixItHint > FixIt
Definition: UppercaseLiteralSuffixCheck.cpp:62
clang::tidy::modernize::UseNoexceptCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
Definition: UseNoexceptCheck.cpp:33
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:471
clang::tidy::modernize::UseNoexceptCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: UseNoexceptCheck.cpp:54
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:76
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:27
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidyCheck.cpp:55
clang::ast_matchers::AST_MATCHER
AST_MATCHER(Expr, isMacroID)
Definition: PreferIsaOrDynCastInConditionalsCheck.cpp:19
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::modernize::UseNoexceptCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
Definition: UseNoexceptCheck.cpp:28
clang::tidy::ClangTidyCheck::OptionsView::store
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.
Definition: ClangTidyCheck.cpp:152
clang::tidy::ClangTidyOptions::OptionMap
std::map< std::string, ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:111