1*845618cfSAMS21 //===--- NoexceptFunctionCheck.cpp - clang-tidy ---------------------------===// 2*845618cfSAMS21 // 3*845618cfSAMS21 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*845618cfSAMS21 // See https://llvm.org/LICENSE.txt for license information. 5*845618cfSAMS21 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*845618cfSAMS21 // 7*845618cfSAMS21 //===----------------------------------------------------------------------===// 8*845618cfSAMS21 9*845618cfSAMS21 #include "NoexceptFunctionBaseCheck.h" 10*845618cfSAMS21 #include "../utils/LexerUtils.h" 11*845618cfSAMS21 #include "clang/AST/ASTContext.h" 12*845618cfSAMS21 #include "clang/AST/Decl.h" 13*845618cfSAMS21 #include "clang/ASTMatchers/ASTMatchFinder.h" 14*845618cfSAMS21 15*845618cfSAMS21 using namespace clang::ast_matchers; 16*845618cfSAMS21 17*845618cfSAMS21 namespace clang::tidy::performance { 18*845618cfSAMS21 check(const MatchFinder::MatchResult & Result)19*845618cfSAMS21void NoexceptFunctionBaseCheck::check(const MatchFinder::MatchResult &Result) { 20*845618cfSAMS21 const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(BindFuncDeclName); 21*845618cfSAMS21 assert(FuncDecl); 22*845618cfSAMS21 23*845618cfSAMS21 if (SpecAnalyzer.analyze(FuncDecl) != 24*845618cfSAMS21 utils::ExceptionSpecAnalyzer::State::Throwing) 25*845618cfSAMS21 return; 26*845618cfSAMS21 27*845618cfSAMS21 // Don't complain about nothrow(false), but complain on nothrow(expr) 28*845618cfSAMS21 // where expr evaluates to false. 29*845618cfSAMS21 const auto *ProtoType = FuncDecl->getType()->castAs<FunctionProtoType>(); 30*845618cfSAMS21 const Expr *NoexceptExpr = ProtoType->getNoexceptExpr(); 31*845618cfSAMS21 if (NoexceptExpr) { 32*845618cfSAMS21 NoexceptExpr = NoexceptExpr->IgnoreImplicit(); 33*845618cfSAMS21 if (!isa<CXXBoolLiteralExpr>(NoexceptExpr)) 34*845618cfSAMS21 reportNoexceptEvaluatedToFalse(FuncDecl, NoexceptExpr); 35*845618cfSAMS21 return; 36*845618cfSAMS21 } 37*845618cfSAMS21 38*845618cfSAMS21 auto Diag = reportMissingNoexcept(FuncDecl); 39*845618cfSAMS21 40*845618cfSAMS21 // Add FixIt hints. 41*845618cfSAMS21 const SourceManager &SM = *Result.SourceManager; 42*845618cfSAMS21 43*845618cfSAMS21 const SourceLocation NoexceptLoc = 44*845618cfSAMS21 utils::lexer::getLocationForNoexceptSpecifier(FuncDecl, SM); 45*845618cfSAMS21 if (NoexceptLoc.isValid()) 46*845618cfSAMS21 Diag << FixItHint::CreateInsertion(NoexceptLoc, " noexcept "); 47*845618cfSAMS21 } 48*845618cfSAMS21 49*845618cfSAMS21 } // namespace clang::tidy::performance 50