Skip to content

Commit 9f9a652

Browse files
authored
refs issue #9089: avoid usage of expensive std::stringstream (#2996)
1 parent 853c271 commit 9f9a652

6 files changed

Lines changed: 92 additions & 93 deletions

File tree

lib/checkio.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1938,7 +1938,9 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
19381938
os << type->str() << "::";
19391939
type = type->tokAt(2);
19401940
}
1941-
type->stringify(os, false, true, false);
1941+
std::string s;
1942+
type->stringify(s, false, true, false);
1943+
os << s;
19421944
if (type->strAt(1) == "*" && !argInfo->element)
19431945
os << " *";
19441946
else if (argInfo->variableInfo && !argInfo->element && argInfo->variableInfo->isArray())
@@ -1956,7 +1958,9 @@ void CheckIO::argumentType(std::ostream& os, const ArgumentInfo * argInfo)
19561958
if (type->strAt(1) == "*" || argInfo->address)
19571959
os << " *";
19581960
os << " {aka ";
1959-
type->stringify(os, false, true, false);
1961+
std::string s;
1962+
type->stringify(s, false, true, false);
1963+
os << s;
19601964
if (type->strAt(1) == "*" || argInfo->address)
19611965
os << " *";
19621966
os << "}";

lib/errorlogger.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -622,11 +622,12 @@ bool ErrorLogger::reportUnmatchedSuppressions(const std::list<Suppressions::Supp
622622

623623
std::string ErrorLogger::callStackToString(const std::list<ErrorMessage::FileLocation> &callStack)
624624
{
625-
std::ostringstream ostr;
625+
std::string str;
626626
for (std::list<ErrorMessage::FileLocation>::const_iterator tok = callStack.begin(); tok != callStack.end(); ++tok) {
627-
ostr << (tok == callStack.begin() ? "" : " -> ") << tok->stringify();
627+
str += (tok == callStack.begin() ? "" : " -> ");
628+
str += tok->stringify();
628629
}
629-
return ostr.str();
630+
return str;
630631
}
631632

632633

@@ -663,12 +664,15 @@ void ErrorMessage::FileLocation::setfile(const std::string &file)
663664

664665
std::string ErrorMessage::FileLocation::stringify() const
665666
{
666-
std::ostringstream oss;
667-
oss << '[' << Path::toNativeSeparators(mFileName);
668-
if (line != Suppressions::Suppression::NO_LINE)
669-
oss << ':' << line;
670-
oss << ']';
671-
return oss.str();
667+
std::string str;
668+
str += '[';
669+
str += Path::toNativeSeparators(mFileName);
670+
if (line != Suppressions::Suppression::NO_LINE) {
671+
str += ':';
672+
str += std::to_string(line);
673+
}
674+
str += ']';
675+
return str;
672676
}
673677

674678
std::string ErrorLogger::toxml(const std::string &str)

lib/mathlib.cpp

Lines changed: 9 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -294,24 +294,13 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
294294
{
295295
// hexadecimal numbers:
296296
if (isIntHex(str)) {
297-
if (str[0] == '-') {
298-
biguint ret = 0;
299-
std::istringstream istr(str);
300-
istr >> std::hex >> ret;
301-
return ret;
302-
} else {
303-
unsigned long long ret = 0;
304-
std::istringstream istr(str);
305-
istr >> std::hex >> ret;
306-
return (biguint)ret;
307-
}
297+
const biguint ret = std::stoull(str, nullptr, 16);
298+
return ret;
308299
}
309300

310301
// octal numbers:
311302
if (isOct(str)) {
312-
biguint ret = 0;
313-
std::istringstream istr(str);
314-
istr >> std::oct >> ret;
303+
const biguint ret = std::stoull(str, nullptr, 8);
315304
return ret;
316305
}
317306

@@ -340,9 +329,7 @@ MathLib::biguint MathLib::toULongNumber(const std::string & str)
340329
return static_cast<biguint>(doubleval);
341330
}
342331

343-
biguint ret = 0;
344-
std::istringstream istr(str);
345-
istr >> ret;
332+
const biguint ret = std::stoull(str, nullptr, 10);
346333
return ret;
347334
}
348335

