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