Skip to content

Commit 5b32407

Browse files
committed
avoid expensive std::ostream usage in SymbolDatabase::printXml()
1 parent ab1145b commit 5b32407

File tree

1 file changed

+215
-105
lines changed

1 file changed

+215
-105
lines changed

lib/symboldatabase.cpp

Lines changed: 215 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -3615,26 +3615,50 @@ bool Variable::arrayDimensions(const Settings* settings, bool& isContainer)
36153615
return arr;
36163616
}
36173617

3618+
static std::string scopeTypeToString(Scope::ScopeType type)
3619+
{
3620+
switch (type) {
3621+
case Scope::ScopeType::eGlobal:
3622+
return "Global";
3623+
case Scope::ScopeType::eClass:
3624+
return "Class";
3625+
case Scope::ScopeType::eStruct:
3626+
return "Struct";
3627+
case Scope::ScopeType::eUnion:
3628+
return "Union";
3629+
case Scope::ScopeType::eNamespace:
3630+
return "Namespace";
3631+
case Scope::ScopeType::eFunction:
3632+
return "Function";
3633+
case Scope::ScopeType::eIf:
3634+
return "If";
3635+
case Scope::ScopeType::eElse:
3636+
return "Else";
3637+
case Scope::ScopeType::eFor:
3638+
return "For";
3639+
case Scope::ScopeType::eWhile:
3640+
return "While";
3641+
case Scope::ScopeType::eDo:
3642+
return "Do";
3643+
case Scope::ScopeType::eSwitch:
3644+
return "Switch";
3645+
case Scope::ScopeType::eTry:
3646+
return "Try";
3647+
case Scope::ScopeType::eCatch:
3648+
return "Catch";
3649+
case Scope::ScopeType::eUnconditional:
3650+
return "Unconditional";
3651+
case Scope::ScopeType::eLambda:
3652+
return "Lambda";
3653+
case Scope::ScopeType::eEnum:
3654+
return "Enum";
3655+
}
3656+
return "Unknown";
3657+
}
3658+
36183659
static std::ostream & operator << (std::ostream & s, Scope::ScopeType type)
36193660
{
3620-
s << (type == Scope::eGlobal ? "Global" :
3621-
type == Scope::eClass ? "Class" :
3622-
type == Scope::eStruct ? "Struct" :
3623-
type == Scope::eUnion ? "Union" :
3624-
type == Scope::eNamespace ? "Namespace" :
3625-
type == Scope::eFunction ? "Function" :
3626-
type == Scope::eIf ? "If" :
3627-
type == Scope::eElse ? "Else" :
3628-
type == Scope::eFor ? "For" :
3629-
type == Scope::eWhile ? "While" :
3630-
type == Scope::eDo ? "Do" :
3631-
type == Scope::eSwitch ? "Switch" :
3632-
type == Scope::eTry ? "Try" :
3633-
type == Scope::eCatch ? "Catch" :
3634-
type == Scope::eUnconditional ? "Unconditional" :
3635-
type == Scope::eLambda ? "Lambda" :
3636-
type == Scope::eEnum ? "Enum" :
3637-
"Unknown");
3661+
s << scopeTypeToString(type);
36383662
return s;
36393663
}
36403664

@@ -4010,137 +4034,223 @@ void SymbolDatabase::printOut(const char *title) const
40104034

