10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 12 #include "clang/Tooling/FixIt.h" 18 namespace performance {
20 void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) {
23 if (!getLangOpts().CPlusPlus11)
27 cxxMethodDecl(anyOf(cxxConstructorDecl(), hasOverloadedOperatorName(
"=")),
28 unless(isImplicit()), unless(isDeleted()))
33 void NoexceptMoveConstructorCheck::check(
34 const MatchFinder::MatchResult &Result) {
35 if (
const auto *
Decl = Result.Nodes.getNodeAs<CXXMethodDecl>(
"decl")) {
36 StringRef MethodType =
"assignment operator";
37 if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(
Decl)) {
38 if (!Ctor->isMoveConstructor())
40 MethodType =
"constructor";
41 }
else if (!
Decl->isMoveAssignmentOperator()) {
45 const auto *ProtoType =
Decl->getType()->getAs<FunctionProtoType>();
47 if (isUnresolvedExceptionSpec(ProtoType->getExceptionSpecType()))
50 if (!isNoexceptExceptionSpec(ProtoType->getExceptionSpecType())) {
52 diag(
Decl->getLocation(),
"move %0s should be marked noexcept")
55 SourceManager &SM = *Result.SourceManager;
56 assert(
Decl->getNumParams() > 0);
57 SourceLocation NoexceptLoc =
Decl->getParamDecl(
Decl->getNumParams() - 1)
60 if (NoexceptLoc.isValid())
61 NoexceptLoc = Lexer::findLocationAfterToken(
62 NoexceptLoc, tok::r_paren, SM, Result.Context->getLangOpts(),
true);
63 if (NoexceptLoc.isValid())
64 Diag << FixItHint::CreateInsertion(NoexceptLoc,
" noexcept ");
70 if (ProtoType->canThrow() == CT_Can) {
71 Expr *
E = ProtoType->getNoexceptExpr();
72 E = E->IgnoreImplicit();
73 if (!isa<CXXBoolLiteralExpr>(E)) {
75 "noexcept specifier on the move %0 evaluates to 'false'")
const FunctionDecl * Decl
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//