98 lines · c
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SUSPICIOUSCALLARGUMENTCHECK_H10#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SUSPICIOUSCALLARGUMENTCHECK_H11 12#include "../ClangTidyCheck.h"13#include "llvm/ADT/StringSet.h"14#include <optional>15 16namespace clang::tidy::readability {17 18/// Finds function calls where the arguments passed are provided out of order,19/// based on the difference between the argument name and the parameter names20/// of the function.21///22/// For the user-facing documentation see:23/// https://clang.llvm.org/extra/clang-tidy/checks/readability/suspicious-call-argument.html24class SuspiciousCallArgumentCheck : public ClangTidyCheck {25 enum class Heuristic {26 Equality,27 Abbreviation,28 Prefix,29 Suffix,30 Substring,31 Levenshtein,32 JaroWinkler,33 Dice34 };35 36 /// When applying a heuristic, the value of this enum decides which kind of37 /// bound will be selected from the bounds configured for the heuristic.38 /// This only applies to heuristics that can take bounds.39 enum class BoundKind {40 /// Check for dissimilarity of the names. Names are deemed dissimilar if41 /// the similarity measurement is **below** the configured threshold.42 DissimilarBelow,43 44 /// Check for similarity of the names. Names are deemed similar if the45 /// similarity measurement (the result of heuristic) is **above** the46 /// configured threshold.47 SimilarAbove48 };49 50public:51 static constexpr std::size_t SmallVectorSize = 8;52 static constexpr std::size_t HeuristicCount =53 static_cast<std::size_t>(Heuristic::Dice) + 1;54 55 SuspiciousCallArgumentCheck(StringRef Name, ClangTidyContext *Context);56 void storeOptions(ClangTidyOptions::OptionMap &Opts) override;57 void registerMatchers(ast_matchers::MatchFinder *Finder) override;58 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;59 60private:61 const std::size_t MinimumIdentifierNameLength;62 63 /// The configuration for which heuristics were enabled.64 SmallVector<Heuristic, HeuristicCount> AppliedHeuristics;65 66 /// The lower and upper bounds for each heuristic, as configured by the user.67 SmallVector<std::pair<int8_t, int8_t>, HeuristicCount> ConfiguredBounds;68 69 /// The abbreviation-to-abbreviated map for the Abbreviation heuristic.70 llvm::StringMap<std::string> AbbreviationDictionary;71 72 bool isHeuristicEnabled(Heuristic H) const;73 std::optional<int8_t> getBound(Heuristic H, BoundKind BK) const;74 75 // Runtime information of the currently analyzed function call.76 SmallVector<QualType, SmallVectorSize> ArgTypes;77 SmallVector<StringRef, SmallVectorSize> ArgNames;78 SmallVector<QualType, SmallVectorSize> ParamTypes;79 SmallVector<StringRef, SmallVectorSize> ParamNames;80 81 void setParamNamesAndTypes(const FunctionDecl *CalleeFuncDecl);82 83 void setArgNamesAndTypes(const CallExpr *MatchedCallExpr,84 std::size_t InitialArgIndex);85 86 bool areParamAndArgComparable(std::size_t Position1, std::size_t Position2,87 const ASTContext &Ctx) const;88 89 bool areArgsSwapped(std::size_t Position1, std::size_t Position2) const;90 91 bool areNamesSimilar(StringRef Arg, StringRef Param, Heuristic H,92 BoundKind BK) const;93};94 95} // namespace clang::tidy::readability96 97#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SUSPICIOUSCALLARGUMENTCHECK_H98