40114035
void SymbolDatabase::printXml(std::ostream &out) const
40124036
{
4013-
out << std::setiosflags(std::ios::boolalpha);
4037+
std::string outs;
40144038

40154039
std::set<const Variable *> variables;
40164040

40174041
// Scopes..
4018-
out << " <scopes>" << std::endl;
4042+
outs += " <scopes>\n";
40194043
for (std::list<Scope>::const_iterator scope = scopeList.cbegin(); scope != scopeList.cend(); ++scope) {
4020-
out << " <scope";
4021-
out << " id=\"" << &*scope << "\"";
4022-
out << " type=\"" << scope->type << "\"";
4023-
if (!scope->className.empty())
4024-
out << " className=\"" << ErrorLogger::toxml(scope->className) << "\"";
4025-
if (scope->bodyStart)
4026-
out << " bodyStart=\"" << scope->bodyStart << '\"';
4027-
if (scope->bodyEnd)
4028-
out << " bodyEnd=\"" << scope->bodyEnd << '\"';
4029-
if (scope->nestedIn)
4030-
out << " nestedIn=\"" << scope->nestedIn << "\"";
4031-
if (scope->function)
4032-
out << " function=\"" << scope->function << "\"";
4033-
if (scope->definedType)
4034-
out << " definedType=\"" << scope->definedType << "\"";
4044+
outs += " <scope";
4045+
outs += " id=\"";
4046+
outs += ptr_to_string(&*scope);
4047+
outs += "\"";
4048+
outs += " type=\"";
4049+
outs += scopeTypeToString(scope->type);
4050+
outs += "\"";
4051+
if (!scope->className.empty()) {
4052+
outs += " className=\"";
4053+
outs += ErrorLogger::toxml(scope->className);
4054+
outs += "\"";
4055+
}
4056+
if (scope->bodyStart) {
4057+
outs += " bodyStart=\"";
4058+
outs += ptr_to_string(scope->bodyStart);
4059+
outs += '\"';
4060+
}
4061+
if (scope->bodyEnd) {
4062+
outs += " bodyEnd=\"";
4063+
outs += ptr_to_string(scope->bodyEnd);
4064+
outs += '\"';
4065+
}
4066+
if (scope->nestedIn) {
4067+
outs += " nestedIn=\"";
4068+
outs += ptr_to_string(scope->nestedIn);
4069+
outs += "\"";
4070+
}
4071+
if (scope->function) {
4072+
outs += " function=\"";
4073+
outs += ptr_to_string(scope->function);
4074+
outs += "\"";
4075+
}
4076+
if (scope->definedType) {
4077+
outs += " definedType=\"";
4078+
outs += ptr_to_string(scope->definedType);
4079+
outs += "\"";
4080+
}
40354081
if (scope->functionList.empty() && scope->varlist.empty())
4036-
out << "/>" << std::endl;
4082+
outs += "/>\n";
40374083
else {
4038-
out << '>' << std::endl;
4084+
outs += ">\n";
40394085
if (!scope->functionList.empty()) {
4040-
out << " <functionList>" << std::endl;
4086+
outs += " <functionList>\n";
40414087
for (std::list<Function>::const_iterator function = scope->functionList.cbegin(); function != scope->functionList.cend(); ++function) {
4042-
out << " <function id=\"" << &*function
4043-
<< "\" token=\"" << function->token
4044-
<< "\" tokenDef=\"" << function->tokenDef
4045-
<< "\" name=\"" << ErrorLogger::toxml(function->name()) << '\"';
4046-
out << " type=\"" << (function->type == Function::eConstructor? "Constructor" :
4047-
function->type == Function::eCopyConstructor ? "CopyConstructor" :
4048-
function->type == Function::eMoveConstructor ? "MoveConstructor" :
4049-
function->type == Function::eOperatorEqual ? "OperatorEqual" :
4050-
function->type == Function::eDestructor ? "Destructor" :
4051-
function->type == Function::eFunction ? "Function" :
4052-
function->type == Function::eLambda ? "Lambda" :
4053-
"Unknown") << '\"';
4088+
outs += " <function id=\"";
4089+
outs += ptr_to_string(&*function);
4090+
outs += "\" token=\"";
4091+
outs += ptr_to_string(function->token);
4092+
outs += "\" tokenDef=\"";
4093+
outs += ptr_to_string(function->tokenDef);
4094+
outs += "\" name=\"";
4095+
outs += ErrorLogger::toxml(function->name());
4096+
outs += '\"';
4097+
outs += " type=\"";
4098+
outs += (function->type == Function::eConstructor? "Constructor" :
4099+
function->type == Function::eCopyConstructor ? "CopyConstructor" :
4100+
function->type == Function::eMoveConstructor ? "MoveConstructor" :
4101+
function->type == Function::eOperatorEqual ? "OperatorEqual" :
4102+
function->type == Function::eDestructor ? "Destructor" :
4103+
function->type == Function::eFunction ? "Function" :
4104+
function->type == Function::eLambda ? "Lambda" :
4105+
"Unknown");
4106+
outs += '\"';
40544107
if (function->nestedIn->definedType) {
40554108
if (function->hasVirtualSpecifier())
4056-
out << " hasVirtualSpecifier=\"true\"";
4109+
outs += " hasVirtualSpecifier=\"true\"";
40574110
else if (function->isImplicitlyVirtual())
4058-
out << " isImplicitlyVirtual=\"true\"";
4111+
outs += " isImplicitlyVirtual=\"true\"";
4112+
}
4113+
if (function->access == AccessControl::Public || function->access == AccessControl::Protected || function->access == AccessControl::Private) {
4114+
outs += " access=\"";
4115+
outs += accessControlToString(function->access);
4116+
outs +="\"";
40594117
}
4060-
if (function->access == AccessControl::Public || function->access == AccessControl::Protected || function->access == AccessControl::Private)
4061-
out << " access=\"" << accessControlToString(function->access) << "\"";
40624118
if (function->isInlineKeyword())
4063-
out << " isInlineKeyword=\"true\"";
4119+
outs += " isInlineKeyword=\"true\"";
40644120
if (function->isStatic())
4065-
out << " isStatic=\"true\"";
4121+
outs += " isStatic=\"true\"";
40664122
if (function->isAttributeNoreturn())
4067-
out << " isAttributeNoreturn=\"true\"";
4068-
if (const Function* overriddenFunction = function->getOverriddenFunction())
4069-
out << " overriddenFunction=\"" << overriddenFunction << "\"";
4123+
outs += " isAttributeNoreturn=\"true\"";
4124+
if (const Function* overriddenFunction = function->getOverriddenFunction()) {
4125+
outs += " overriddenFunction=\"";
4126+
outs += ptr_to_string(overriddenFunction);
4127+
outs += "\"";
4128+
}
40704129
if (function->argCount() == 0U)
4071-
out << "/>" << std::endl;
4130+
outs += "/>\n";
40724131
else {
4073-
out << ">" << std::endl;
4132+
outs += ">\n";
40744133
for (unsigned int argnr = 0; argnr < function->argCount(); ++argnr) {
40754134
const Variable *arg = function->getArgumentVar(argnr);
4076-
out << " <arg nr=\"" << argnr+1 << "\" variable=\"" << arg << "\"/>" << std::endl;
4135+
outs += " <arg nr=\"";
4136+
outs += std::to_string(argnr+1);
4137+
outs += "\" variable=\"";
4138+
outs += ptr_to_string(arg);
4139+
outs += "\"/>\n";
40774140
variables.insert(arg);
40784141
}
4079-
out << " </function>" << std::endl;
4142+
outs += " </function>\n";
40804143
}
40814144
}
4082-
out << " </functionList>" << std::endl;
4145+
outs += " </functionList>\n";
40834146
}
40844147
if (!scope->varlist.empty()) {
4085-
out << " <varlist>" << std::endl;
4086-
for (std::list<Variable>::const_iterator var = scope->varlist.cbegin(); var != scope->varlist.cend(); ++var)
4087-
out << " <var id=\"" << &*var << "\"/>" << std::endl;
4088-
out << " </varlist>" << std::endl;
4148+
outs += " <varlist>\n";
4149+
for (std::list<Variable>::const_iterator var = scope->varlist.cbegin(); var != scope->varlist.cend(); ++var) {
4150+
outs += " <var id=\"";
4151+
outs += ptr_to_string(&*var);
4152+
outs += "\"/>\n";
4153+
}
4154+
outs += " </varlist>\n";
40894155
}
4090-
out << " </scope>" << std::endl;
4156+
outs += " </scope>\n";
40914157
}
40924158
}
4093-
out << " </scopes>" << std::endl;
4159+
outs += " </scopes>\n";
40944160

40954161
if (!typeList.empty()) {
4096-
out << " <types>\n";
4162+
outs += " <types>\n";
40974163
for (const Type& type:typeList) {
4098-
out << " <type id=\"" << &type << "\" classScope=\"" << type.classScope << "\"";
4164+
outs += " <type id=\"";
4165+
outs += ptr_to_string(&type);
4166+
outs += "\" classScope=\"";
4167+
outs += ptr_to_string(type.classScope);
4168+
outs += "\"";
40994169
if (type.derivedFrom.empty()) {
4100-
out << "/>\n";
4170+
outs += "/>\n";
41014171
continue;
41024172
}
4103-
out << ">\n";
4173+
outs += ">\n";
41044174
for (const Type::BaseInfo& baseInfo: type.derivedFrom) {
4105-
out << " <derivedFrom"
4106-
<< " access=\"" << accessControlToString(baseInfo.access) << "\""
4107-
<< " type=\"" << baseInfo.type << "\""
4108-
<< " isVirtual=\"" << (baseInfo.isVirtual ? "true" : "false") << "\""
4109-
<< " nameTok=\"" << baseInfo.nameTok << "\""
4110-
<< "/>\n";
4111-
}
4112-
out << " </type>\n";
4113-
}
4114-
out << " </types>\n";
4175+
outs += " <derivedFrom";
4176+
outs += " access=\"";
4177+
outs += accessControlToString(baseInfo.access);
4178+
outs += "\"";
4179+
outs += " type=\"";
4180+
outs += ptr_to_string(baseInfo.type);
4181+
outs += "\"";
4182+
outs += " isVirtual=\"";
4183+
outs += bool_to_string(baseInfo.isVirtual);
4184+
outs += "\"";
4185+
outs += " nameTok=\"";
4186+
outs += ptr_to_string(baseInfo.nameTok);
4187+
outs += "\"";
4188+
outs += "/>\n";
4189+
}
4190+
outs += " </type>\n";
4191+
}
4192+
outs += " </types>\n";
41154193
}
41164194

