1 //===--- UnnamedNamespaceInHeaderCheck.cpp - clang-tidy ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "UnnamedNamespaceInHeaderCheck.h" 11 #include "clang/AST/ASTContext.h" 12 #include "clang/ASTMatchers/ASTMatchFinder.h" 13 #include "clang/ASTMatchers/ASTMatchers.h" 14 15 using namespace clang::ast_matchers; 16 17 namespace clang { 18 namespace ast_matchers { 19 AST_MATCHER(NamespaceDecl, isAnonymousNamespace) { 20 return Node.isAnonymousNamespace(); 21 } 22 } // namespace ast_matchers 23 24 namespace tidy { 25 namespace build { 26 27 void UnnamedNamespaceInHeaderCheck::registerMatchers( 28 ast_matchers::MatchFinder *Finder) { 29 Finder->addMatcher( 30 namespaceDecl(isAnonymousNamespace()).bind("anonymousNamespace"), this); 31 } 32 33 void 34 UnnamedNamespaceInHeaderCheck::check(const MatchFinder::MatchResult &Result) { 35 SourceManager *SM = Result.SourceManager; 36 const auto *N = Result.Nodes.getNodeAs<NamespaceDecl>("anonymousNamespace"); 37 SourceLocation Loc = N->getLocStart(); 38 if (!Loc.isValid()) 39 return; 40 41 // Look if we're inside a header, check for common suffixes only. 42 // TODO: Allow configuring the set of file extensions. 43 StringRef FileName = SM->getPresumedLoc(Loc).getFilename(); 44 if (FileName.endswith(".h") || FileName.endswith(".hh") || 45 FileName.endswith(".hpp") || FileName.endswith(".hxx")) 46 diag(Loc, "do not use unnamed namespaces in header files."); 47 } 48 49 } // namespace build 50 } // namespace tidy 51 } // namespace clang 52