Index: clang-tidy/google/UsingNamespaceDirectiveCheck.h =================================================================== --- clang-tidy/google/UsingNamespaceDirectiveCheck.h +++ clang-tidy/google/UsingNamespaceDirectiveCheck.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_USINGNAMESPACEDIRECTIVECHECK_H #include "../ClangTidy.h" +#include "llvm/Support/Regex.h" namespace clang { namespace tidy { @@ -34,10 +35,13 @@ /// Corresponding cpplint.py check name: `build/namespaces`. class UsingNamespaceDirectiveCheck : public ClangTidyCheck { public: - UsingNamespaceDirectiveCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + UsingNamespaceDirectiveCheck(StringRef Name, ClangTidyContext *Context); + void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + llvm::Regex StandardLiteralsNamespaceRE; }; } // namespace build Index: clang-tidy/google/UsingNamespaceDirectiveCheck.cpp =================================================================== --- clang-tidy/google/UsingNamespaceDirectiveCheck.cpp +++ clang-tidy/google/UsingNamespaceDirectiveCheck.cpp @@ -19,6 +19,11 @@ namespace google { namespace build { +UsingNamespaceDirectiveCheck::UsingNamespaceDirectiveCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + StandardLiteralsNamespaceRE("^std::.*literals$") {} + void UsingNamespaceDirectiveCheck::registerMatchers( ast_matchers::MatchFinder *Finder) { // Only register the matchers for C++; the functionality currently does not @@ -34,6 +39,13 @@ if (U->isImplicit() || !Loc.isValid()) return; + if (StandardLiteralsNamespaceRE.match( + U->getNominatedNamespace()->getQualifiedNameAsString())) { + // Do not warn if name matches std::.*literals. User-defined literals in + // standard library can only be used with a using directive. + return; + } + diag(Loc, "do not use namespace using-directives; " "use using-declarations instead"); // TODO: We could suggest a list of using directives replacing the using Index: test/clang-tidy/google-namespaces.cpp =================================================================== --- test/clang-tidy/google-namespaces.cpp +++ test/clang-tidy/google-namespaces.cpp @@ -6,3 +6,31 @@ // CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace] using spaaaace::core; // no-warning + +namespace std { +inline namespace literals { +inline namespace chrono_literals { +} +inline namespace complex_literals { +} +inline namespace string_literals { +} +} +} + +using namespace std::chrono_literals; // no-warning +using namespace std::complex_literals; // no-warning +using namespace std::literals; // no-warning +using namespace std::literals::chrono_literals; // no-warning +using namespace std::literals::complex_literals; // no-warning +using namespace std::literals::string_literals; // no-warning +using namespace std::string_literals; // no-warning + +namespace literals {} +namespace foo::literals {} + +using namespace literals; +// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; Use using-declarations instead [google-build-using-namespace] + +using namespace foo::literals; +// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; Use using-declarations instead [google-build-using-namespace]