hugoeg updated this revision to Diff 162864.
hugoeg marked 2 inline comments as done.
hugoeg added a comment.
made some major updates after no-namespace landed
https://reviews.llvm.org/D50542
Files:
clang-tidy/abseil/AbseilTidyModule.cpp
clang-tidy/abseil/CMakeLists.txt
clang-tidy/abseil/NoInternalDepsCheck.cpp
clang-tidy/abseil/NoInternalDepsCheck.h
docs/ReleaseNotes.rst
docs/clang-tidy/checks/abseil-no-internal-deps.rst
docs/clang-tidy/checks/list.rst
test/clang-tidy/Inputs/absl/external-file.h
test/clang-tidy/Inputs/absl/strings/internal-file.h
test/clang-tidy/abseil-no-internal-deps.cpp
test/clang-tidy/abseil-no-namespace.cpp
Index: test/clang-tidy/abseil-no-namespace.cpp
===================================================================
--- test/clang-tidy/abseil-no-namespace.cpp
+++ test/clang-tidy/abseil-no-namespace.cpp
@@ -7,7 +7,7 @@
/// Warning will be triggered on code that is not internal that is included.
#include "absl/external-file.h"
-// CHECK: absl/external-file.h:1:11: warning: namespace 'absl' is reserved
+// CHECK: absl/external-file.h:3:11: warning: namespace 'absl' is reserved
namespace absl {}
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: namespace 'absl' is reserved for implementation of the Abseil library and should not be opened in user code [abseil-no-namespace]
Index: test/clang-tidy/abseil-no-internal-deps.cpp
===================================================================
--- test/clang-tidy/abseil-no-internal-deps.cpp
+++ test/clang-tidy/abseil-no-internal-deps.cpp
@@ -0,0 +1,39 @@
+// RUN: %check_clang_tidy %s abseil-no-internal-deps %t, -- -- -I %S/Inputs
+// RUN: clang-tidy -checks='-*, abseil-no-internal-deps' -header-filter='.*' %s -- -I %S/Inputs 2>&1 | FileCheck %s
+
+#include "absl/strings/internal-file.h"
+// CHECK-NOT: warning:
+
+#include "absl/external-file.h"
+// CHECK: absl/external-file.h:1:23: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil [abseil-no-internal-deps]
+
+void DirectAcess() {
+ absl::strings_internal::InternalFunction();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+
+ absl::strings_internal::InternalTemplateFunction<std::string>("a");
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+}
+
+class FriendUsage {
+ friend struct absl::container_internal::InternalStruct;
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+};
+
+namespace absl {
+void OpeningNamespace() {
+ strings_internal::InternalFunction();
+ // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not reference any 'internal' namespaces; those implementation details are reserved to Abseil
+}
+} // namespace absl
+
+// should not trigger warnings
+void CorrectUsage() {
+ std::string Str = absl::StringsFunction("a");
+ absl::SomeContainer b;
+}
+
+namespace absl {
+SomeContainer b;
+std::string Str = absl::StringsFunction("a");
+} // namespace absl
Index: test/clang-tidy/Inputs/absl/strings/internal-file.h
===================================================================
--- test/clang-tidy/Inputs/absl/strings/internal-file.h
+++ test/clang-tidy/Inputs/absl/strings/internal-file.h
@@ -1 +1,34 @@
-namespace absl {}
+namespace std {
+struct string {
+ string(const char *);
+ ~string();
+};
+} // namespace std
+
+namespace absl {
+std::string StringsFunction(std::string s1) { return s1; }
+class SomeContainer {};
+namespace strings_internal {
+void InternalFunction() {}
+template <class P> P InternalTemplateFunction(P a) {}
+} // namespace strings_internal
+
+namespace container_internal {
+struct InternalStruct {};
+} // namespace container_internal
+} // namespace absl
+
+// should not trigger warnings because inside Abseil files
+void DirectAcessInternal() {
+ absl::strings_internal::InternalFunction();
+ absl::strings_internal::InternalTemplateFunction<std::string>("a");
+}
+
+class FriendUsageInternal {
+ friend struct absl::container_internal::InternalStruct;
+};
+
+namespace absl {
+void OpeningNamespaceInternally() { strings_internal::InternalFunction(); }
+} // namespace absl
+
Index: test/clang-tidy/Inputs/absl/external-file.h
===================================================================
--- test/clang-tidy/Inputs/absl/external-file.h
+++ test/clang-tidy/Inputs/absl/external-file.h
@@ -1 +1,3 @@
+void DirectAcess2() { absl::strings_internal::InternalFunction(); }
+
namespace absl {}
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
.. toctree::
abseil-duration-division
abseil-faster-strsplit-delimiter
+ abseil-no-internal-deps
abseil-no-namespace
abseil-string-find-startswith
android-cloexec-accept
Index: docs/clang-tidy/checks/abseil-no-internal-deps.rst
===================================================================
--- docs/clang-tidy/checks/abseil-no-internal-deps.rst
+++ docs/clang-tidy/checks/abseil-no-internal-deps.rst
@@ -0,0 +1,24 @@
+subl.. title:: clang-tidy - abseil-no-internal-deps
+
+abseil-no-internal-deps
+=======================
+
+Warns if code using Abseil depends on internal details. If something is in a
+namespace that includes the word “internal”, code is not allowed to depend upon
+it beaucse it’s an implementation detail. They cannot friend it, include it,
+you mention it or refer to it in any way. Doing so violates Abseil's
+compatibility guidelines and may result in breakage. See
+https://abseil.io/about/compatibility for more information.
+
+The following cases will result in warnings:
+
+.. code-block:: c++
+
+ absl::strings_internal::foo();
+ // warning triggered on this line
+ class foo {
+ friend struct absl::container_internal::faa;
+ // warning triggered on this line
+ };
+ absl::memory_internal::MakeUniqueResult();
+ // warning triggered on this line
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -60,6 +60,11 @@
- New :doc:`abseil-duration-division
<clang-tidy/checks/abseil-duration-division>` check.
+- New :doc:`abseil-no-internal-deps
+ <clang-tidy/checks/abseil-no-internal-deps>` check.
+
+ Gives a warning if code using Abseil depends on internal details.
+
Checks for uses of ``absl::Duration`` division that is done in a
floating-point context, and recommends the use of a function that
returns a floating-point value.
Index: clang-tidy/abseil/NoInternalDepsCheck.h
===================================================================
--- clang-tidy/abseil/NoInternalDepsCheck.h
+++ clang-tidy/abseil/NoInternalDepsCheck.h
@@ -0,0 +1,37 @@
+//===--- NoInternalDepsCheck.h - clang-tidy----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NOINTERNALDEPSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NOINTERNALDEPSCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+/// Finds instances where the user depends on internal details and warns them
+/// against doing so.Should not run on internal Abseil files or Abseil source
+/// code.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-no-internal-deps.html
+class NoInternalDepsCheck : public ClangTidyCheck {
+public:
+ NoInternalDepsCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_NOINTERNALDEPSCHECK_H
Index: clang-tidy/abseil/NoInternalDepsCheck.cpp
===================================================================
--- clang-tidy/abseil/NoInternalDepsCheck.cpp
+++ clang-tidy/abseil/NoInternalDepsCheck.cpp
@@ -0,0 +1,48 @@
+//===--- NoInternalDepsCheck.cpp - clang-tidy------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NoInternalDepsCheck.h"
+#include "AbseilMatcher.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace abseil {
+
+void NoInternalDepsCheck::registerMatchers(MatchFinder *Finder) {
+ if (!getLangOpts().CPlusPlus)
+ return;
+
+ // TODO: refactor matcher to be configurable or just match on any internal
+ // access from outside the enclosing namespace.
+
+ Finder->addMatcher(
+ nestedNameSpecifierLoc(loc(specifiesNamespace(namespaceDecl(
+ matchesName("internal"),
+ hasParent(namespaceDecl(hasName("absl")))))),
+ unless(isInAbseilFile()))
+ .bind("InternalDep"),
+ this);
+}
+
+void NoInternalDepsCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *InternalDependency =
+ Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("InternalDep");
+
+ diag(InternalDependency->getBeginLoc(),
+ "do not reference any 'internal' namespaces; those implementation "
+ "details are reserved to Abseil");
+}
+
+} // namespace abseil
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/abseil/CMakeLists.txt
===================================================================
--- clang-tidy/abseil/CMakeLists.txt
+++ clang-tidy/abseil/CMakeLists.txt
@@ -4,6 +4,7 @@
AbseilTidyModule.cpp
DurationDivisionCheck.cpp
FasterStrsplitDelimiterCheck.cpp
+ NoInternalDepsCheck.cpp
NoNamespaceCheck.cpp
StringFindStartswithCheck.cpp
Index: clang-tidy/abseil/AbseilTidyModule.cpp
===================================================================
--- clang-tidy/abseil/AbseilTidyModule.cpp
+++ clang-tidy/abseil/AbseilTidyModule.cpp
@@ -12,6 +12,7 @@
#include "../ClangTidyModuleRegistry.h"
#include "DurationDivisionCheck.h"
#include "FasterStrsplitDelimiterCheck.h"
+#include "NoInternalDepsCheck.h"
#include "NoNamespaceCheck.h"
#include "StringFindStartswithCheck.h"
@@ -26,6 +27,8 @@
"abseil-duration-division");
CheckFactories.registerCheck<FasterStrsplitDelimiterCheck>(
"abseil-faster-strsplit-delimiter");
+ CheckFactories.registerCheck<NoInternalDepsCheck>(
+ "abseil-no-internal-deps");
CheckFactories.registerCheck<NoNamespaceCheck>("abseil-no-namespace");
CheckFactories.registerCheck<StringFindStartswithCheck>(
"abseil-string-find-startswith");
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits