[RISCV] Simplify usage of SplatPat_simm5_plus1. NFC (#125340)
[llvm-project.git] / clang / test / SemaCXX / builtin-dump-struct.cpp
blob91ffa7c8c05bdeefbb6856d63d581207acb6dd01
1 // RUN: %clang_cc1 -std=c++20 -verify %s
3 namespace std {
4 typedef decltype(sizeof(int)) size_t;
6 template <class E> struct initializer_list {
7 const E *data;
8 size_t size;
10 constexpr initializer_list(const E *data, size_t size)
11 : data(data), size(size) {}
12 constexpr initializer_list() : data(), size() {}
14 constexpr const E *begin() const { return data; }
15 constexpr const E *end() const { return data + size; }
19 struct ConstexprString {
20 constexpr ConstexprString() : ConstexprString("") {}
21 constexpr ConstexprString(const char *p, std::size_t size) : data(new char[size+1]) {
22 __builtin_memcpy(data, p, size);
23 data[size] = '\0';
25 constexpr ConstexprString(const char *p) : ConstexprString(p, __builtin_strlen(p)) {}
26 constexpr explicit ConstexprString(const char *p, const char *q) : data(nullptr) {
27 auto p_size = __builtin_strlen(p);
28 auto q_size = __builtin_strlen(q);
29 data = new char[p_size + q_size + 1];
30 __builtin_memcpy(data, p, p_size);
31 __builtin_memcpy(data + p_size, q, q_size + 1);
33 constexpr ConstexprString(const ConstexprString &o) : ConstexprString(o.data) {}
34 constexpr ConstexprString(ConstexprString &&o) : data(o.data) { o.data = nullptr; }
35 constexpr ConstexprString &operator=(const ConstexprString &o) {
36 return *this = ConstexprString(o);
38 constexpr ConstexprString &operator=(ConstexprString &&o) {
39 delete[] data;
40 data = o.data;
41 o.data = nullptr;
42 return *this;
44 constexpr ~ConstexprString() { delete[] data; }
45 char *data;
47 friend constexpr ConstexprString operator+(const ConstexprString &a, const ConstexprString &b) {
48 return ConstexprString(a.data, b.data);
50 friend constexpr ConstexprString &operator+=(ConstexprString &a, const ConstexprString &b) {
51 return a = a + b;
53 friend constexpr bool operator==(const ConstexprString &a, const ConstexprString &b) {
54 return __builtin_strcmp(a.data, b.data) == 0;
58 template<typename... T> constexpr void Format(ConstexprString &out, const char *fmt, T... args);
60 struct Arg {
61 template<typename T, int (*)[__is_integral(T) ? 1 : -1] = nullptr>
62 constexpr Arg(T value) {
63 bool negative = false;
64 if (value < 0) {
65 value = -value;
66 negative = true;
68 while (value > 0) {
69 char str[2] = {char('0' + value % 10), '\0'};
70 s = ConstexprString(str) + s;
71 value /= 10;
73 if (negative)
74 s = "-" + s;
76 template<typename T, int (*)[__is_class(T) ? 1 : -1] = nullptr>
77 constexpr Arg(const T &value) {
78 __builtin_dump_struct(&value, Format, s);
80 constexpr Arg(const char *s) : s(s) {}
81 constexpr Arg(const ConstexprString *s) : s("\"" + *s + "\"") {}
82 template<typename T, int (*)[__is_integral(T) ? 1 : -1] = nullptr>
83 constexpr Arg(const T *p) : s("reference to " + Arg(*p).s) {}
84 ConstexprString s;
87 template<typename... T> constexpr void Format(ConstexprString &out, const char *fmt, T... args) { // #Format
88 Arg formatted_args[] = {args...};
89 int i = 0;
90 while (const char *percent = __builtin_strchr(fmt, '%')) {
91 if (percent[1] == '%') continue;
92 if (percent != fmt && percent[-1] == '*') --percent;
93 out += ConstexprString(fmt, percent - fmt);
94 out += formatted_args[i++].s;
96 // Skip past format specifier until we hit a conversion specifier.
97 fmt = percent;
98 while (!__builtin_strchr("diouxXeEfFgGcsp", *fmt)) ++fmt;
99 // Skip the conversion specifier too. TODO: Check it's the right one.
100 ++fmt;
102 out += ConstexprString(fmt);
105 template<typename T> constexpr ConstexprString ToString(const T &t) { return Arg(t).s; }
107 struct A {
108 int x, y, z : 3;
109 int : 4;
110 ConstexprString s;
112 struct B : A {
113 int p, q;
114 struct {
115 int anon1, anon2;
117 union {
118 int anon3;
120 struct {
121 int m;
122 } c;
123 int &&r;
126 #if PRINT_OUTPUT
127 #include <stdio.h>
128 int main() {
129 puts(ToString(B{1, 2, 3, "hello", 4, 5, 6, 7, 8, 9, 10}).data);
131 #else
132 static_assert(ToString(B{1, 2, 3, "hello", 4, 5, 6, 7, 8, 9, 10}) == &R"(
135 int x = 1
136 int y = 2
137 int z : 3 = 3
138 ConstexprString s = "hello"
140 int p = 4
141 int q = 5
142 int anon1 = 6
143 int anon2 = 7
144 int anon3 = 8
145 struct (unnamed) c = {
146 int m = 9
148 int && r = reference to 10
150 )"[1]);
152 class Incomplete; // #incomplete-type
154 template <class T>
155 class Class {
156 T value = {};
159 void errors(B b) {
160 ConstexprString cs;
161 __builtin_dump_struct(); // expected-error {{too few arguments to function call, expected 2, have 0}}
162 __builtin_dump_struct(1); // expected-error {{too few arguments to function call, expected 2, have 1}}
163 __builtin_dump_struct(1, 2); // expected-error {{expected pointer to struct as 1st argument to '__builtin_dump_struct', found 'int'}}
164 __builtin_dump_struct(&b, 2); // expected-error {{expected a callable expression as 2nd argument to '__builtin_dump_struct', found 'int'}}
165 __builtin_dump_struct(&b, Format, 0); // expected-error {{no matching function for call to 'Format'}}
166 // expected-note@-1 {{in call to printing function with arguments '(0, "%s", "B")' while dumping struct}}
167 // expected-note@#Format {{no known conversion from 'int' to 'ConstexprString &' for 1st argument}}
168 __builtin_dump_struct((Incomplete *)nullptr, Format, cs); // expected-error {{incomplete type 'Incomplete' where a complete type is required}}
169 // expected-note@#incomplete-type {{forward declaration of 'Incomplete'}}
170 // Ensure the Class<int> gets instantiated; otherwise crash happens.
171 __builtin_dump_struct((Class<int> *)nullptr, Format, cs);
173 #endif
175 // Check that PseudoObjectExprBitfields:NumSubExprs doesn't overflow. This
176 // would previously cause a crash.
177 struct t1 {
178 int v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16,
179 v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
180 v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46,
181 v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61,
182 v62, v63, v64, v65, v66, v67, v68, v69, v70, v71, v72, v73, v74, v75, v76,
183 v77, v78, v79, v80, v81, v82, v83, v84, v85, v86, v87, v88, v89, v90, v91,
184 v92, v93, v94, v95, v96, v97, v98, v99;
187 struct t2 {
188 t1 v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16,
189 v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31,
190 v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46,
191 v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61,
192 v62, v63, v64, v65, v66, v67, v68, v69, v70, v71, v72, v73, v74, v75, v76,
193 v77, v78, v79, v80, v81, v82, v83, v84, v85, v86, v87, v88, v89, v90, v91,
194 v92, v93, v94, v95, v96, v97, v98, v99;
197 int printf(const char *, ...);
198 void f1(t2 w) { __builtin_dump_struct(&w, printf); }