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 [&](
int ,
int ,
const std::string & ,
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);
97#if !defined(GPU_SHADER)
102 R
"(static void test(GPUSource &source, GPUFunctionDictionary *g_functions, GPUPrintFormatMap *g_formats) {
103 source.add_dependency("a.hh");
104 source.add_dependency("b.glsl");
105 source.add_dependency("d.hh");
106 UNUSED_VARS(source, g_functions, g_formats);
120 using namespace shader;
125[[gpu::unroll]] for (int i = 2; i < 4; i++, y++) { content += i; })";
147[[gpu::unroll]] for (int i = 2; i < 4 && i < y; i++, y++) { cont += i; })";
173[[gpu::unroll(2)]] for (; i < j;) { content += i; })";
194[[gpu::unroll(2)]] for (; i < j;) { [[gpu::unroll(2)]] for (; j < k;) {} })";
236 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { break; })";
239 EXPECT_EQ(
error,
"Unrolled loop cannot contain \"break\" statement.");
242 string input = R
"([[gpu::unroll(2)]] for (; i < j;) { continue; })";
245 EXPECT_EQ(
error,
"Unrolled loop cannot contain \"continue\" statement.");
249[[gpu::unroll(2)]] for (; i < j;) { for (; j < k;) {break;continue;} })";
256 { for (; j < k;) {break;continue;} }
260 { for (; j < k;) {break;continue;} }
269 string input = R
"([[gpu::unroll]] for (int i = 3; i > 2; i++) {})";
276[[gpu::unroll_define(2)]] for (int i = 0; i < DEFINE; i++) { a = i; })";
300 using namespace shader;
307template void func<float>(float a);
313void func(float a) {a;}
323template<typename T, int i>
327template void func<float, 1>(float a);
335void funcTfloatT1(float a) {
347template<> void func<T, Q>(T a) {a}
350 void funcTTTQ(T a) {a}
359template<typename T, int i = 0> void func(T a) {a;}
363 EXPECT_EQ(
error,
"Default arguments are not supported inside template declaration");
367template void func(float a);
374 string input = R
"(func<float, 1>(a);)";
375 string expect = R
"(funcTfloatT1(a);)";
386 using namespace shader;
393template struct A<float>;
399struct ATfloat { float a; };
410template<> struct A<float>{
427void func(A<float> a) {}
430void func(ATfloat a) {}
438GPU_TEST(preprocess_template_struct);
442 using namespace shader;
446 string input = R
"(void func() { auto &a = b; a.a = 0; c = a(a); a_c_a = a; })";
447 string expect = R
"(void func() { b.a = 0; c = a(b); a_c_a = b; })";
454 string input = R
"(void func() { const int &a = b; a.a = 0; c = a(a); })";
455 string expect = R
"(void func() { b.a = 0; c = a(b); })";
462 string input = R
"(void func() { const int i = 0; auto &a = b[i]; a.a = 0; })";
463 string expect = R
"(void func() { const int i = 0; b[i].a = 0; })";
470 string input = R
"(void func() { auto &a = b(0); })";
473 EXPECT_EQ(
error,
"Reference definitions cannot contain function calls.");
476 string input = R
"(void func() { int i = 0; auto &a = b[i++]; })";
482 string input = R
"(void func() { auto &a = b[0 + 1]; })";
486 "Array subscript inside reference declaration must be a single variable or a "
487 "constant, not an expression.");
490 string input = R
"(void func() { auto &a = b[c]; })";
494 "Cannot locate array subscript variable declaration. "
495 "If it is a global variable, assign it to a temporary const variable for "
496 "indexing inside the reference.");
499 string input = R
"(void func() { int c = 0; auto &a = b[c]; })";
502 EXPECT_EQ(
error,
"Array subscript variable must be declared as const qualified.");
505 string input = R
"(auto &a = b;)";
508 EXPECT_EQ(
error,
"Reference is defined inside a global or unterminated scope.");
520int func(int a, int b = 0)
526int func(int a, int b )
545int func(int a = 0, const int b = 0)
551int func(int a , const int b )
576int2 func(int2 a = int2(0, 0)) {
588 return func(int2(0, 0));
599void func(int a = 0) {
621GPU_TEST(preprocess_default_arguments);
625 using namespace shader;
635 return B::func(int a);
648struct A_S {int _pad;};
653 return B_func(int a);
660 return A_func(int a);
690 return A_B_func(int a);
786struct A_B_S {int _pad;};
809 EXPECT_EQ(
error,
"The `using` keyword is not allowed in global scope.");
820 "Unsupported `using namespace`. "
821 "Add individual `using` directives for each needed symbol.");
832 "The `using` keyword is only allowed in namespace scope to make visible symbols "
833 "from the same namespace declared in another scope, potentially from another "
845 "The `using` keyword is only allowed in namespace scope to make visible symbols "
846 "from the same namespace declared in another scope, potentially from another "
854template<typename T> T read(T a)
858template float read<float>(float);
859float write(float a){ return a; }
870float NS_read(float a)
875float NS_write(float a){ return a; }
888 static S static_method(S s) {
891 S other_method(int s) {
909 NS_S NS_S_static_method(NS_S s) {
913 NS_S other_method(inout NS_S _inout_sta this_ _inout_end, int s) {
929 using namespace shader;
933 string input = R
"(a.xyzw().aaa().xxx().grba().yzww; aaaa();)";
934 string expect = R
"(a.xyzw .aaa .xxx .grba .yzww; aaaa();)";
945 using namespace shader;
950enum class enum_class : int {
959#define enum_class int
961constant static constexpr int enum_class_VALUE = 0;
971enum class enum_class {
977 EXPECT_EQ(
error,
"enum declaration must explicitly use an underlying type");
983static void test_preprocess_matrix_constructors()
985 using namespace shader;
989 string input = R
"(mat3(a); mat3 a; my_mat4x4(a); mat2x2(a); mat3x2(a);)";
990 string expect = R
"(__mat3x3(a); mat3 a; my_mat4x4(a); __mat2x2(a); mat3x2(a);)";
997GPU_TEST(preprocess_matrix_constructors);
1002 using namespace shader;
1003 using namespace std;
1007[[gpu::vertex_function]] void my_func() {
1013#if defined(GPU_VERTEX_SHADER)
1026GPU_TEST(preprocess_stage_attribute);
1030 using namespace shader;
1031 using namespace std;
1036 interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1041#if defined(CREATE_INFO_draw_resource_id_varying)
1043 interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1057 i += interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1063#if defined(CREATE_INFO_draw_resource_id_varying)
1066 i += interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1085 i += interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1094#if defined(CREATE_INFO_draw_resource_id_varying)
1096 i += interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1113 i += interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1114 i += buffer_get(draw_resource_id, resource_id_buf)[0];
1123#if defined(CREATE_INFO_draw_resource_id_varying)
1125#if defined(CREATE_INFO_draw_resource_id)
1127 i += interface_get(draw_resource_id_varying, drw_ResourceID_iface).resource_index;
1128 i += buffer_get(draw_resource_id, resource_id_buf)[0];
1145template<> uint my_func<uint>(uint i) {
1146 return buffer_get(draw_resource_id, resource_id_buf)[i];
1150 uint my_funcTuint(uint i) {
1151#if defined(CREATE_INFO_draw_resource_id)
1153 return buffer_get(draw_resource_id, resource_id_buf)[i];
1167GPU_TEST(preprocess_resource_guard);
1171 using namespace shader;
1172 using namespace std;
1183struct S {int _pad;};
1185struct T {int _pad;};
1204 using namespace shader;
1205 using namespace std;
1215 static S construct()
1234 return this->member;
1240 S s = S::construct();
1290 S function(inout S _inout_sta this_ _inout_end, int i)
1297 int size(const S this_)
1299 return this_.member;
1305 S s = S_construct();
1323GPU_TEST(preprocess_struct_methods);
1327 using namespace std;
1328 using namespace shader::parser;
1330 ParserData::report_callback no_err_report = [](int, int, string,
const char *) {};
13460;0;0;0;0;0;0;0;0;0;)";
1359sw{ww=0;};Sw{ww;};)";
1369 string expect_scopes = R
"(GNN)";
1376 int i = 0, u = 2, v = {1.0f};
1386ww(ww=0){ww=0,w=0,w={0};{w=w=w,wP;i(wEw){r;}}})";
1390 Parser parser("float i;", no_err_report);
1391 parser.insert_after(Token::from_position(&
parser.data_get(), 0),
"A ");
1392 parser.insert_after(Token::from_position(&
parser.data_get(), 0),
"B ");
1407 Token A = Token::from_position(&parser.data_get(), 1);
1408 Token B = Token::from_position(&parser.data_get(), 6);
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 int preprocess_include(char *maindata, const int maindata_len)
static void error(const char *str)
PBVHData & data_get(blender::bke::pbvh::Tree &pbvh)
static void test_preprocess_namespace()
static void test_preprocess_reference()
static void test_preprocess_unroll()
static void test_preprocess_default_arguments()
static void test_preprocess_stage_attribute()
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_empty_struct()
static void test_preprocess_template()
static void test_preprocess_resource_guard()
static void test_preprocess_struct_methods()
static void test_preprocess_template_struct()
static void test_preprocess_swizzle()
static void test_preprocess_parser()
static void test_preprocess_utilities()
static void test_preprocess_enum()
static void test_preprocess_include()