UsingNamespaceDirectiveCheck.cpp 1.9 KB

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