From 2ce71fca18a68e0ac4e9fdd5c45afcca167bd534 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cle=CC=81ment=20Foucault?= Date: Fri, 16 May 2025 11:01:07 +0200 Subject: [PATCH] GPU: Shader Preprocess: Add support for template inside namespaces And also support for template definition on single line. --- .../gpu/glsl_preprocess/glsl_preprocess.hh | 11 +++++-- .../gpu/tests/shader_preprocess_test.cc | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/source/blender/gpu/glsl_preprocess/glsl_preprocess.hh b/source/blender/gpu/glsl_preprocess/glsl_preprocess.hh index 00c6f78b56e..d1bb4ee6c13 100644 --- a/source/blender/gpu/glsl_preprocess/glsl_preprocess.hh +++ b/source/blender/gpu/glsl_preprocess/glsl_preprocess.hh @@ -687,12 +687,17 @@ class Preprocessor { std::string out_content = content; /* Parse all global symbols (struct / functions) inside the content. */ - std::regex regex(R"(\n(?:const )?\w+ (\w+)\(?)"); + std::regex regex(R"([\n\>] ?(?:const )?(\w+) (\w+)\(?)"); regex_global_search(content, regex, [&](const std::smatch &match) { - std::string function = match[1].str(); + std::string return_type = match[1].str(); + if (return_type == "template") { + /* Matched a template instantiation. */ + return; + } + std::string function = match[2].str(); /* Replace all occurrences of the non-namespace specified symbol. * Reject symbols that contain the target symbol name. */ - std::regex regex(R"(([^:\w]))" + function + R"(([\s\(]))"); + std::regex regex(R"(([^:\w]))" + function + R"(([\s\(\<]))"); out_content = std::regex_replace( out_content, regex, "$1" + namespace_name + "::" + function + "$2"); }); diff --git a/source/blender/gpu/tests/shader_preprocess_test.cc b/source/blender/gpu/tests/shader_preprocess_test.cc index 21efd85b146..b005ae3a699 100644 --- a/source/blender/gpu/tests/shader_preprocess_test.cc +++ b/source/blender/gpu/tests/shader_preprocess_test.cc @@ -682,6 +682,35 @@ using C = B::func; "from the same namespace declared in another scope, potentially from another " "file."); } + { + /* Template on the same line as function signature inside a namespace. + * Template instantiation with other functions. */ + string input = R"( +namespace NS { +template T read(T a) +{ + return a; +} +template float read(float); +float write(float a){ return a; } +} +)"; + + string expect = R"( + +#define NS_read_TEMPLATE(T) T NS_read(T a) \ +{ \ + return a; \ +} +NS_read_TEMPLATE(float)/*float*/ +float NS_write(float a){ return a; } + +)"; + string error; + string output = process_test_string(input, error); + EXPECT_EQ(output, expect); + EXPECT_EQ(error, ""); + } } GPU_TEST(preprocess_namespace);