41174195
// Variables..
41184196
for (const Variable *var : mVariableList)
41194197
variables.insert(var);
4120-
out << " <variables>" << std::endl;
4198+
outs += " <variables>\n";
41214199
for (const Variable *var : variables) {
41224200
if (!var)
41234201
continue;
4124-
out << " <var id=\"" << var << '\"';
4125-
out << " nameToken=\"" << var->nameToken() << '\"';
4126-
out << " typeStartToken=\"" << var->typeStartToken() << '\"';
4127-
out << " typeEndToken=\"" << var->typeEndToken() << '\"';
4128-
out << " access=\"" << accessControlToString(var->mAccess) << '\"';
4129-
out << " scope=\"" << var->scope() << '\"';
4130-
if (var->valueType())
4131-
out << " constness=\"" << var->valueType()->constness << '\"';
4132-
out << " isArray=\"" << var->isArray() << '\"';
4133-
out << " isClass=\"" << var->isClass() << '\"';
4134-
out << " isConst=\"" << var->isConst() << '\"';
4135-
out << " isExtern=\"" << var->isExtern() << '\"';
4136-
out << " isPointer=\"" << var->isPointer() << '\"';
4137-
out << " isReference=\"" << var->isReference() << '\"';
4138-
out << " isStatic=\"" << var->isStatic() << '\"';
4139-
out << " isVolatile=\"" << var->isVolatile() << '\"';
4140-
out << "/>" << std::endl;
4141-
}
4142-
out << " </variables>" << std::endl;
4143-
out << std::resetiosflags(std::ios::boolalpha);
4202+
outs += " <var id=\"";
4203+
outs += ptr_to_string(var);
4204+
outs += '\"';
4205+
outs += " nameToken=\"";
4206+
outs += ptr_to_string(var->nameToken());
4207+
outs += '\"';
4208+
outs += " typeStartToken=\"";
4209+
outs += ptr_to_string(var->typeStartToken());
4210+
outs += '\"';
4211+
outs += " typeEndToken=\"";
4212+
outs += ptr_to_string(var->typeEndToken());
4213+
outs += '\"';
4214+
outs += " access=\"";
4215+
outs += accessControlToString(var->mAccess);
4216+
outs += '\"';
4217+
outs += " scope=\"";
4218+
outs += ptr_to_string(var->scope());
4219+
outs += '\"';
4220+
if (var->valueType()) {
4221+
outs += " constness=\"";
4222+
outs += std::to_string(var->valueType()->constness);
4223+
outs += '\"';
4224+
}
4225+
outs += " isArray=\"";
4226+
outs += bool_to_string(var->isArray());
4227+
outs += '\"';
4228+
outs += " isClass=\"";
4229+
outs += bool_to_string(var->isClass());
4230+
outs += '\"';
4231+
outs += " isConst=\"";
4232+
outs += bool_to_string(var->isConst());
4233+
outs += '\"';
4234+
outs += " isExtern=\"";
4235+
outs += bool_to_string(var->isExtern());
4236+
outs += '\"';
4237+
outs += " isPointer=\"";
4238+
outs += bool_to_string(var->isPointer());
4239+
outs += '\"';
4240+
outs += " isReference=\"";
4241+
outs += bool_to_string(var->isReference());
4242+
outs += '\"';
4243+
outs += " isStatic=\"";
4244+
outs += bool_to_string(var->isStatic());
4245+
outs += '\"';
4246+
outs += " isVolatile=\"";
4247+
outs += bool_to_string(var->isVolatile());
4248+
outs += '\"';
4249+
outs += "/>\n";
4250+
}
4251+
outs += " </variables>\n";
4252+
4253+
out << outs;
41444254
}
41454255

41464256
//---------------------------------------------------------------------------

0 commit comments

Comments
 (0)