11 #include "clang/AST/ASTContext.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Frontend/CompilerInstance.h"
14 #include "clang/Lex/MacroInfo.h"
15 #include "clang/Lex/Preprocessor.h"
17 using namespace clang::ast_matchers;
30 class MacroExpansionsWithFileAndLine :
public PPCallbacks {
32 explicit MacroExpansionsWithFileAndLine(
33 LambdaFunctionNameCheck::SourceRangeSet *SME)
36 void MacroExpands(
const Token &MacroNameTok,
37 const MacroDefinition &MD, SourceRange
Range,
38 const MacroArgs *Args)
override {
39 bool has_file =
false;
40 bool has_line =
false;
41 for (
const auto& T : MD.getMacroInfo()->tokens()) {
42 if (T.is(tok::identifier)) {
43 StringRef IdentName = T.getIdentifierInfo()->getName();
44 if (IdentName ==
"__FILE__") {
46 }
else if (IdentName ==
"__LINE__") {
51 if (has_file && has_line) {
62 void LambdaFunctionNameCheck::registerMatchers(MatchFinder *
Finder) {
64 Finder->addMatcher(predefinedExpr(hasAncestor(lambdaExpr())).bind(
"E"),
68 void LambdaFunctionNameCheck::registerPPCallbacks(CompilerInstance &Compiler) {
69 Compiler.getPreprocessor().addPPCallbacks(
70 llvm::make_unique<MacroExpansionsWithFileAndLine>(
74 void LambdaFunctionNameCheck::check(
const MatchFinder::MatchResult &Result) {
75 const auto *E = Result.Nodes.getNodeAs<PredefinedExpr>(
"E");
76 if (E->getIdentType() != PredefinedExpr::Func &&
77 E->getIdentType() != PredefinedExpr::Function) {
81 if (E->getLocation().isMacroID()) {
83 Result.SourceManager->getImmediateExpansionRange(E->getLocation());
90 diag(E->getLocation(),
91 "inside a lambda, '%0' expands to the name of the function call "
92 "operator; consider capturing the name of the enclosing function "
94 << PredefinedExpr::getIdentTypeName(E->getIdentType());
LambdaFunctionNameCheck::SourceRangeSet * SuppressMacroExpansions
std::unique_ptr< ast_matchers::MatchFinder > Finder
CharSourceRange Range
SourceRange for the file name.