61 lines · cpp
1//===----------------------------------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "GlobalNamesInHeadersCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11#include "clang/ASTMatchers/ASTMatchers.h"12#include "clang/Lex/Lexer.h"13 14using namespace clang::ast_matchers;15 16namespace clang::tidy::google::readability {17 18GlobalNamesInHeadersCheck::GlobalNamesInHeadersCheck(StringRef Name,19 ClangTidyContext *Context)20 : ClangTidyCheck(Name, Context),21 HeaderFileExtensions(Context->getHeaderFileExtensions()) {}22 23void GlobalNamesInHeadersCheck::registerMatchers(24 ast_matchers::MatchFinder *Finder) {25 Finder->addMatcher(decl(anyOf(usingDecl(), usingDirectiveDecl()),26 hasDeclContext(translationUnitDecl()))27 .bind("using_decl"),28 this);29}30 31void GlobalNamesInHeadersCheck::check(const MatchFinder::MatchResult &Result) {32 const auto *D = Result.Nodes.getNodeAs<Decl>("using_decl");33 // If it comes from a macro, we'll assume it is fine.34 if (D->getBeginLoc().isMacroID())35 return;36 37 // Ignore if it comes from the "main" file ...38 if (Result.SourceManager->isInMainFile(39 Result.SourceManager->getExpansionLoc(D->getBeginLoc()))) {40 // unless that file is a header.41 if (!utils::isSpellingLocInHeaderFile(42 D->getBeginLoc(), *Result.SourceManager, HeaderFileExtensions))43 return;44 }45 46 if (const auto *UsingDirective = dyn_cast<UsingDirectiveDecl>(D)) {47 if (UsingDirective->getNominatedNamespace()->isAnonymousNamespace()) {48 // Anonymous namespaces inject a using directive into the AST to import49 // the names into the containing namespace.50 // We should not have them in headers, but there is another warning for51 // that.52 return;53 }54 }55 56 diag(D->getBeginLoc(),57 "using declarations in the global namespace in headers are prohibited");58}59 60} // namespace clang::tidy::google::readability61