11#include "clang/AST/ASTContext.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
14#include "clang/ASTMatchers/ASTMatchers.h"
15#include "llvm/ADT/StringSet.h"
25 if (
Parent->isTranslationUnit())
32 declRefExpr(to(functionDecl().bind(
"func"))).bind(
"use-site"),
this);
40 "__errno_location",
"malloc",
"calloc",
"realloc",
"free",
"aligned_alloc"};
43 const auto *UsageSiteExpr = Result.Nodes.getNodeAs<DeclRefExpr>(
"use-site");
44 const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"func");
47 if (FuncDecl->getBuiltinID() != 0)
53 if (NS && Result.SourceManager->isMacroBodyExpansion(NS->getLocation()) &&
57 const DeclarationName &
Name = FuncDecl->getDeclName();
58 if (
Name.isIdentifier() &&
62 diag(UsageSiteExpr->getBeginLoc(),
63 "%0 must resolve to a function declared "
64 "within the namespace defined by the '%1' macro")
67 diag(FuncDecl->getLocation(),
"resolves to this declaration",
68 clang::DiagnosticIDs::Note);
const FunctionDecl * Decl
llvm::SmallString< 256U > Name
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register AST matchers with Finder.
static const llvm::StringRef RequiredNamespaceStart
const DeclContext * getOutermostNamespace(const DeclContext *Decl)
static const llvm::StringRef RequiredNamespaceMacroName
static const llvm::StringSet IgnoredFunctions