1 //===--- UsingNamespaceDirectiveCheck.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 "UsingNamespaceDirectiveCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12 #include "clang/ASTMatchers/ASTMatchers.h"
14 using namespace clang::ast_matchers
;
16 namespace clang::tidy::google::build
{
18 void UsingNamespaceDirectiveCheck::registerMatchers(
19 ast_matchers::MatchFinder
*Finder
) {
20 Finder
->addMatcher(usingDirectiveDecl().bind("usingNamespace"), this);
23 void UsingNamespaceDirectiveCheck::check(
24 const MatchFinder::MatchResult
&Result
) {
25 const auto *U
= Result
.Nodes
.getNodeAs
<UsingDirectiveDecl
>("usingNamespace");
26 SourceLocation Loc
= U
->getBeginLoc();
27 if (U
->isImplicit() || !Loc
.isValid())
30 // Do not warn if namespace is a std namespace with user-defined literals. The
31 // user-defined literals can only be used with a using directive.
32 if (isStdLiteralsNamespace(U
->getNominatedNamespace()))
35 diag(Loc
, "do not use namespace using-directives; "
36 "use using-declarations instead");
37 // TODO: We could suggest a list of using directives replacing the using
38 // namespace directive.
41 bool UsingNamespaceDirectiveCheck::isStdLiteralsNamespace(
42 const NamespaceDecl
*NS
) {
43 if (!NS
->getName().ends_with("literals"))
46 const auto *Parent
= dyn_cast_or_null
<NamespaceDecl
>(NS
->getParent());
50 if (Parent
->isStdNamespace())
53 return Parent
->getName() == "literals" && Parent
->getParent() &&
54 Parent
->getParent()->isStdNamespace();
56 } // namespace clang::tidy::google::build