brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · 2b7db25 Raw
101 lines · cpp
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#include "UnusedLocalNonTrivialVariableCheck.h"10#include "../utils/Matchers.h"11#include "../utils/OptionsUtils.h"12#include "clang/AST/ASTContext.h"13#include "clang/AST/ASTTypeTraits.h"14#include "clang/AST/Type.h"15#include "clang/ASTMatchers/ASTMatchFinder.h"16#include "clang/ASTMatchers/ASTMatchers.h"17#include "clang/ASTMatchers/ASTMatchersMacros.h"18#include "clang/Basic/LangOptions.h"19 20using namespace clang::ast_matchers;21using namespace clang::tidy::matchers;22 23namespace clang::tidy::bugprone {24 25namespace {26static constexpr StringRef DefaultIncludeTypeRegex =27    "::std::.*mutex;::std::future;::std::basic_string;::std::basic_regex;"28    "::std::basic_istringstream;::std::basic_stringstream;::std::bitset;"29    "::std::filesystem::path";30 31AST_MATCHER(VarDecl, isLocalVarDecl) { return Node.isLocalVarDecl(); }32AST_MATCHER(VarDecl, isReferenced) { return Node.isReferenced(); }33AST_MATCHER(VarDecl, explicitMarkUnused) {34  // Implementations should not emit a warning that a name-independent35  // declaration is used or unused.36  const LangOptions &LangOpts = Finder->getASTContext().getLangOpts();37  return Node.hasAttr<UnusedAttr>() ||38         (LangOpts.CPlusPlus26 && Node.isPlaceholderVar(LangOpts));39}40AST_MATCHER(Type, isReferenceType) { return Node.isReferenceType(); }41AST_MATCHER(QualType, isTrivial) {42  return Node.isTrivialType(Finder->getASTContext()) ||43         Node.isTriviallyCopyableType(Finder->getASTContext());44}45} // namespace46 47UnusedLocalNonTrivialVariableCheck::UnusedLocalNonTrivialVariableCheck(48    StringRef Name, ClangTidyContext *Context)49    : ClangTidyCheck(Name, Context),50      IncludeTypes(utils::options::parseStringList(51          Options.get("IncludeTypes", DefaultIncludeTypeRegex))),52      ExcludeTypes(53          utils::options::parseStringList(Options.get("ExcludeTypes", ""))) {}54 55void UnusedLocalNonTrivialVariableCheck::storeOptions(56    ClangTidyOptions::OptionMap &Opts) {57  Options.store(Opts, "IncludeTypes",58                utils::options::serializeStringList(IncludeTypes));59  Options.store(Opts, "ExcludeTypes",60                utils::options::serializeStringList(ExcludeTypes));61}62 63void UnusedLocalNonTrivialVariableCheck::registerMatchers(MatchFinder *Finder) {64  if (IncludeTypes.empty())65    return;66 67  Finder->addMatcher(68      varDecl(isLocalVarDecl(), unless(isReferenced()),69              unless(isExceptionVariable()), hasLocalStorage(), isDefinition(),70              unless(hasType(isReferenceType())), unless(hasType(isTrivial())),71              unless(explicitMarkUnused()),72              hasType(hasUnqualifiedDesugaredType(73                  anyOf(recordType(hasDeclaration(namedDecl(74                            matchesAnyListedName(IncludeTypes),75                            unless(matchesAnyListedName(ExcludeTypes))))),76                        templateSpecializationType(hasDeclaration(namedDecl(77                            matchesAnyListedName(IncludeTypes),78                            unless(matchesAnyListedName(ExcludeTypes)))))))))79          .bind("var"),80      this);81}82 83void UnusedLocalNonTrivialVariableCheck::check(84    const MatchFinder::MatchResult &Result) {85  const auto *MatchedDecl = Result.Nodes.getNodeAs<VarDecl>("var");86  diag(MatchedDecl->getLocation(), "unused local variable %0 of type %1")87      << MatchedDecl << MatchedDecl->getType();88}89 90bool UnusedLocalNonTrivialVariableCheck::isLanguageVersionSupported(91    const LangOptions &LangOpts) const {92  return LangOpts.CPlusPlus;93}94 95std::optional<TraversalKind>96UnusedLocalNonTrivialVariableCheck::getCheckTraversalKind() const {97  return TK_IgnoreUnlessSpelledInSource;98}99 100} // namespace clang::tidy::bugprone101