1 //===- AbseilMatcher.h - clang-tidy ---------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "clang/AST/ASTContext.h"
10 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 namespace clang::ast_matchers
{
15 /// Matches AST nodes that were found within Abseil files.
17 /// Example matches Y but not X
18 /// (matcher = cxxRecordDecl(isInAbseilFile())
20 /// #include "absl/strings/internal-file.h"
23 /// absl/strings/internal-file.h:
28 /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc>,
29 /// Matcher<NestedNameSpecifierLoc>
30 AST_POLYMORPHIC_MATCHER(
31 isInAbseilFile
, AST_POLYMORPHIC_SUPPORTED_TYPES(Decl
, Stmt
, TypeLoc
,
32 NestedNameSpecifierLoc
)) {
33 auto &SourceManager
= Finder
->getASTContext().getSourceManager();
34 SourceLocation Loc
= SourceManager
.getSpellingLoc(Node
.getBeginLoc());
37 OptionalFileEntryRef FileEntry
=
38 SourceManager
.getFileEntryRefForID(SourceManager
.getFileID(Loc
));
41 // Determine whether filepath contains "absl/[absl-library]" substring, where
42 // [absl-library] is AbseilLibraries list entry.
43 StringRef Path
= FileEntry
->getName();
44 static constexpr llvm::StringLiteral
AbslPrefix("absl/");
45 size_t PrefixPosition
= Path
.find(AbslPrefix
);
46 if (PrefixPosition
== StringRef::npos
)
48 Path
= Path
.drop_front(PrefixPosition
+ AbslPrefix
.size());
49 static const char *AbseilLibraries
[] = {
50 "algorithm", "base", "container", "debugging", "flags",
51 "hash", "iterator", "memory", "meta", "numeric",
52 "profiling", "random", "status", "strings", "synchronization",
53 "time", "types", "utility"};
54 return llvm::any_of(AbseilLibraries
, [&](const char *Library
) {
55 return Path
.startswith(Library
);
59 } // namespace clang::ast_matchers