[clang] [Clang] [P2996] Support reflecting arbitrary types and aliases (PR #232074)

Ambrose Leeb via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 16 12:47:11 PDT 2026


================
@@ -118,3 +121,481 @@ consteval void test()
     static_assert(^^const foo == ^^const int);
     static_assert(^^const int == ^^int const);
 }
+namespace StandardTypes {
+using info = decltype(^^int);
+struct Incomplete;
+struct Record { int member; };
+union Union { int member; };
+enum Enum { enumerator };
+enum class ScopedEnum {};
+enum class ForwardEnum;
+template <class T> struct ClassTemplate {};
+template <class T> using AliasTemplate = ClassTemplate<T>;
+
+static_assert(^^Incomplete == ^^struct Incomplete);
+static_assert(^^Record == ^^struct Record);
+static_assert(^^Union == ^^union Union);
+static_assert(^^Enum == ^^enum Enum);
+static_assert(^^Record != ^^Union);
+static_assert(^^Enum != ^^ScopedEnum);
+static_assert(^^ForwardEnum == ^^ForwardEnum);
+static_assert(^^const ClassTemplate<int> == ^^const AliasTemplate<int>);
+static_assert(^^ClassTemplate<int> != ^^ClassTemplate<float>);
+static_assert(^^const Record != ^^Record);
+static_assert(^^volatile Record != ^^const Record);
+static_assert(^^Record * != ^^const Record *);
+static_assert(^^int * != ^^int *const);
+static_assert(^^int & != ^^int &&);
+static_assert(^^int[3] == ^^int[1 + 2]);
+static_assert(^^int[3] != ^^int[4]);
+static_assert(^^int[] != ^^int[3]);
+static_assert(^^int[2][3] != ^^int[3][2]);
+static_assert(^^void(int) == ^^void(int));
+static_assert(^^void(int) != ^^void(float));
+static_assert(^^void(int, ...) != ^^void(int));
+static_assert(^^void() noexcept != ^^void());
+static_assert(^^int Record::* != ^^float Record::*);
+static_assert(^^void (Record::*)() const != ^^void (Record::*)());
+static_assert(^^void (Record::*)() & != ^^void (Record::*)() &&);
+static_assert(^^void (*)(int) != ^^void(int));
+
+using Pointer = int *;
+using OtherPointer = Pointer;
+using Array = int[3];
+using Function = void(int);
+using RecordAlias = Record;
+static_assert(^^Pointer != ^^int *);
+static_assert(^^Pointer != ^^OtherPointer);
+static_assert(^^const Pointer == ^^int *const);
+static_assert(^^Array != ^^int[3]);
+static_assert(^^const Array == ^^const int[3]);
+static_assert(^^Function != ^^void(int));
+static_assert(^^RecordAlias != ^^Record);
+static_assert(^^const RecordAlias == ^^const Record);
+
+Record object;
+static_assert(^^decltype(object) == ^^Record);
+Pointer pointer_object;
+static_assert(^^decltype(pointer_object) == ^^int *);
+static_assert(^^decltype(pointer_object) != ^^Pointer);
+static_assert(^^decltype((object)) == ^^Record &);
+auto lambda = [] {};
+static_assert(^^decltype(lambda) == ^^decltype(lambda));
+static_assert(^^decltype(lambda) != ^^Record);
+
+template <info R> struct Reflected {};
+static_assert(__is_same(Reflected<^^int *>, Reflected<^^int *>));
+static_assert(!__is_same(Reflected<^^int *>, Reflected<^^float *>));
+static_assert(__is_same(Reflected<^^Record>, Reflected<^^struct Record>));
+static_assert(!__is_same(Reflected<^^Pointer>, Reflected<^^int *>));
+
+template <class T> constexpr info reflected = ^^T;
+static_assert(reflected<int *> == ^^int *);
+static_assert(reflected<Record> == ^^Record);
+static_assert(reflected<Pointer> == ^^int *);
+static_assert(reflected<void(int)> == ^^void(int));
+
+template <class T, int N> consteval bool dependent() {
+  static_assert(__is_same(decltype(^^T), info));
+  static_assert(__is_same(decltype(^^typename T::type), info));
+  static_assert(^^T * == ^^T *);
----------------
Sirraide wrote:

I probably need to do a pass to deduplicate a few of these tests yeah

https://github.com/llvm/llvm-project/pull/232074


More information about the cfe-commits mailing list