@@ -488,23 +475,17 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
488475
// hexadecimal numbers:
489476
if (isIntHex(str)) {
490477
if (str[0] == '-') {
491-
bigint ret = 0;
492-
std::istringstream istr(str);
493-
istr >> std::hex >> ret;
478+
const bigint ret = std::stoll(str, nullptr, 16);
494479
return ret;
495480
} else {
496-
unsigned long long ret = 0;
497-
std::istringstream istr(str);
498-
istr >> std::hex >> ret;
481+
const biguint ret = std::stoull(str, nullptr, 16);
499482
return (bigint)ret;
500483
}
501484
}
502485

503486
// octal numbers:
504487
if (isOct(str)) {
505-
bigint ret = 0;
506-
std::istringstream istr(str);
507-
istr >> std::oct >> ret;
488+
const bigint ret = std::stoll(str, nullptr, 8);
508489
return ret;
509490
}
510491

@@ -540,15 +521,11 @@ MathLib::bigint MathLib::toLongNumber(const std::string & str)
540521
}
541522

542523
if (str[0] == '-') {
543-
bigint ret = 0;
544-
std::istringstream istr(str);
545-
istr >> ret;
524+
const bigint ret = std::stoll(str, nullptr, 10);
546525
return ret;
547526
}
548527

549-
biguint ret = 0;
550-
std::istringstream istr(str);
551-
istr >> ret;
528+
const biguint ret = std::stoull(str, nullptr, 10);
552529
return ret;
553530
}
554531

lib/symboldatabase.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3400,9 +3400,11 @@ void SymbolDatabase::printOut(const char *title) const
34003400

34013401
if (scope->type == Scope::eEnum) {
34023402
std::cout << " enumType: ";
3403-
if (scope->enumType)
3404-
scope->enumType->stringify(std::cout, false, true, false);
3405-
else
3403+
if (scope->enumType) {
3404+
std::string s;
3405+
scope->enumType->stringify(s, false, true, false);
3406+
std::cout << s;
3407+
} else
34063408
std::cout << "int";
34073409
std::cout << std::endl;
34083410
std::cout << " enumClass: " << scope->enumClass << std::endl;

lib/token.cpp

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,44 +1174,49 @@ void Token::printLines(int lines) const
11741174
std::cout << stringifyList(stringifyOptions::forDebugExprId(), nullptr, end) << std::endl;
11751175
}
11761176

1177-
void Token::stringify(std::ostream& os, const stringifyOptions& options) const
1177+
void Token::stringify(std::string& os, const stringifyOptions& options) const
11781178
{
11791179
if (options.attributes) {
11801180
if (isUnsigned())
1181-
os << "unsigned ";
1181+
os += "unsigned ";
11821182
else if (isSigned())
1183-
os << "signed ";
1183+
os += "signed ";
11841184
if (isComplex())
1185-
os << "_Complex ";
1185+
os += "_Complex ";
11861186
if (isLong()) {
11871187
if (!(mTokType == eString || mTokType == eChar))
1188-
os << "long ";
1188+
os += "long ";
11891189
}
11901190
}
11911191
if (options.macro && isExpandedMacro())
1192-
os << "$";
1192+
os += '$';
11931193
if (isName() && mStr.find(' ') != std::string::npos) {
11941194
for (char i : mStr) {
11951195
if (i != ' ')
1196-
os << i;
1196+
os += i;
11971197
}
11981198
} else if (mStr[0] != '\"' || mStr.find('\0') == std::string::npos)
1199-
os << mStr;
1199+
os += mStr;
12001200
else {
12011201
for (char i : mStr) {
12021202
if (i == '\0')
1203-
os << "\\0";
1203+
os += "\\0";
12041204
else
1205-
os << i;
1205+
os += i;
12061206
}
12071207
}
1208-
if (options.varid && mImpl->mVarId != 0)
1209-
os << "@" << (options.idtype ? "var" : "") << mImpl->mVarId;
1210-
else if (options.exprid && mImpl->mExprId != 0)
1211-
os << "@" << (options.idtype ? "expr" : "") << mImpl->mExprId;
1208+
if (options.varid && mImpl->mVarId != 0) {
1209+
os += '@';
1210+
os += (options.idtype ? "var" : "");
1211+
os += std::to_string(mImpl->mVarId);
1212+
} else if (options.exprid && mImpl->mExprId != 0) {
1213+
os += '@';
1214+
os += (options.idtype ? "expr" : "");
1215+
os += std::to_string(mImpl->mExprId);
1216+
}
12121217
}
12131218

