10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/Frontend/CompilerInstance.h"
13 #include "clang/Lex/MacroInfo.h"
14 #include "clang/Lex/Preprocessor.h"
29 class MacroExpansionsWithFileAndLine :
public PPCallbacks {
31 explicit MacroExpansionsWithFileAndLine(
32 LambdaFunctionNameCheck::SourceRangeSet *SME)
33 : SuppressMacroExpansions(SME) {}
35 void MacroExpands(
const Token &MacroNameTok,
36 const MacroDefinition &
MD, SourceRange
Range,
37 const MacroArgs *Args)
override {
38 bool has_file =
false;
39 bool has_line =
false;
40 for (
const auto& T :
MD.getMacroInfo()->tokens()) {
41 if (T.is(tok::identifier)) {
42 StringRef IdentName = T.getIdentifierInfo()->getName();
43 if (IdentName ==
"__FILE__") {
45 }
else if (IdentName ==
"__LINE__") {
50 if (has_file && has_line) {
51 SuppressMacroExpansions->insert(
Range);
56 LambdaFunctionNameCheck::SourceRangeSet* SuppressMacroExpansions;
61 void LambdaFunctionNameCheck::registerMatchers(MatchFinder *Finder) {
63 Finder->addMatcher(predefinedExpr(hasAncestor(lambdaExpr())).bind(
"E"),
67 void LambdaFunctionNameCheck::registerPPCallbacks(
68 const SourceManager &SM, Preprocessor *
PP, Preprocessor *ModuleExpanderPP) {
69 PP->addPPCallbacks(std::make_unique<MacroExpansionsWithFileAndLine>(
70 &SuppressMacroExpansions));
73 void LambdaFunctionNameCheck::check(
const MatchFinder::MatchResult &Result) {
74 const auto *
E = Result.Nodes.getNodeAs<PredefinedExpr>(
"E");
75 if (
E->getIdentKind() != PredefinedExpr::Func &&
76 E->getIdentKind() != PredefinedExpr::Function) {
80 if (
E->getLocation().isMacroID()) {
82 Result.SourceManager->getImmediateExpansionRange(
E->getLocation());
83 if (SuppressMacroExpansions.find(ER.getAsRange()) !=
84 SuppressMacroExpansions.end()) {
89 diag(
E->getLocation(),
90 "inside a lambda, '%0' expands to the name of the function call "
91 "operator; consider capturing the name of the enclosing function "
93 << PredefinedExpr::getIdentKindName(
E->getIdentKind());