1 //===--- GlobalNamesInHeadersCheck.cpp - clang-tidy -----------------*- C++ -*-===//
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 "GlobalNamesInHeadersCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
13 #include "clang/Lex/Lexer.h"
15 using namespace clang::ast_matchers
;
17 namespace clang::tidy::google::readability
{
19 GlobalNamesInHeadersCheck::GlobalNamesInHeadersCheck(StringRef Name
,
20 ClangTidyContext
*Context
)
21 : ClangTidyCheck(Name
, Context
),
22 HeaderFileExtensions(Context
->getHeaderFileExtensions()) {}
24 void GlobalNamesInHeadersCheck::registerMatchers(
25 ast_matchers::MatchFinder
*Finder
) {
26 Finder
->addMatcher(decl(anyOf(usingDecl(), usingDirectiveDecl()),
27 hasDeclContext(translationUnitDecl()))
32 void GlobalNamesInHeadersCheck::check(const MatchFinder::MatchResult
&Result
) {
33 const auto *D
= Result
.Nodes
.getNodeAs
<Decl
>("using_decl");
34 // If it comes from a macro, we'll assume it is fine.
35 if (D
->getBeginLoc().isMacroID())
38 // Ignore if it comes from the "main" file ...
39 if (Result
.SourceManager
->isInMainFile(
40 Result
.SourceManager
->getExpansionLoc(D
->getBeginLoc()))) {
41 // unless that file is a header.
42 if (!utils::isSpellingLocInHeaderFile(
43 D
->getBeginLoc(), *Result
.SourceManager
, HeaderFileExtensions
))
47 if (const auto *UsingDirective
= dyn_cast
<UsingDirectiveDecl
>(D
)) {
48 if (UsingDirective
->getNominatedNamespace()->isAnonymousNamespace()) {
49 // Anonymous namespaces inject a using directive into the AST to import
50 // the names into the containing namespace.
51 // We should not have them in headers, but there is another warning for
57 diag(D
->getBeginLoc(),
58 "using declarations in the global namespace in headers are prohibited");
61 } // namespace clang::tidy::google::readability