From e29b326dd80431b2eb4a66dc350fb229fc209761 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 28 Mar 2024 21:07:09 +0100 Subject: [PATCH] cppparser: Parse macro directly following string literal This allows the following C code to parse: #define SUFFIX "bar" const char *str = "foo"SUFFIX; This is technically not valid C++ since C++ uses this syntax for custom string literals, but we might as well check if there is a macro defined with this name if we can't find a matching string literal and are about to throw an error --- dtool/src/cppparser/cppPreprocessor.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dtool/src/cppparser/cppPreprocessor.cxx b/dtool/src/cppparser/cppPreprocessor.cxx index 9599536539..a56775edf0 100644 --- a/dtool/src/cppparser/cppPreprocessor.cxx +++ b/dtool/src/cppparser/cppPreprocessor.cxx @@ -2186,6 +2186,17 @@ get_literal(int token, YYLTYPE loc, const string &str, const YYSTYPE &value) { CPPIdentifier *ident = new CPPIdentifier("operator \"\" " + suffix); CPPDeclaration *decl = ident->find_symbol(current_scope, global_scope, this); + if (decl == nullptr) { + // Special case to handle C code, which allows a macro to directly follow + // a string, like "str"SUFFIX. In this case, it becomes a separate token. + Manifests::const_iterator mi = _manifests.find(suffix); + if (mi != _manifests.end() && !should_ignore_manifest((*mi).second)) { + CPPManifest *manifest = (*mi).second; + _saved_tokens.push_back(expand_manifest(manifest, loc)); + return CPPToken(token, loc, str, value); + } + } + if (decl == nullptr || decl->get_subtype() != CPPDeclaration::ST_function_group) { error("unknown literal suffix " + suffix, loc); return CPPToken(token, loc, str, value);