1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 */ 9 10 #include <string> 11 #include <set> 12 13 #include "plugin.hxx" 14 15 // Look for places calling std::find on a standard container where it should be using the container find method, which 16 // is more efficient. 17 // 18 // This lives in /store because the implementation is a hack and is highly dependent on the inwards 19 // of the libc++ library on the machine it runs on. 20 // 21 22 namespace { 23 24 class FindOnContainer: 25 public loplugin::FilteringPlugin<FindOnContainer> 26 { 27 public: FindOnContainer(InstantiationData const & data)28 explicit FindOnContainer(InstantiationData const & data): FilteringPlugin(data) {} 29 run()30 virtual void run() override { TraverseDecl(compiler.getASTContext().getTranslationUnitDecl()); } 31 32 bool VisitCallExpr(const CallExpr * expr); 33 }; 34 VisitCallExpr(const CallExpr * expr)35bool FindOnContainer::VisitCallExpr(const CallExpr * expr) { 36 if (ignoreLocation(expr)) { 37 return true; 38 } 39 FunctionDecl const * fdecl = expr->getDirectCallee(); 40 if (fdecl == nullptr) { 41 return true; 42 } 43 std::string qname { fdecl->getQualifiedNameAsString() }; 44 if (qname == "std::find") 45 { 46 std::string tname = expr->getArg(0)->getType().getAsString(); 47 if (tname.find("std::_List_iterator") != std::string::npos 48 || tname.find("std::_List_const_iterator") != std::string::npos 49 || tname.find("std::vector") != std::string::npos 50 || tname.find("std::_Deque_iterator") != std::string::npos 51 || tname == "const int *" 52 || tname == "struct std::_Bit_const_iterator" 53 || tname == "const rtl::OUString *" 54 || tname == "class rtl::OUString *" 55 || tname == "const class rtl::OUString *" 56 || tname == "const sal_Int8 *" 57 || tname == "const sal_Int32 *" 58 || tname == "sal_Int32 *" 59 || tname == "sal_uInt16 *" ) 60 { 61 return true; 62 } 63 expr->dump(); 64 report( 65 DiagnosticsEngine::Warning, 66 ("rather use the more specific find method " + tname), 67 expr->getExprLoc()); 68 return true; 69 } 70 return true; 71 } 72 73 loplugin::Plugin::Registration< FindOnContainer > X("findoncontainer"); 74 75 } 76 77 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 78