10 #include "clang/AST/ASTContext.h" 11 #include "clang/ASTMatchers/ASTMatchFinder.h" 17 namespace llvm_check {
19 void PreferRegisterOverUnsignedCheck::registerMatchers(MatchFinder *Finder) {
20 auto RegisterClassMatch = hasType(
21 cxxRecordDecl(hasName(
"::llvm::Register")).bind(
"registerClassDecl"));
25 hasType(qualType(isUnsignedInteger()).bind(
"varType")),
26 varDecl(hasInitializer(exprWithCleanups(has(implicitCastExpr(has(
27 cxxMemberCallExpr(allOf(on(RegisterClassMatch),
28 has(memberExpr(hasDeclaration(
29 cxxConversionDecl())))))))))))
34 void PreferRegisterOverUnsignedCheck::check(
35 const MatchFinder::MatchResult &Result) {
36 const auto *VarType = Result.Nodes.getNodeAs<QualType>(
"varType");
37 const auto *UserVarDecl = Result.Nodes.getNodeAs<VarDecl>(
"var");
39 StringRef Replacement =
"llvm::Register";
40 const DeclContext *Context = UserVarDecl->getDeclContext();
42 if (
const auto *Namespace = dyn_cast<NamespaceDecl>(Context))
43 if (isa<TranslationUnitDecl>(Namespace->getDeclContext()) &&
44 Namespace->getName() ==
"llvm")
45 Replacement =
"Register";
46 for (
const auto *UsingDirective : Context->using_directives()) {
47 const NamespaceDecl *Namespace = UsingDirective->getNominatedNamespace();
48 if (isa<TranslationUnitDecl>(Namespace->getDeclContext()) &&
49 Namespace->getName() ==
"llvm")
50 Replacement =
"Register";
52 Context = Context->getParent();
54 diag(UserVarDecl->getLocation(),
55 "variable %0 declared as %1; use '%2' instead")
56 << UserVarDecl << *VarType << Replacement
57 << FixItHint::CreateReplacement(
58 UserVarDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange(),
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//