16 string input =
"test (u, u(s,(s,s)), u) {t{{}},t,{};(,)} {u{}} end";
21 "test (u! u(s!(s!s))! u) {t{{}},t,{};(!)} {u{}} end");
23 vector<string> split_expect{
"test (u, u(s,(s,s",
"",
", u",
" {t{{}},t,{};(,",
"} {u{}} end"};
25 EXPECT_EQ_VECTOR(split_expect, split_result);
27 string input2 =
"u, u(s,(s,s)), u";
30 input2,
',',
'(',
')');
31 EXPECT_EQ_VECTOR(split_expect2, split_result2);
33 string input_reference =
"void func(int &a, int (&c)[2]) {{ int &b = a; }} int &b = a;";
34 int fn_ref_count = 0, arg_ref_count = 0, global_ref_count = 0;
36 input_reference, [&](
int parenthesis_depth,
int bracket_depth,
char & ) {
37 if ((parenthesis_depth == 1 || parenthesis_depth == 2) && bracket_depth == 0) {
40 else if (bracket_depth > 0) {
43 else if (bracket_depth == 0 && parenthesis_depth == 0) {
44 global_ref_count += 1;
54 std::string &first_error,
68 [&](
const std::smatch & ,
const char *err_msg) {
69 if (first_error.empty()) {
70 first_error = err_msg;
75 if (r_metadata !=
nullptr) {
80 size_t newline =
result.find(
'\n');
81 return result.substr(newline + 1);
90 string input = R
"([[gpu::unroll]] for (int i = 2; i < 4; i++, y++) { content += i; })";
91 string expect = R
"({ int i = 2;
108 string input = R
"([[gpu::unroll]] for (int i = 2; i < 4 && i < y; i++, y++) { cont += i; })";
109 string expect = R
"({ int i = 2;
111if (i < y) { cont += i; }
115if (i < y) { cont += i; }
126 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { content += i; })";
127 string expect = R
"({ ;
129if (i < j) { content += i; }
133if (i < j) { content += i; }
144 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { [[gpu::unroll(2)]] for (; j < k;) {} })";
145 string expect = R
"({ ;
182 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { break; })";
185 EXPECT_EQ(
error,
"Error: Unrolled loop cannot contain \"break\" statement.");
188 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { continue; })";
191 EXPECT_EQ(
error,
"Error: Unrolled loop cannot contain \"continue\" statement.");
194 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { for (; j < k;) {break;continue;} })";
195 string expect = R
"({ ;
197if (i < j) { for (; j < k;) {break;continue;} }
201if (i < j) { for (; j < k;) {break;continue;} }
212 string input = R
"([[gpu::unroll]] for (int i = 3; i > 2; i++) {})";
215 EXPECT_EQ(
error,
"Error: Unsupported condition in unrolled loop.");
222 using namespace shader;
229template void func<float>(float a);)";
231#define func_TEMPLATE(T) \
233func_TEMPLATE(float)/*float a*/)";
241template<typename T, int i>
245template void func<float, 1>(float a);)";
247#define func_TEMPLATE(T, i) \
248void func_##T##_##i##_(T a) { \
251func_TEMPLATE(float, 1)/*float a*/)";
258 string input = R
"(template<typename T, int i = 0> void func(T a) {a;)";
264 string input = R
"(template void func(float a);)";
270 string input = R
"(func<float, 1>(a);)";
271 string expect = R
"(TEMPLATE_GLUE2(func, float, 1)(a);)";
282 using namespace shader;
286 string input = R
"(void func() { auto &a = b; a.a = 0; c = a(a); a_c_a = a; })";
287 string expect = R
"(void func() { b.a = 0; c = a(b); a_c_a = b; })";
294 string input = R
"(void func() { const int &a = b; a.a = 0; c = a(a); })";
295 string expect = R
"(void func() { b.a = 0; c = a(b); })";
302 string input = R
"(void func() { const int i = 0; auto &a = b[i]; a.a = 0; })";
303 string expect = R
"(void func() { const int i = 0; b[i].a = 0; })";
310 string input = R
"(void func() { auto &a = b(0); })";
313 EXPECT_EQ(
error,
"Reference definitions cannot contain function calls.");
316 string input = R
"(void func() { int i = 0; auto &a = b[i++]; })";
319 EXPECT_EQ(
error,
"Reference definitions cannot have side effects.");
322 string input = R
"(void func() { auto &a = b[0 + 1]; })";
326 "Array subscript inside reference declaration must be a single variable or a "
327 "constant, not an expression.");
330 string input = R
"(void func() { auto &a = b[c]; })";
334 "Cannot locate array subscript variable declaration. "
335 "If it is a global variable, assign it to a temporary const variable for "
336 "indexing inside the reference.");
339 string input = R
"(void func() { int c = 0; auto &a = b[c]; })";
342 EXPECT_EQ(
error,
"Array subscript variable must be declared as const qualified.");
345 string input = R
"(auto &a = b;)";
348 EXPECT_EQ(
error,
"Reference is defined inside a global or unterminated scope.");
355 using namespace shader;
360int func(int a, int b = 0)
366int func(int a, int b)
385int func(int a = 0, const int b = 0)
391int func(int a, const int b)
416int2 func(int2 a = int2(0, 0)) {
428 return func(int2(0, 0));
439void func(int a = 0) {
461GPU_TEST(preprocess_default_arguments);
465 using namespace shader;
475 return B::func(int a);
492 return B_func(int a);
499 return A_func(int a);
529 return A_B_func(int a);
647 EXPECT_EQ(
error,
"The `using` keyword is not allowed in global scope.");
658 "Unsupported `using namespace`. "
659 "Add individual `using` directives for each needed symbol.");
670 "The `using` keyword is only allowed in namespace scope to make visible symbols "
671 "from the same namespace declared in another scope, potentially from another "
683 "The `using` keyword is only allowed in namespace scope to make visible symbols "
684 "from the same namespace declared in another scope, potentially from another "
692template<typename T> T read(T a)
696template float read<float>(float);
697float write(float a){ return a; }
703#define NS_read_TEMPLATE(T) T NS_read(T a) \
707NS_read_TEMPLATE(float)/*float*/
708float NS_write(float a){ return a; }
721 using namespace shader;
725 string input = R
"(a.xyzw().aaa().xxx().grba().yzww; aaaa();)";
726 string expect = R
"(a.xyzw .aaa .xxx .grba .yzww; aaaa();)";
736static void test_preprocess_matrix_constructors()
738 using namespace shader;
742 string input = R
"(mat3(a); mat3 a; my_mat4x4(a); mat2x2(a); mat3x2(a);)";
743 string expect = R
"(__mat3x3(a); mat3 a; my_mat4x4(a); __mat2x2(a); mat3x2(a);)";
750GPU_TEST(preprocess_matrix_constructors);
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
std::string process(SourceLanguage language, std::string str, const std::string &filename, bool do_parse_function, bool do_small_type_linting, report_callback report_error, metadata::Source &r_metadata)
static std::string get_content_between_balanced_pair(const std::string &input, char start_delimiter, char end_delimiter, const bool backwards=false)
static void reference_search(std::string &str, std::function< void(int, int, char &)> callback)
static std::string replace_char_between_balanced_pair(const std::string &input, const char start_delimiter, const char end_delimiter, const char from, const char to)
static std::vector< std::string > split_string_not_between_balanced_pair(const std::string &str, const char delimiter, const char pair_start, const char pair_end)
static std::vector< std::string > split_string(const std::string &str, const char delimiter)
#define GPU_TEST(test_name)
static void error(const char *str)
static void test_preprocess_namespace()
static void test_preprocess_reference()
static void test_preprocess_unroll()
static void test_preprocess_default_arguments()
static std::string process_test_string(std::string str, std::string &first_error, shader::metadata::Source *r_metadata=nullptr, shader::Preprocessor::SourceLanguage language=shader::Preprocessor::SourceLanguage::BLENDER_GLSL)
static void test_preprocess_template()
static void test_preprocess_swizzle()
static void test_preprocess_utilities()