10 #include "clang/Frontend/CompilerInstance.h"
11 #include "clang/Lex/PPCallbacks.h"
12 #include "clang/Lex/Preprocessor.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/Support/Regex.h"
20 namespace cppcoreguidelines {
24 bool isCapsOnly(StringRef
Name) {
25 return std::all_of(
Name.begin(),
Name.end(), [](
const char c) {
26 if (std::isupper(c) || std::isdigit(c) || c ==
'_')
34 MacroUsageCallbacks(MacroUsageCheck *Check,
const SourceManager &SM,
35 StringRef RegExp,
bool CapsOnly,
bool IgnoreCommandLine)
36 : Check(Check), SM(SM), RegExp(RegExp), CheckCapsOnly(CapsOnly),
37 IgnoreCommandLineMacros(IgnoreCommandLine) {}
38 void MacroDefined(
const Token &MacroNameTok,
39 const MacroDirective *
MD)
override {
40 if (SM.isWrittenInBuiltinFile(
MD->getLocation()) ||
41 MD->getMacroInfo()->isUsedForHeaderGuard() ||
42 MD->getMacroInfo()->getNumTokens() == 0)
45 if (IgnoreCommandLineMacros &&
46 SM.isWrittenInCommandLineFile(
MD->getLocation()))
49 StringRef MacroName = MacroNameTok.getIdentifierInfo()->getName();
50 if (!CheckCapsOnly && !llvm::Regex(RegExp).
match(MacroName))
51 Check->warnMacro(
MD, MacroName);
53 if (CheckCapsOnly && !isCapsOnly(MacroName))
54 Check->warnNaming(
MD, MacroName);
58 MacroUsageCheck *Check;
59 const SourceManager &SM;
62 bool IgnoreCommandLineMacros;
69 Options.
store(Opts,
"IgnoreCommandLineMacros", IgnoreCommandLineMacros);
74 Preprocessor *ModuleExpanderPP) {
75 PP->addPPCallbacks(std::make_unique<MacroUsageCallbacks>(
76 this, SM, AllowedRegexp, CheckCapsOnly, IgnoreCommandLineMacros));
81 "macro '%0' used to declare a constant; consider using a 'constexpr' "
87 if (
MD->getMacroInfo()->isVariadic())
88 Message =
"variadic macro '%0' used; consider using a 'constexpr' "
89 "variadic template function";
90 else if (
MD->getMacroInfo()->isFunctionLike())
91 Message =
"function-like macro '%0' used; consider a 'constexpr' template "
98 StringRef MacroName) {
99 diag(
MD->getLocation(),
"macro definition does not define the macro name "
100 "'%0' using all uppercase characters")