[llvm] [ADT] Add detection utility for incomplete types (PR #65495)
Jakub Kuderski via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 6 09:29:44 PDT 2023
https://github.com/kuhar updated https://github.com/llvm/llvm-project/pull/65495:
>From 5e2154436fcbd34c91a4305c837fd89a9cbbebcc Mon Sep 17 00:00:00 2001
From: Jakub Kuderski <jakub at nod-labs.com>
Date: Wed, 6 Sep 2023 11:54:05 -0400
Subject: [PATCH] [ADT] Add detection utility for incomplete types
This allows us to produce better error messages for types that were only
forward-declared, but where a full definiton was expected.
The first user will be https://reviews.llvm.org/D159013.
---
llvm/include/llvm/ADT/STLExtras.h | 10 ++++++++++
llvm/unittests/ADT/STLExtrasTest.cpp | 6 ++++++
2 files changed, 16 insertions(+)
diff --git a/llvm/include/llvm/ADT/STLExtras.h b/llvm/include/llvm/ADT/STLExtras.h
index 8f9774d78bd1820..5b926864f0cc4a2 100644
--- a/llvm/include/llvm/ADT/STLExtras.h
+++ b/llvm/include/llvm/ADT/STLExtras.h
@@ -2476,6 +2476,16 @@ bool hasNItemsOrLess(ContainerTy &&C, unsigned N) {
template <class Ptr> auto to_address(const Ptr &P) { return P.operator->(); }
template <class T> constexpr T *to_address(T *P) { return P; }
+// Detect incomplete types, relying on the fact that their size is unknown.
+namespace detail {
+template <typename T> using has_sizeof = decltype(sizeof(T));
+} // namespace detail
+
+/// Detects when type `T` is incomplete. This is true for forward declarations
+/// and false for types with a full definition.
+template <typename T>
+constexpr bool is_incomplete_v = !is_detected<detail::has_sizeof, T>::value;
+
} // end namespace llvm
namespace std {
diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp
index 278447166fc59f4..c34760d83874daf 100644
--- a/llvm/unittests/ADT/STLExtrasTest.cpp
+++ b/llvm/unittests/ADT/STLExtrasTest.cpp
@@ -1300,4 +1300,10 @@ TEST(STLExtrasTest, LessSecond) {
}
}
+struct Foo;
+struct Bar {};
+
+static_assert(is_incomplete_v<Foo>, "Foo is incomplete");
+static_assert(!is_incomplete_v<Bar>, "Bar is defined");
+
} // namespace
More information about the llvm-commits
mailing list