From 3f6546c7d6861fa258a1be651872506aa25e6f3c Mon Sep 17 00:00:00 2001 From: Johannes Braun Date: Sat, 18 Aug 2018 16:24:18 +0200 Subject: [PATCH] Fix faulty macro replacement for seemingly function-like macros as well as empty-argument-macros --- examples/from_file/main.cpp | 8 ++++++- src/preprocessor/macro.cpp | 35 ++++++++++++++++++++++++++----- src/preprocessor/preprocessor.cpp | 2 +- 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/examples/from_file/main.cpp b/examples/from_file/main.cpp index 80ad5ee..b4722a3 100644 --- a/examples/from_file/main.cpp +++ b/examples/from_file/main.cpp @@ -20,9 +20,15 @@ int main() constexpr const char* source = R"( #include "inc.glsl" + +#define MY_FUN sin +#define OTHER_FUN() cos void main() -{} +{ + int x = int(MY_FUN(177.f)); + int y = int(OTHER_FUN( )(12.f)); +} )"; const glsp::processed_file src = process_state.preprocess_source(source, "Shader"); diff --git a/src/preprocessor/macro.cpp b/src/preprocessor/macro.cpp index 5b6f7d4..73cd3bc 100644 --- a/src/preprocessor/macro.cpp +++ b/src/preprocessor/macro.cpp @@ -27,21 +27,46 @@ namespace glshader::process::impl::macro while (cls::is_name_char(text_ptr)) ++text_ptr; - const std::string str(begin, text_ptr); + const bool has_trailing_brackets = *skip::space(text_ptr) == '(' && *skip::space(skip::space(text_ptr)+1) == ')'; + + const std::string str = std::string(begin, text_ptr) + (has_trailing_brackets ? "()" : ""); return is_defined(str, processed); } - std::string expand_macro(const std::string& name, const char* param_start, const int param_length, + std::string expand_macro(std::string name, const char* param_start, int param_length, const files::path& current_file, const int current_line, processed_file& processed) { std::stringstream stream; - if (processed.definitions.count(name) == 0) - return name; + if (processed.definitions.count(name) == 0) + { + if(param_length == 0) + { + name = name + "()"; + param_start = nullptr; + if (processed.definitions.count(name) == 0) + return name; + } + else + { + int param_len = (skip::space(param_start) - param_start); + if(param_len == param_length) + { + name = name + "()"; + param_start = nullptr; + if (processed.definitions.count(name) == 0) + return name; + } + else + { + return name; + } + } + } auto info = processed.definitions.at(name); if (info.parameters.empty()) - return info.replacement; + return info.replacement + (param_start ? std::string(param_start-1, param_length+2) : ""); std::vector inputs; diff --git a/src/preprocessor/preprocessor.cpp b/src/preprocessor/preprocessor.cpp index 3c04307..8c748ff 100644 --- a/src/preprocessor/preprocessor.cpp +++ b/src/preprocessor/preprocessor.cpp @@ -171,7 +171,7 @@ namespace glshader::process { text_ptr = skip::to_next_token(directive_name); const auto name_begin = text_ptr; - while (!cls::is_space(text_ptr) && !cls::is_newline(text_ptr) && *text_ptr != '(') + while (!cls::is_space(text_ptr) && !cls::is_newline(text_ptr) && (*text_ptr != '(' || (*text_ptr == '(' && *skip::space(text_ptr+1)==')'))) ++text_ptr; if (const auto space_skipped = skip::space(text_ptr); -- GitLab