From 2e3d694018fc9d33c0ed0f9e341f72fba224e410 Mon Sep 17 00:00:00 2001 From: Jakub Kuderski Date: Wed, 6 Sep 2023 14:06:40 -0400 Subject: [PATCH] [ADT] Add detection utility for incomplete types (#65495) This allows us to produce better error messages for types that were only forward-declared, but where a full definition was expected. The first user will be https://reviews.llvm.org/D159013; this change is sent to review separately to reduce the scope of the other patch. --- 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 8f9774d78bd1..5b926864f0cc 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 auto to_address(const Ptr &P) { return P.operator->(); } template constexpr T *to_address(T *P) { return P; } +// Detect incomplete types, relying on the fact that their size is unknown. +namespace detail { +template 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 +constexpr bool is_incomplete_v = !is_detected::value; + } // end namespace llvm namespace std { diff --git a/llvm/unittests/ADT/STLExtrasTest.cpp b/llvm/unittests/ADT/STLExtrasTest.cpp index 278447166fc5..c34760d83874 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 is incomplete"); +static_assert(!is_incomplete_v, "Bar is defined"); + } // namespace