1 //===--- PreferRegisterOverUnsignedCheck.cpp - clang-tidy -----------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "PreferRegisterOverUnsignedCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 using namespace clang::ast_matchers
;
15 namespace clang::tidy::llvm_check
{
17 void PreferRegisterOverUnsignedCheck::registerMatchers(MatchFinder
*Finder
) {
18 auto RegisterClassMatch
= hasType(
19 cxxRecordDecl(hasName("::llvm::Register")).bind("registerClassDecl"));
23 valueDecl(hasType(qualType(isUnsignedInteger()).bind("varType")),
24 varDecl(hasInitializer(exprWithCleanups(
25 has(implicitCastExpr(has(cxxMemberCallExpr(
26 on(RegisterClassMatch
),
27 has(memberExpr(hasDeclaration(
28 cxxConversionDecl()))))))))))
33 void PreferRegisterOverUnsignedCheck::check(
34 const MatchFinder::MatchResult
&Result
) {
35 const auto *VarType
= Result
.Nodes
.getNodeAs
<QualType
>("varType");
36 const auto *UserVarDecl
= Result
.Nodes
.getNodeAs
<VarDecl
>("var");
38 bool NeedsQualification
= true;
39 const DeclContext
*Context
= UserVarDecl
->getDeclContext();
41 if (const auto *Namespace
= dyn_cast
<NamespaceDecl
>(Context
))
42 if (isa
<TranslationUnitDecl
>(Namespace
->getDeclContext()) &&
43 Namespace
->getName() == "llvm")
44 NeedsQualification
= false;
45 for (const auto *UsingDirective
: Context
->using_directives()) {
46 const NamespaceDecl
*Namespace
= UsingDirective
->getNominatedNamespace();
47 if (isa
<TranslationUnitDecl
>(Namespace
->getDeclContext()) &&
48 Namespace
->getName() == "llvm")
49 NeedsQualification
= false;
51 Context
= Context
->getParent();
53 diag(UserVarDecl
->getLocation(),
54 "variable %0 declared as %1; use '%select{|llvm::}2Register' instead")
55 << UserVarDecl
<< *VarType
<< NeedsQualification
56 << FixItHint::CreateReplacement(
57 UserVarDecl
->getTypeSourceInfo()->getTypeLoc().getSourceRange(),
58 NeedsQualification
? "llvm::Register" : "Register");
61 } // namespace clang::tidy::llvm_check