clang-tools  15.0.0git
PreferRegisterOverUnsignedCheck.cpp
Go to the documentation of this file.
1 //===--- PreferRegisterOverUnsignedCheck.cpp - clang-tidy -----------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 
13 using namespace clang::ast_matchers;
14 
15 namespace clang {
16 namespace tidy {
17 namespace llvm_check {
18 
19 void PreferRegisterOverUnsignedCheck::registerMatchers(MatchFinder *Finder) {
20  auto RegisterClassMatch = hasType(
21  cxxRecordDecl(hasName("::llvm::Register")).bind("registerClassDecl"));
22 
23  Finder->addMatcher(
24  traverse(TK_AsIs,
25  valueDecl(allOf(
26  hasType(qualType(isUnsignedInteger()).bind("varType")),
27  varDecl(hasInitializer(exprWithCleanups(
28  has(implicitCastExpr(has(cxxMemberCallExpr(
29  allOf(on(RegisterClassMatch),
30  has(memberExpr(hasDeclaration(
31  cxxConversionDecl())))))))))))
32  .bind("var")))),
33  this);
34 }
35 
37  const MatchFinder::MatchResult &Result) {
38  const auto *VarType = Result.Nodes.getNodeAs<QualType>("varType");
39  const auto *UserVarDecl = Result.Nodes.getNodeAs<VarDecl>("var");
40 
41  bool NeedsQualification = true;
42  const DeclContext *Context = UserVarDecl->getDeclContext();
43  while (Context) {
44  if (const auto *Namespace = dyn_cast<NamespaceDecl>(Context))
45  if (isa<TranslationUnitDecl>(Namespace->getDeclContext()) &&
46  Namespace->getName() == "llvm")
47  NeedsQualification = false;
48  for (const auto *UsingDirective : Context->using_directives()) {
49  const NamespaceDecl *Namespace = UsingDirective->getNominatedNamespace();
50  if (isa<TranslationUnitDecl>(Namespace->getDeclContext()) &&
51  Namespace->getName() == "llvm")
52  NeedsQualification = false;
53  }
54  Context = Context->getParent();
55  }
56  diag(UserVarDecl->getLocation(),
57  "variable %0 declared as %1; use '%select{|llvm::}2Register' instead")
58  << UserVarDecl << *VarType << NeedsQualification
59  << FixItHint::CreateReplacement(
60  UserVarDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange(),
61  NeedsQualification ? "llvm::Register" : "Register");
62 }
63 
64 } // namespace llvm_check
65 } // namespace tidy
66 } // namespace clang
clang::clangd::check
bool check(llvm::StringRef File, llvm::Optional< Range > LineRange, const ThreadsafeFS &TFS, const ClangdLSPServer::Options &Opts, bool EnableCodeCompletion)
Definition: Check.cpp:273
clang::ast_matchers
Definition: AbseilMatcher.h:14
PreferRegisterOverUnsignedCheck.h
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27