1214-
void Token::stringify(std::ostream& os, bool varid, bool attributes, bool macro) const
1219+
void Token::stringify(std::string& os, bool varid, bool attributes, bool macro) const
12151220
{
12161221
stringifyOptions options;
12171222
options.varid = varid;
@@ -1225,7 +1230,7 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
12251230
if (this == end)
12261231
return "";
12271232

1228-
std::ostringstream ret;
1233+
std::string ret;
12291234

12301235
unsigned int lineNumber = mImpl->mLineNumber - (options.linenumbers ? 1U : 0U);
12311236
unsigned int fileIndex = options.files ? ~0U : mImpl->mFileIndex;
@@ -1239,12 +1244,12 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
12391244

12401245
fileIndex = tok->mImpl->mFileIndex;
12411246
if (options.files) {
1242-
ret << "\n\n##file ";
1247+
ret += "\n\n##file ";
12431248
if (fileNames && fileNames->size() > tok->mImpl->mFileIndex)
1244-
ret << fileNames->at(tok->mImpl->mFileIndex);
1249+
ret += fileNames->at(tok->mImpl->mFileIndex);
12451250
else
1246-
ret << fileIndex;
1247-
ret << '\n';
1251+
ret += std::to_string(fileIndex);
1252+
ret += '\n';
12481253
}
12491254

12501255
lineNumber = lineNumbers[fileIndex];
@@ -1253,27 +1258,34 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
12531258

12541259
if (options.linebreaks && (lineNumber != tok->linenr() || fileChange)) {
12551260
if (lineNumber+4 < tok->linenr() && fileIndex == tok->mImpl->mFileIndex) {
1256-
ret << '\n' << lineNumber+1 << ":\n|\n";
1257-
ret << tok->linenr()-1 << ":\n";
1258-
ret << tok->linenr() << ": ";
1261+
ret += '\n';
1262+
ret += std::to_string(lineNumber+1);
1263+
ret += ":\n|\n";
1264+
ret += std::to_string(tok->linenr()-1);
1265+
ret += ":\n";
1266+
ret += std::to_string(tok->linenr());
1267+
ret += ": ";
12591268
} else if (this == tok && options.linenumbers) {
1260-
ret << tok->linenr() << ": ";
1269+
ret += std::to_string(tok->linenr());
1270+
ret += ": ";
12611271
} else if (lineNumber > tok->linenr()) {
12621272
lineNumber = tok->linenr();
1263-
ret << '\n';
1273+
ret += '\n';
12641274
if (options.linenumbers) {
1265-
ret << lineNumber << ':';
1275+
ret += std::to_string(lineNumber);
1276+
ret += ':';
12661277
if (lineNumber == tok->linenr())
1267-
ret << ' ';
1278+
ret += ' ';
12681279
}
12691280
} else {
12701281
while (lineNumber < tok->linenr()) {
12711282
++lineNumber;
1272-
ret << '\n';
1283+
ret += '\n';
12731284
if (options.linenumbers) {
1274-
ret << lineNumber << ':';
1285+
ret += std::to_string(lineNumber);
1286+
ret += ':';
12751287
if (lineNumber == tok->linenr())
1276-
ret << ' ';
1288+
ret += ' ';
12771289
}
12781290
}
12791291
}
@@ -1282,11 +1294,11 @@ std::string Token::stringifyList(const stringifyOptions& options, const std::vec
12821294

12831295
tok->stringify(ret, options); // print token
12841296
if (tok->next() != end && (!options.linebreaks || (tok->next()->linenr() == tok->linenr() && tok->next()->fileIndex() == tok->fileIndex())))
1285-
ret << ' ';
1297+
ret += ' ';
12861298
}
12871299
if (options.linebreaks && (options.files || options.linenumbers))
1288-
ret << '\n';
1289-
return ret.str();
1300+
ret += '\n';
1301+
return ret;
12901302
}
12911303
std::string Token::stringifyList(bool varid, bool attributes, bool linenumbers, bool linebreaks, bool files, const std::vector<std::string>* fileNames, const Token* end) const
12921304
{
@@ -1472,38 +1484,38 @@ bool Token::isUnaryPreOp() const
14721484

14731485
static std::string stringFromTokenRange(const Token* start, const Token* end)
14741486
{
1475-
std::ostringstream ret;
1487+
std::string ret;
14761488
if (end)
14771489
end = end->next();
14781490
for (const Token *tok = start; tok && tok != end; tok = tok->next()) {
14791491
if (tok->isUnsigned())
1480-
ret << "unsigned ";
1492+
ret += "unsigned ";
14811493
if (tok->isLong() && !tok->isLiteral())
1482-
ret << "long ";
1494+
ret += "long ";
14831495
if (tok->tokType() == Token::eString) {
14841496
for (unsigned char c: tok->str()) {
14851497
if (c == '\n')
1486-
ret << "\\n";
1498+
ret += "\\n";
14871499
else if (c == '\r')
1488-
ret << "\\r";
1500+
ret += "\\r";
14891501
else if (c == '\t')
1490-
ret << "\\t";
1502+
ret += "\\t";
14911503
else if (c >= ' ' && c <= 126)
1492-
ret << c;
1504+
ret += c;
14931505
else {
14941506
char str[10];
14951507
sprintf(str, "\\x%02x", c);
1496-
ret << str;
1508+
ret += str;
14971509
}
14981510
}
14991511
} else if (tok->originalName().empty() || tok->isUnsigned() || tok->isLong()) {
1500-
ret << tok->str();
1512+
ret += tok->str();
15011513
} else
1502-
ret << tok->originalName();
1514+
ret += tok->originalName();
15031515
if (Token::Match(tok, "%name%|%num% %name%|%num%"))
1504-
ret << ' ';
1516+
ret += ' ';
15051517
}
1506-
return ret.str();
1518+
return ret;
15071519
}
15081520

15091521
std::string Token::expressionString() const

lib/token.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -887,7 +887,7 @@ class CPPCHECKLIB Token {
887887
}
888888
};
889889

890-
void stringify(std::ostream& os, const stringifyOptions& options) const;
890+
void stringify(std::string& os, const stringifyOptions& options) const;
891891

892892
/**
893893
* Stringify a token
@@ -896,7 +896,7 @@ class CPPCHECKLIB Token {
896896
* @param attributes Print attributes of tokens like "unsigned" in front of it.
897897
* @param macro Prints $ in front of the token if it was expanded from a macro.
898898
*/
899-
void stringify(std::ostream& os, bool varid, bool attributes, bool macro) const;
899+
void stringify(std::string& os, bool varid, bool attributes, bool macro) const;
900900

901901
std::string stringifyList(const stringifyOptions& options, const std::vector<std::string>* fileNames = nullptr, const Token* end = nullptr) const;
902902
std::string stringifyList(const Token* end, bool attributes = true) const;

0 commit comments

Comments
 (0)