[libcxx-commits] [libcxx] c8eff95 - [libc++] Add a clang-tidy check to make sure we use _Uglyfied attribute names
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Feb 1 09:57:13 PST 2023
Author: Nikolas Klauser
Date: 2023-02-01T18:57:06+01:00
New Revision: c8eff9560fc1d2462a60bccb560a9ef87a4ba5bb
URL: https://github.com/llvm/llvm-project/commit/c8eff9560fc1d2462a60bccb560a9ef87a4ba5bb
DIFF: https://github.com/llvm/llvm-project/commit/c8eff9560fc1d2462a60bccb560a9ef87a4ba5bb.diff
LOG: [libc++] Add a clang-tidy check to make sure we use _Uglyfied attribute names
Reviewed By: ldionne, #libc
Spies: krytarowski, jdoerfert, libcxx-commits
Differential Revision: https://reviews.llvm.org/D142322
Added:
libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp
libcxx/test/tools/clang_tidy_checks/uglify_attributes.hpp
Modified:
libcxx/include/__config
libcxx/include/__memory/shared_ptr.h
libcxx/include/__memory/unique_ptr.h
libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 40c9deb622951..a4af3f176ec37 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -767,9 +767,9 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
// Deprecations warnings are always enabled, except when users explicitly opt-out
// by defining _LIBCPP_DISABLE_DEPRECATION_WARNINGS.
# if !defined(_LIBCPP_DISABLE_DEPRECATION_WARNINGS)
-# if __has_attribute(deprecated)
-# define _LIBCPP_DEPRECATED __attribute__((deprecated))
-# define _LIBCPP_DEPRECATED_(m) __attribute__((deprecated(m)))
+# if __has_attribute(__deprecated__)
+# define _LIBCPP_DEPRECATED __attribute__((__deprecated__))
+# define _LIBCPP_DEPRECATED_(m) __attribute__((__deprecated__(m)))
# elif _LIBCPP_STD_VER > 11
# define _LIBCPP_DEPRECATED [[deprecated]]
# define _LIBCPP_DEPRECATED_(m) [[deprecated(m)]]
diff --git a/libcxx/include/__memory/shared_ptr.h b/libcxx/include/__memory/shared_ptr.h
index 6bb9ca968dfad..f990612c2c946 100644
--- a/libcxx/include/__memory/shared_ptr.h
+++ b/libcxx/include/__memory/shared_ptr.h
@@ -404,7 +404,7 @@ struct __shared_ptr_deleter_ctor_reqs
};
#if defined(_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI)
-# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
#else
# define _LIBCPP_SHARED_PTR_TRIVIAL_ABI
#endif
diff --git a/libcxx/include/__memory/unique_ptr.h b/libcxx/include/__memory/unique_ptr.h
index 9cdbda8eba409..c50ac4cad4ba7 100644
--- a/libcxx/include/__memory/unique_ptr.h
+++ b/libcxx/include/__memory/unique_ptr.h
@@ -115,7 +115,7 @@ struct __unique_ptr_deleter_sfinae<_Deleter&> {
};
#if defined(_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI)
-# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((trivial_abi))
+# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI __attribute__((__trivial_abi__))
#else
# define _LIBCPP_UNIQUE_PTR_TRIVIAL_ABI
#endif
diff --git a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
index adceee2d8b3c7..2ef102419e2fd 100644
--- a/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
+++ b/libcxx/test/tools/clang_tidy_checks/CMakeLists.txt
@@ -8,8 +8,9 @@ find_package(Clang 16)
set(SOURCES
abi_tag_on_virtual.cpp
hide_from_abi.cpp
- robust_against_adl.cpp
qualify_declval.cpp
+ robust_against_adl.cpp
+ uglify_attributes.cpp
libcpp_module.cpp
)
diff --git a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
index f1dfbf563959e..685d34a86b54a 100644
--- a/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
+++ b/libcxx/test/tools/clang_tidy_checks/libcpp_module.cpp
@@ -13,6 +13,7 @@
#include "hide_from_abi.hpp"
#include "robust_against_adl.hpp"
#include "qualify_declval.hpp"
+#include "uglify_attributes.hpp"
namespace {
class LibcxxTestModule : public clang::tidy::ClangTidyModule {
@@ -21,6 +22,7 @@ class LibcxxTestModule : public clang::tidy::ClangTidyModule {
check_factories.registerCheck<libcpp::abi_tag_on_virtual>("libcpp-avoid-abi-tag-on-virtual");
check_factories.registerCheck<libcpp::hide_from_abi>("libcpp-hide-from-abi");
check_factories.registerCheck<libcpp::robust_against_adl_check>("libcpp-robust-against-adl");
+ check_factories.registerCheck<libcpp::uglify_attributes>("libcpp-uglify-attributes");
check_factories.registerCheck<libcpp::qualify_declval>("libcpp-qualify-declval");
}
};
diff --git a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp
new file mode 100644
index 0000000000000..03b9fe5e4d0f6
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.cpp
@@ -0,0 +1,95 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+#include "clang-tidy/ClangTidyModuleRegistry.h"
+
+#include "uglify_attributes.hpp"
+
+#include <algorithm>
+#include <string_view>
+
+namespace {
+bool isUgly(std::string_view str) {
+ if (str.size() < 2)
+ return false;
+ if (str[0] == '_' && str[1] >= 'A' && str[1] <= 'Z')
+ return true;
+ return str.find("__") != std::string_view::npos;
+}
+
+AST_MATCHER(clang::Attr, isPretty) {
+ if (Node.isKeywordAttribute())
+ return false;
+ if (Node.isCXX11Attribute() && !Node.hasScope()) // TODO: reject standard attributes that are version extensions
+ return false;
+ if (Node.hasScope())
+ if (!isUgly(Node.getScopeName()->getName()))
+ return true;
+
+ if (Node.getAttrName())
+ return !isUgly(Node.getAttrName()->getName());
+
+ return false;
+}
+
+std::optional<std::string> getUglyfiedCXX11Attr(const clang::Attr& attr) {
+ // Don't try to fix attributes with `using` in them.
+ if (std::ranges::search(std::string_view(attr.getSpelling()), std::string_view("::")).empty())
+ return std::nullopt;
+
+ std::string attr_string;
+ if (attr.isClangScope())
+ attr_string += "_Clang::";
+ else if (attr.isGNUScope())
+ attr_string += "__gnu__::";
+
+ if (!attr.getAttrName()->getName().starts_with("__")) {
+ attr_string += "__";
+ attr_string += attr.getAttrName()->getName();
+ attr_string += "__";
+ } else {
+ attr_string += attr.getAttrName()->getName();
+ }
+ return std::move(attr_string);
+}
+
+std::optional<std::string> getUglyfiedGNUAttr(const clang::Attr& attr) {
+ return "__" + attr.getAttrName()->getName().str() + "__";
+}
+
+std::optional<std::string> getUglified(const clang::Attr& attr) {
+ if (attr.isCXX11Attribute()) {
+ return getUglyfiedCXX11Attr(attr);
+ } else if (attr.isGNUAttribute()) {
+ return getUglyfiedGNUAttr(attr);
+ }
+
+ return std::nullopt;
+}
+} // namespace
+
+namespace libcpp {
+uglify_attributes::uglify_attributes(llvm::StringRef name, clang::tidy::ClangTidyContext* context)
+ : clang::tidy::ClangTidyCheck(name, context) {}
+
+void uglify_attributes::registerMatchers(clang::ast_matchers::MatchFinder* finder) {
+ using namespace clang::ast_matchers;
+ finder->addMatcher(attr(isPretty()).bind("normal_attribute"), this);
+}
+
+void uglify_attributes::check(const clang::ast_matchers::MatchFinder::MatchResult& result) {
+ if (const auto* call = result.Nodes.getNodeAs<clang::Attr>("normal_attribute"); call != nullptr) {
+ auto diagnostic = diag(call->getLoc(), "Non-standard attributes should use the _Ugly spelling");
+ auto uglified = getUglified(*call);
+ if (uglified.has_value()) {
+ diagnostic << clang::FixItHint::CreateReplacement(call->getRange(), *uglified);
+ }
+ }
+}
+} // namespace libcpp
diff --git a/libcxx/test/tools/clang_tidy_checks/uglify_attributes.hpp b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.hpp
new file mode 100644
index 0000000000000..a3a06e6703dc5
--- /dev/null
+++ b/libcxx/test/tools/clang_tidy_checks/uglify_attributes.hpp
@@ -0,0 +1,18 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-tidy/ClangTidyCheck.h"
+
+namespace libcpp {
+class uglify_attributes : public clang::tidy::ClangTidyCheck {
+public:
+ uglify_attributes(llvm::StringRef, clang::tidy::ClangTidyContext*);
+ void registerMatchers(clang::ast_matchers::MatchFinder*) override;
+ void check(const clang::ast_matchers::MatchFinder::MatchResult&) override;
+};
+} // namespace libcpp
More information about the libcxx-commits
mailing list