@@ -313,57 +313,52 @@ class Converter : public clang::RecursiveASTVisitor<Converter> {
313313
314314#define StrCat (...) _StrCat(__FUNCTION__, __LINE__, __VA_ARGS__)
315315
316- // All-literal overload: selected (by partial ordering) when every argument
317- // is a string literal. Merges all literals (each followed by a space) into
318- // a single buffer and performs one rs_code append instead of one per literal.
319- // e.g. StrCat("foo", "bar") is equivalent to StrCat("foo bar").
320- template <std::size_t ... Ns>
321- inline void _StrCat (const char *func, int line, const char (&...vals)[Ns]) {
316+ // Appends each argument to rs_code_, merging consecutive string literals
317+ // into a single buffer before each append. Non-literal arguments are
318+ // appended individually.
319+ // e.g. StrCat("foo", "bar", var1, "xyz") performs:
320+ // rs_code_ += "foo bar " (one append for the merged literal run)
321+ // rs_code_ += var1 + ' ' (one append for the non-literal)
322+ // rs_code_ += "xyz " (one append for the trailing literal)
323+ template <typename ... Ts>
324+ inline void _StrCat (const char *func, int line, const Ts &...vals) {
322325 llvm::errs () << ' [' << func << ' :' << line << " ] " ;
323326 ((llvm::errs () << vals << ' \n ' ), ...);
324- constexpr std::size_t total = (Ns + ...);
325- const auto merged = _MergeStrings<total>(vals...);
326- rs_code_->append (merged.data (), total);
327+ _AppendRuns (*rs_code_, std::array<char , 0 >{}, vals...);
327328 }
328329
329- // General fallback: used when at least one argument is not a string literal.
330- // Each argument is appended individually (value then space).
331- template <typename ... Ts>
332- inline void _StrCat (const char *func, int line, const Ts &...vals) {
333- llvm::errs () << ' [' << func << ' :' << line << " ] " ;
334- ((llvm::errs () << vals << ' \n ' , AppendToCode (*rs_code_, vals)), ...);
330+ // Base case: no more arguments. Flush the pending literal buffer if any.
331+ template <std::size_t BufSize>
332+ static void _AppendRuns (std::string &rs_code, std::array<char , BufSize> buf) {
333+ if constexpr (BufSize > 0 )
334+ rs_code.append (buf.data (), BufSize);
335335 }
336336
337- // Merges k string literals (each followed by a space) into a single
338- // std::array<char, Total> where Total = sum(Ns). The null terminator of
339- // each literal is dropped and replaced by a space character.
340- template <std::size_t Total, std::size_t ... Ns>
341- static constexpr std::array<char , Total>
342- _MergeStrings (const char (&...strs)[Ns]) {
343- std::array<char , Total> result{};
344- std::size_t pos = 0 ;
345- auto fill = [&](const char *s, std::size_t n) {
346- for (std::size_t i = 0 ; i < n - 1 ; ++i)
347- result[pos++] = s[i];
348- result[pos++] = ' ' ;
349- };
350- (fill (strs, Ns), ...);
351- return result;
337+ // Head is a string literal: extend the pending buffer (N-1 content chars
338+ // followed by a space, replacing the null terminator) and recurse.
339+ template <std::size_t BufSize, std::size_t N, typename ... Rest>
340+ static void _AppendRuns (std::string &rs_code, std::array<char , BufSize> buf,
341+ const char (&val)[N], const Rest &...rest) {
342+ std::array<char , BufSize + N> new_buf;
343+ for (std::size_t i = 0 ; i < BufSize; ++i)
344+ new_buf[i] = buf[i];
345+ for (std::size_t i = 0 ; i < N - 1 ; ++i)
346+ new_buf[BufSize + i] = val[i];
347+ new_buf[BufSize + N - 1 ] = ' ' ;
348+ _AppendRuns (rs_code, new_buf, rest...);
352349 }
353350
354- // General fallback: append val then a space (two operations).
355- template <typename T>
356- static void AppendToCode (std::string &rs_code, const T &val) {
351+ // Head is NOT a string literal: flush the pending buffer (if any), append
352+ // the non-literal argument (value + space), then continue with an empty
353+ // buffer.
354+ template <std::size_t BufSize, typename T, typename ... Rest>
355+ static void _AppendRuns (std::string &rs_code, std::array<char , BufSize> buf,
356+ const T &val, const Rest &...rest) {
357+ if constexpr (BufSize > 0 )
358+ rs_code.append (buf.data (), BufSize);
357359 rs_code += val;
358360 rs_code += ' ' ;
359- }
360-
361- // Specialization for a single string literal in the general (mixed) path:
362- // reuses _MergeStrings to perform one append call.
363- template <std::size_t N>
364- static void AppendToCode (std::string &rs_code, const char (&val)[N]) {
365- const auto combined = _MergeStrings<N>(val);
366- rs_code.append (combined.data (), N);
361+ _AppendRuns (rs_code, std::array<char , 0 >{}, rest...);
367362 }
368363
369364 class Buffer {
0 commit comments