From 694321baab7916ba27b09d1786ffd7cc2f617129 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:27:50 +0100 Subject: [PATCH 1/6] avoid temporary object creations with macro insertions in `simplecpp::preprocess()` --- simplecpp.cpp | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index be775a90..b06cfa75 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -3304,26 +3304,26 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL #endif std::map sizeOfType(rawtokens.sizeOfType); - sizeOfType.insert(std::make_pair("char", sizeof(char))); - sizeOfType.insert(std::make_pair("short", sizeof(short))); - sizeOfType.insert(std::make_pair("short int", sizeOfType["short"])); - sizeOfType.insert(std::make_pair("int", sizeof(int))); - sizeOfType.insert(std::make_pair("long", sizeof(long))); - sizeOfType.insert(std::make_pair("long int", sizeOfType["long"])); - sizeOfType.insert(std::make_pair("long long", sizeof(long long))); - sizeOfType.insert(std::make_pair("float", sizeof(float))); - sizeOfType.insert(std::make_pair("double", sizeof(double))); - sizeOfType.insert(std::make_pair("long double", sizeof(long double))); - sizeOfType.insert(std::make_pair("char *", sizeof(char *))); - sizeOfType.insert(std::make_pair("short *", sizeof(short *))); - sizeOfType.insert(std::make_pair("short int *", sizeOfType["short *"])); - sizeOfType.insert(std::make_pair("int *", sizeof(int *))); - sizeOfType.insert(std::make_pair("long *", sizeof(long *))); - sizeOfType.insert(std::make_pair("long int *", sizeOfType["long *"])); - sizeOfType.insert(std::make_pair("long long *", sizeof(long long *))); - sizeOfType.insert(std::make_pair("float *", sizeof(float *))); - sizeOfType.insert(std::make_pair("double *", sizeof(double *))); - sizeOfType.insert(std::make_pair("long double *", sizeof(long double *))); + sizeOfType.emplace("char", sizeof(char)); + sizeOfType.emplace("short", sizeof(short)); + sizeOfType.emplace("short int", sizeOfType["short"]); + sizeOfType.emplace("int", sizeof(int)); + sizeOfType.emplace("long", sizeof(long)); + sizeOfType.emplace("long int", sizeOfType["long"]); + sizeOfType.emplace("long long", sizeof(long long)); + sizeOfType.emplace("float", sizeof(float)); + sizeOfType.emplace("double", sizeof(double)); + sizeOfType.emplace("long double", sizeof(long double)); + sizeOfType.emplace("char *", sizeof(char *)); + sizeOfType.emplace("short *", sizeof(short *)); + sizeOfType.emplace("short int *", sizeOfType["short *"]); + sizeOfType.emplace("int *", sizeof(int *)); + sizeOfType.emplace("long *", sizeof(long *)); + sizeOfType.emplace("long int *", sizeOfType["long *"]); + sizeOfType.emplace("long long *", sizeof(long long *)); + sizeOfType.emplace("float *", sizeof(float *)); + sizeOfType.emplace("double *", sizeof(double *)); + sizeOfType.emplace("long double *", sizeof(long double *)); // use a dummy vector for the macros because as this is not part of the file and would add an empty entry - e.g. /usr/include/poll.h std::vector dummy; @@ -3343,27 +3343,27 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const std::string lhs(macrostr.substr(0,eq)); const std::string rhs(eq==std::string::npos ? std::string("1") : macrostr.substr(eq+1)); const Macro macro(lhs, rhs, dummy); - macros.insert(std::pair(macro.name(), macro)); + macros.emplace(macro.name(), macro); } const bool strictAnsiUndefined = dui.undefined.find("__STRICT_ANSI__") != dui.undefined.cend(); if (!isGnu(dui) && !strictAnsiDefined && !strictAnsiUndefined) - macros.insert(std::pair("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy))); + macros.emplace("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy)); - macros.insert(std::make_pair("__FILE__", Macro("__FILE__", "__FILE__", dummy))); - macros.insert(std::make_pair("__LINE__", Macro("__LINE__", "__LINE__", dummy))); - macros.insert(std::make_pair("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy))); + macros.emplace("__FILE__", Macro("__FILE__", "__FILE__", dummy)); + macros.emplace("__LINE__", Macro("__LINE__", "__LINE__", dummy)); + macros.emplace("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy)); struct tm ltime = {}; getLocaltime(ltime); - macros.insert(std::make_pair("__DATE__", Macro("__DATE__", getDateDefine(<ime), dummy))); - macros.insert(std::make_pair("__TIME__", Macro("__TIME__", getTimeDefine(<ime), dummy))); + macros.emplace("__DATE__", Macro("__DATE__", getDateDefine(<ime), dummy)); + macros.emplace("__TIME__", Macro("__TIME__", getTimeDefine(<ime), dummy)); if (!dui.std.empty()) { const cstd_t c_std = simplecpp::getCStd(dui.std); if (c_std != CUnknown) { const std::string std_def = simplecpp::getCStdString(c_std); if (!std_def.empty()) - macros.insert(std::make_pair("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy))); + macros.emplace("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy)); } else { const cppstd_t cpp_std = simplecpp::getCppStd(dui.std); if (cpp_std == CPPUnknown) { @@ -3380,7 +3380,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } const std::string std_def = simplecpp::getCppStdString(cpp_std); if (!std_def.empty()) - macros.insert(std::make_pair("__cplusplus", Macro("__cplusplus", std_def, dummy))); + macros.emplace("__cplusplus", Macro("__cplusplus", std_def, dummy)); } } @@ -3467,7 +3467,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL if (dui.undefined.find(macro.name()) == dui.undefined.end()) { const MacroMap::iterator it = macros.find(macro.name()); if (it == macros.end()) - macros.insert(std::pair(macro.name(), macro)); + macros.emplace(macro.name(), macro); else it->second = macro; } From af3f67d718ffe0031de427602a5de2a8e22e1793 Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:38:50 +0100 Subject: [PATCH 2/6] create `Macro` objects in-place --- simplecpp.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index b06cfa75..834b3d7e 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -48,6 +48,7 @@ #ifdef SIMPLECPP_WINDOWS # include #endif +#include #include #include #include @@ -3348,22 +3349,22 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL const bool strictAnsiUndefined = dui.undefined.find("__STRICT_ANSI__") != dui.undefined.cend(); if (!isGnu(dui) && !strictAnsiDefined && !strictAnsiUndefined) - macros.emplace("__STRICT_ANSI__", Macro("__STRICT_ANSI__", "1", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__STRICT_ANSI__"), std::forward_as_tuple("__STRICT_ANSI__", "1", dummy)); - macros.emplace("__FILE__", Macro("__FILE__", "__FILE__", dummy)); - macros.emplace("__LINE__", Macro("__LINE__", "__LINE__", dummy)); - macros.emplace("__COUNTER__", Macro("__COUNTER__", "__COUNTER__", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__FILE__"), std::forward_as_tuple("__FILE__", "__FILE__", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__LINE__"), std::forward_as_tuple("__LINE__", "__LINE__", dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__COUNTER__"), std::forward_as_tuple("__COUNTER__", "__COUNTER__", dummy)); struct tm ltime = {}; getLocaltime(ltime); - macros.emplace("__DATE__", Macro("__DATE__", getDateDefine(<ime), dummy)); - macros.emplace("__TIME__", Macro("__TIME__", getTimeDefine(<ime), dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__DATE__"), std::forward_as_tuple("__DATE__", getDateDefine(<ime), dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__TIME__"), std::forward_as_tuple("__TIME__", getTimeDefine(<ime), dummy)); if (!dui.std.empty()) { const cstd_t c_std = simplecpp::getCStd(dui.std); if (c_std != CUnknown) { const std::string std_def = simplecpp::getCStdString(c_std); if (!std_def.empty()) - macros.emplace("__STDC_VERSION__", Macro("__STDC_VERSION__", std_def, dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__STDC_VERSION__"), std::forward_as_tuple("__STDC_VERSION__", std_def, dummy)); } else { const cppstd_t cpp_std = simplecpp::getCppStd(dui.std); if (cpp_std == CPPUnknown) { @@ -3380,7 +3381,7 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL } const std::string std_def = simplecpp::getCppStdString(cpp_std); if (!std_def.empty()) - macros.emplace("__cplusplus", Macro("__cplusplus", std_def, dummy)); + macros.emplace(std::piecewise_construct, std::forward_as_tuple("__cplusplus"), std::forward_as_tuple("__cplusplus", std_def, dummy)); } } From 5f337aea4d222c2bc7c0ad80ca02f8014771f88d Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:45:12 +0100 Subject: [PATCH 3/6] changed `simplecpp::Macro::tokenListDefine` to a shared pointer --- simplecpp.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 834b3d7e..712b3d61 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -1487,9 +1488,9 @@ namespace simplecpp { class Macro { public: - explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(f), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} + explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} - Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(true) { + Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { if (sameline(tok->previousSkipComments(), tok)) throw std::runtime_error("bad macro syntax"); if (tok->op != '#') @@ -1505,15 +1506,15 @@ namespace simplecpp { throw std::runtime_error("bad macro syntax"); } - Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(f), valueDefinedInCode_(false) { + Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(false) { const std::string def(name + ' ' + value); StdCharBufStream stream(reinterpret_cast(def.data()), def.size()); - tokenListDefine.readfile(stream); - if (!parseDefine(tokenListDefine.cfront())) + tokenListDefine->readfile(stream); + if (!parseDefine(tokenListDefine->cfront())) throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); } - Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.files), valueDefinedInCode_(other.valueDefinedInCode_) { + Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { // TODO: remove the try-catch - see #537 // avoid bugprone-exception-escape clang-tidy warning try { @@ -1531,11 +1532,11 @@ namespace simplecpp { if (this != &other) { files = other.files; valueDefinedInCode_ = other.valueDefinedInCode_; - if (other.tokenListDefine.empty()) + if (other.tokenListDefine->empty()) parseDefine(other.nameTokDef); else { tokenListDefine = other.tokenListDefine; - parseDefine(tokenListDefine.cfront()); + parseDefine(tokenListDefine->cfront()); } usageList = other.usageList; } @@ -2391,7 +2392,7 @@ namespace simplecpp { std::vector &files; /** this is used for -D where the definition is not seen anywhere in code */ - TokenList tokenListDefine; + std::shared_ptr tokenListDefine; /** usage of this macro */ mutable std::list usageList; From fa29505fac43172426460bd01da294347aa4b17f Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:50:16 +0100 Subject: [PATCH 4/6] avoid redundant initialization of `simplecpp::Macro::nameTokDef` --- simplecpp.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 712b3d61..2263382f 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1488,9 +1488,9 @@ namespace simplecpp { class Macro { public: - explicit Macro(std::vector &f) : nameTokDef(nullptr), valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} + explicit Macro(std::vector &f) : valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} - Macro(const Token *tok, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { + Macro(const Token *tok, std::vector &f) : files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { if (sameline(tok->previousSkipComments(), tok)) throw std::runtime_error("bad macro syntax"); if (tok->op != '#') @@ -1506,7 +1506,7 @@ namespace simplecpp { throw std::runtime_error("bad macro syntax"); } - Macro(const std::string &name, const std::string &value, std::vector &f) : nameTokDef(nullptr), files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(false) { + Macro(const std::string &name, const std::string &value, std::vector &f) : files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(false) { const std::string def(name + ' ' + value); StdCharBufStream stream(reinterpret_cast(def.data()), def.size()); tokenListDefine->readfile(stream); @@ -1514,7 +1514,7 @@ namespace simplecpp { throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); } - Macro(const Macro &other) : nameTokDef(nullptr), files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { + Macro(const Macro &other) : files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { // TODO: remove the try-catch - see #537 // avoid bugprone-exception-escape clang-tidy warning try { @@ -2377,7 +2377,7 @@ namespace simplecpp { } /** name token in definition */ - const Token *nameTokDef; + const Token *nameTokDef{}; /** arguments for macro */ std::vector args; From 41147bd2dad3966d806fece2f6640544ed81162c Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:52:57 +0100 Subject: [PATCH 5/6] avoid duplicated assignment of `simplecpp::Macro::tokenListDefine` --- simplecpp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 2263382f..131c2089 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1514,7 +1514,7 @@ namespace simplecpp { throw std::runtime_error("bad macro syntax. macroname=" + name + " value=" + value); } - Macro(const Macro &other) : files(other.files), tokenListDefine(other.tokenListDefine), valueDefinedInCode_(other.valueDefinedInCode_) { + Macro(const Macro &other) : files(other.files), valueDefinedInCode_(other.valueDefinedInCode_) { // TODO: remove the try-catch - see #537 // avoid bugprone-exception-escape clang-tidy warning try { @@ -1532,10 +1532,10 @@ namespace simplecpp { if (this != &other) { files = other.files; valueDefinedInCode_ = other.valueDefinedInCode_; - if (other.tokenListDefine->empty()) + tokenListDefine = other.tokenListDefine; + if (!tokenListDefine || tokenListDefine->empty()) parseDefine(other.nameTokDef); else { - tokenListDefine = other.tokenListDefine; parseDefine(tokenListDefine->cfront()); } usageList = other.usageList; From e3792a317df1297e14b771419e79f969986ef4ed Mon Sep 17 00:00:00 2001 From: firewave Date: Thu, 4 Dec 2025 14:56:05 +0100 Subject: [PATCH 6/6] removed unnecessary creation of `simplecpp::Macro::tokenListDefine` --- simplecpp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simplecpp.cpp b/simplecpp.cpp index 131c2089..27180357 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -1488,9 +1488,9 @@ namespace simplecpp { class Macro { public: - explicit Macro(std::vector &f) : valueToken(nullptr), endToken(nullptr), files(f), tokenListDefine(new TokenList(f)), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} + explicit Macro(std::vector &f) : valueToken(nullptr), endToken(nullptr), files(f), variadic(false), variadicOpt(false), valueDefinedInCode_(false) {} - Macro(const Token *tok, std::vector &f) : files(f), tokenListDefine(new TokenList(f)), valueDefinedInCode_(true) { + Macro(const Token *tok, std::vector &f) : files(f), valueDefinedInCode_(true) { if (sameline(tok->previousSkipComments(), tok)) throw std::runtime_error("bad macro syntax"); if (tok->op != '#')