You can change an argument to a quoted literal, but you can't go the other way.
Macros don't provide any way to test if an argument is a quoted literal.
Can't be done, I'm afraid. You could look into passing the source through M4 before compiling. The M4 syntax is similar to the C preprocessor's. https://www.gnu.org/software/m4/manual/m4.html
If you're going that route, though, you're probably better off just writing a small program that generates your source. Maintaining M4 input sucks.
The problem is that string literals are typically treated as being self-delimiting. This means that the normal pattern matching hack used to identify particular tokens can't work with double quotes.
Here's an example of the trick. Here the macro IS_DQUOTE expands to 1 if you pass in the word dquote but otherwise it expands to 0:
When trying to adapt this to identify actual quoted strings, the most immediate problem is that CONCATENATED(IS_DQUOTE_PATTERN_, "")
is a syntax error.
This can be worked around by abusing UDL suffixes: CONCATENATED("", _x_INVENTED_UDL_SUFFIX)()
But it still doesn't help because it appears that the resulting expansion, which is ""_x_INVENTED_UDL_SUFFIX(), won't expand even if _x_INVENTED_UDL_SUFFIX is a function-like macro.
Some alternatives might be: WHATEVER_YOU_WANT(a, b, STRINGIFY(xyz), d)
or WHATEVER_YOU_WANT(a, b, DQUOTE, c, DQUOTE, d)
or WHATEVER_YOU_WANT(a, b, DQUOTE c DQUOTE, d)
Also, depending on what code is generated you might be able to use templates to do it.