summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-tidy
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-tidy')
-rw-r--r--clang-tools-extra/clang-tidy/modernize/CMakeLists.txt1
-rw-r--r--clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp2
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp114
-rw-r--r--clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h49
4 files changed, 166 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index b2f45b65727..8058f52343c 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -22,6 +22,7 @@ add_clang_library(clangTidyModernizeModule
UseEmplaceCheck.cpp
UseEqualsDefaultCheck.cpp
UseEqualsDeleteCheck.cpp
+ UseNoexceptCheck.cpp
UseNullptrCheck.cpp
UseOverrideCheck.cpp
UseTransparentFunctorsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index de027249d2d..f8c50e0c439 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -28,6 +28,7 @@
#include "UseEmplaceCheck.h"
#include "UseEqualsDefaultCheck.h"
#include "UseEqualsDeleteCheck.h"
+#include "UseNoexceptCheck.h"
#include "UseNullptrCheck.h"
#include "UseOverrideCheck.h"
#include "UseTransparentFunctorsCheck.h"
@@ -69,6 +70,7 @@ public:
CheckFactories.registerCheck<UseEqualsDefaultCheck>("modernize-use-equals-default");
CheckFactories.registerCheck<UseEqualsDeleteCheck>(
"modernize-use-equals-delete");
+ CheckFactories.registerCheck<UseNoexceptCheck>("modernize-use-noexcept");
CheckFactories.registerCheck<UseNullptrCheck>("modernize-use-nullptr");
CheckFactories.registerCheck<UseOverrideCheck>("modernize-use-override");
CheckFactories.registerCheck<UseTransparentFunctorsCheck>(
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp
new file mode 100644
index 00000000000..e32aef92143
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.cpp
@@ -0,0 +1,114 @@
+//===--- UseNoexceptCheck.cpp - clang-tidy---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseNoexceptCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+UseNoexceptCheck::UseNoexceptCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ NoexceptMacro(Options.get("ReplacementString", "")),
+ UseNoexceptFalse(Options.get("UseNoexceptFalse", true)) {}
+
+void UseNoexceptCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "ReplacementString", NoexceptMacro);
+ Options.store(Opts, "UseNoexceptFalse", UseNoexceptFalse);
+}
+
+void UseNoexceptCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus11)
+ return;
+
+ Finder->addMatcher(
+ functionDecl(
+ cxxMethodDecl(
+ hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
+ anyOf(hasOverloadedOperatorName("delete[]"),
+ hasOverloadedOperatorName("delete"), cxxDestructorDecl()))
+ .bind("del-dtor"))
+ .bind("funcDecl"),
+ this);
+
+ Finder->addMatcher(
+ functionDecl(
+ hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
+ unless(anyOf(hasOverloadedOperatorName("delete[]"),
+ hasOverloadedOperatorName("delete"),
+ cxxDestructorDecl())))
+ .bind("funcDecl"),
+ this);
+
+ Finder->addMatcher(
+ parmVarDecl(anyOf(hasType(pointerType(pointee(parenType(innerType(
+ functionProtoType(hasDynamicExceptionSpec())))))),
+ hasType(memberPointerType(pointee(parenType(innerType(
+ functionProtoType(hasDynamicExceptionSpec()))))))))
+ .bind("parmVarDecl"),
+ this);
+}
+
+void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
+ const FunctionProtoType *FnTy = nullptr;
+ bool DtorOrOperatorDel = false;
+ SourceRange Range;
+
+ if (const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("funcDecl")) {
+ DtorOrOperatorDel = Result.Nodes.getNodeAs<FunctionDecl>("del-dtor");
+ FnTy = FuncDecl->getType()->getAs<FunctionProtoType>();
+ if (const auto *TSI = FuncDecl->getTypeSourceInfo())
+ Range =
+ TSI->getTypeLoc().castAs<FunctionTypeLoc>().getExceptionSpecRange();
+ } else if (const auto *ParmDecl =
+ Result.Nodes.getNodeAs<ParmVarDecl>("parmVarDecl")) {
+ FnTy = ParmDecl->getType()
+ ->getAs<Type>()
+ ->getPointeeType()
+ ->getAs<FunctionProtoType>();
+
+ if (const auto *TSI = ParmDecl->getTypeSourceInfo())
+ Range = TSI->getTypeLoc()
+ .getNextTypeLoc()
+ .IgnoreParens()
+ .castAs<FunctionProtoTypeLoc>()
+ .getExceptionSpecRange();
+ }
+ CharSourceRange CRange = Lexer::makeFileCharRange(
+ CharSourceRange::getTokenRange(Range), *Result.SourceManager,
+ Result.Context->getLangOpts());
+
+ assert(FnTy && "FunctionProtoType is null.");
+ bool IsNoThrow = FnTy->isNothrow(*Result.Context);
+ StringRef ReplacementStr =
+ IsNoThrow
+ ? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro.c_str()
+ : NoexceptMacro.empty()
+ ? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)"
+ : ""
+ : "";
+
+ FixItHint FixIt;
+ if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())
+ FixIt = FixItHint::CreateReplacement(CRange, ReplacementStr);
+
+ diag(Range.getBegin(), "dynamic exception specification '%0' is deprecated; "
+ "consider %select{using '%2'|removing it}1 instead")
+ << Lexer::getSourceText(CRange, *Result.SourceManager,
+ Result.Context->getLangOpts())
+ << ReplacementStr.empty() << ReplacementStr << FixIt;
+}
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
diff --git a/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h
new file mode 100644
index 00000000000..4fbd0bdde07
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseNoexceptCheck.h
@@ -0,0 +1,49 @@
+//===--- UseNoexceptCheck.h - clang-tidy-------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// \brief Replace dynamic exception specifications, with
+/// `noexcept` (or user-defined macro) or `noexcept(false)`.
+/// \code
+/// void foo() throw();
+/// void bar() throw(int);
+/// \endcode
+/// Is converted to:
+/// \code
+/// void foo() ;
+// void bar() noexcept(false);
+/// \endcode
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-noexcept.html
+class UseNoexceptCheck : public ClangTidyCheck {
+public:
+ UseNoexceptCheck(StringRef Name, ClangTidyContext *Context);
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ const std::string NoexceptMacro;
+ bool UseNoexceptFalse;
+};
+
+} // namespace modernize
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_NOEXCEPT_H
OpenPOWER on IntegriCloud