Refactor: The code to generate id string from pointer can be simplified (#5382)

This commit is contained in:
Daniel Marjamäki 2023-08-31 23:14:28 +02:00 committed by GitHub
parent 85332b2af6
commit c3136dbc2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 125 deletions

View File

@ -4043,7 +4043,7 @@ void SymbolDatabase::printXml(std::ostream &out) const
for (std::list<Scope>::const_iterator scope = scopeList.cbegin(); scope != scopeList.cend(); ++scope) { for (std::list<Scope>::const_iterator scope = scopeList.cbegin(); scope != scopeList.cend(); ++scope) {
outs += " <scope"; outs += " <scope";
outs += " id=\""; outs += " id=\"";
outs += ptr_to_string(&*scope); outs += id_string(&*scope);
outs += "\""; outs += "\"";
outs += " type=\""; outs += " type=\"";
outs += scopeTypeToString(scope->type); outs += scopeTypeToString(scope->type);
@ -4055,27 +4055,27 @@ void SymbolDatabase::printXml(std::ostream &out) const
} }
if (scope->bodyStart) { if (scope->bodyStart) {
outs += " bodyStart=\""; outs += " bodyStart=\"";
outs += ptr_to_string(scope->bodyStart); outs += id_string(scope->bodyStart);
outs += '\"'; outs += '\"';
} }
if (scope->bodyEnd) { if (scope->bodyEnd) {
outs += " bodyEnd=\""; outs += " bodyEnd=\"";
outs += ptr_to_string(scope->bodyEnd); outs += id_string(scope->bodyEnd);
outs += '\"'; outs += '\"';
} }
if (scope->nestedIn) { if (scope->nestedIn) {
outs += " nestedIn=\""; outs += " nestedIn=\"";
outs += ptr_to_string(scope->nestedIn); outs += id_string(scope->nestedIn);
outs += "\""; outs += "\"";
} }
if (scope->function) { if (scope->function) {
outs += " function=\""; outs += " function=\"";
outs += ptr_to_string(scope->function); outs += id_string(scope->function);
outs += "\""; outs += "\"";
} }
if (scope->definedType) { if (scope->definedType) {
outs += " definedType=\""; outs += " definedType=\"";
outs += ptr_to_string(scope->definedType); outs += id_string(scope->definedType);
outs += "\""; outs += "\"";
} }
if (scope->functionList.empty() && scope->varlist.empty()) if (scope->functionList.empty() && scope->varlist.empty())
@ -4086,11 +4086,11 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += " <functionList>\n"; outs += " <functionList>\n";
for (std::list<Function>::const_iterator function = scope->functionList.cbegin(); function != scope->functionList.cend(); ++function) { for (std::list<Function>::const_iterator function = scope->functionList.cbegin(); function != scope->functionList.cend(); ++function) {
outs += " <function id=\""; outs += " <function id=\"";
outs += ptr_to_string(&*function); outs += id_string(&*function);
outs += "\" token=\""; outs += "\" token=\"";
outs += ptr_to_string(function->token); outs += id_string(function->token);
outs += "\" tokenDef=\""; outs += "\" tokenDef=\"";
outs += ptr_to_string(function->tokenDef); outs += id_string(function->tokenDef);
outs += "\" name=\""; outs += "\" name=\"";
outs += ErrorLogger::toxml(function->name()); outs += ErrorLogger::toxml(function->name());
outs += '\"'; outs += '\"';
@ -4123,7 +4123,7 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += " isAttributeNoreturn=\"true\""; outs += " isAttributeNoreturn=\"true\"";
if (const Function* overriddenFunction = function->getOverriddenFunction()) { if (const Function* overriddenFunction = function->getOverriddenFunction()) {
outs += " overriddenFunction=\""; outs += " overriddenFunction=\"";
outs += ptr_to_string(overriddenFunction); outs += id_string(overriddenFunction);
outs += "\""; outs += "\"";
} }
if (function->argCount() == 0U) if (function->argCount() == 0U)
@ -4135,7 +4135,7 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += " <arg nr=\""; outs += " <arg nr=\"";
outs += std::to_string(argnr+1); outs += std::to_string(argnr+1);
outs += "\" variable=\""; outs += "\" variable=\"";
outs += ptr_to_string(arg); outs += id_string(arg);
outs += "\"/>\n"; outs += "\"/>\n";
variables.insert(arg); variables.insert(arg);
} }
@ -4148,7 +4148,7 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += " <varlist>\n"; outs += " <varlist>\n";
for (std::list<Variable>::const_iterator var = scope->varlist.cbegin(); var != scope->varlist.cend(); ++var) { for (std::list<Variable>::const_iterator var = scope->varlist.cbegin(); var != scope->varlist.cend(); ++var) {
outs += " <var id=\""; outs += " <var id=\"";
outs += ptr_to_string(&*var); outs += id_string(&*var);
outs += "\"/>\n"; outs += "\"/>\n";
} }
outs += " </varlist>\n"; outs += " </varlist>\n";
@ -4162,9 +4162,9 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += " <types>\n"; outs += " <types>\n";
for (const Type& type:typeList) { for (const Type& type:typeList) {
outs += " <type id=\""; outs += " <type id=\"";
outs += ptr_to_string(&type); outs += id_string(&type);
outs += "\" classScope=\""; outs += "\" classScope=\"";
outs += ptr_to_string(type.classScope); outs += id_string(type.classScope);
outs += "\""; outs += "\"";
if (type.derivedFrom.empty()) { if (type.derivedFrom.empty()) {
outs += "/>\n"; outs += "/>\n";
@ -4177,13 +4177,13 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += accessControlToString(baseInfo.access); outs += accessControlToString(baseInfo.access);
outs += "\""; outs += "\"";
outs += " type=\""; outs += " type=\"";
outs += ptr_to_string(baseInfo.type); outs += id_string(baseInfo.type);
outs += "\""; outs += "\"";
outs += " isVirtual=\""; outs += " isVirtual=\"";
outs += bool_to_string(baseInfo.isVirtual); outs += bool_to_string(baseInfo.isVirtual);
outs += "\""; outs += "\"";
outs += " nameTok=\""; outs += " nameTok=\"";
outs += ptr_to_string(baseInfo.nameTok); outs += id_string(baseInfo.nameTok);
outs += "\""; outs += "\"";
outs += "/>\n"; outs += "/>\n";
} }
@ -4200,22 +4200,22 @@ void SymbolDatabase::printXml(std::ostream &out) const
if (!var) if (!var)
continue; continue;
outs += " <var id=\""; outs += " <var id=\"";
outs += ptr_to_string(var); outs += id_string(var);
outs += '\"'; outs += '\"';
outs += " nameToken=\""; outs += " nameToken=\"";
outs += ptr_to_string(var->nameToken()); outs += id_string(var->nameToken());
outs += '\"'; outs += '\"';
outs += " typeStartToken=\""; outs += " typeStartToken=\"";
outs += ptr_to_string(var->typeStartToken()); outs += id_string(var->typeStartToken());
outs += '\"'; outs += '\"';
outs += " typeEndToken=\""; outs += " typeEndToken=\"";
outs += ptr_to_string(var->typeEndToken()); outs += id_string(var->typeEndToken());
outs += '\"'; outs += '\"';
outs += " access=\""; outs += " access=\"";
outs += accessControlToString(var->mAccess); outs += accessControlToString(var->mAccess);
outs += '\"'; outs += '\"';
outs += " scope=\""; outs += " scope=\"";
outs += ptr_to_string(var->scope()); outs += id_string(var->scope());
outs += '\"'; outs += '\"';
if (var->valueType()) { if (var->valueType()) {
outs += " constness=\""; outs += " constness=\"";
@ -7591,7 +7591,7 @@ std::string ValueType::dump() const
case CONTAINER: { case CONTAINER: {
ret += "valueType-type=\"container\""; ret += "valueType-type=\"container\"";
ret += " valueType-containerId=\""; ret += " valueType-containerId=\"";
ret += ptr_to_string(container); ret += id_string(container);
ret += "\""; ret += "\"";
break; break;
} }
@ -7674,7 +7674,7 @@ std::string ValueType::dump() const
if (typeScope) { if (typeScope) {
ret += " valueType-typeScope=\""; ret += " valueType-typeScope=\"";
ret += ptr_to_string(typeScope); ret += id_string(typeScope);
ret += '\"'; ret += '\"';
} }

View File

@ -1710,7 +1710,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
continue; continue;
if (xml) { if (xml) {
outs += " <values id=\""; outs += " <values id=\"";
outs += ptr_to_string(values); outs += id_string(values);
outs += "\">"; outs += "\">";
outs += '\n'; outs += '\n';
} }
@ -1763,7 +1763,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
break; break;
case ValueFlow::Value::ValueType::TOK: case ValueFlow::Value::ValueType::TOK:
outs += "tokvalue=\""; outs += "tokvalue=\"";
outs += ptr_to_string(value.tokvalue); outs += id_string(value.tokvalue);
outs += '\"'; outs += '\"';
break; break;
case ValueFlow::Value::ValueType::FLOAT: case ValueFlow::Value::ValueType::FLOAT:
@ -1801,7 +1801,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
break; break;
case ValueFlow::Value::ValueType::LIFETIME: case ValueFlow::Value::ValueType::LIFETIME:
outs += "lifetime=\""; outs += "lifetime=\"";
outs += ptr_to_string(value.tokvalue); outs += id_string(value.tokvalue);
outs += '\"'; outs += '\"';
outs += " lifetime-scope=\""; outs += " lifetime-scope=\"";
outs += ValueFlow::Value::toString(value.lifetimeScope); outs += ValueFlow::Value::toString(value.lifetimeScope);
@ -1812,7 +1812,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
break; break;
case ValueFlow::Value::ValueType::SYMBOLIC: case ValueFlow::Value::ValueType::SYMBOLIC:
outs += "symbolic=\""; outs += "symbolic=\"";
outs += ptr_to_string(value.tokvalue); outs += id_string(value.tokvalue);
outs += '\"'; outs += '\"';
outs += " symbolic-delta=\""; outs += " symbolic-delta=\"";
outs += std::to_string(value.intvalue); outs += std::to_string(value.intvalue);

View File

@ -5806,7 +5806,7 @@ void Tokenizer::dump(std::ostream &out) const
outs += '\n'; outs += '\n';
for (const Token *tok = list.front(); tok; tok = tok->next()) { for (const Token *tok = list.front(); tok; tok = tok->next()) {
outs += " <token id=\""; outs += " <token id=\"";
outs += ptr_to_string(tok); outs += id_string(tok);
outs += "\" file=\""; outs += "\" file=\"";
outs += ErrorLogger::toxml(list.file(tok)); outs += ErrorLogger::toxml(list.file(tok));
outs += "\" linenr=\""; outs += "\" linenr=\"";
@ -5820,7 +5820,7 @@ void Tokenizer::dump(std::ostream &out) const
outs += '\"'; outs += '\"';
outs += " scope=\""; outs += " scope=\"";
outs += ptr_to_string(tok->scope()); outs += id_string(tok->scope());
outs += '\"'; outs += '\"';
if (tok->isName()) { if (tok->isName()) {
outs += " type=\"name\""; outs += " type=\"name\"";
@ -5880,7 +5880,7 @@ void Tokenizer::dump(std::ostream &out) const
outs += " isAttributeExport=\"true\""; outs += " isAttributeExport=\"true\"";
if (tok->link()) { if (tok->link()) {
outs += " link=\""; outs += " link=\"";
outs += ptr_to_string(tok->link()); outs += id_string(tok->link());
outs += '\"'; outs += '\"';
} }
if (tok->varId() > 0) { if (tok->varId() > 0) {
@ -5895,37 +5895,37 @@ void Tokenizer::dump(std::ostream &out) const
} }
if (tok->variable()) { if (tok->variable()) {
outs += " variable=\""; outs += " variable=\"";
outs += ptr_to_string(tok->variable()); outs += id_string(tok->variable());
outs += '\"'; outs += '\"';
} }
if (tok->function()) { if (tok->function()) {
outs += " function=\""; outs += " function=\"";
outs += ptr_to_string(tok->function()); outs += id_string(tok->function());
outs += '\"'; outs += '\"';
} }
if (!tok->values().empty()) { if (!tok->values().empty()) {
outs += " values=\""; outs += " values=\"";
outs += ptr_to_string(&tok->values()); outs += id_string(&tok->values());
outs += '\"'; outs += '\"';
} }
if (tok->type()) { if (tok->type()) {
outs += " type-scope=\""; outs += " type-scope=\"";
outs += ptr_to_string(tok->type()->classScope); outs += id_string(tok->type()->classScope);
outs += '\"'; outs += '\"';
} }
if (tok->astParent()) { if (tok->astParent()) {
outs += " astParent=\""; outs += " astParent=\"";
outs += ptr_to_string(tok->astParent()); outs += id_string(tok->astParent());
outs += '\"'; outs += '\"';
} }
if (tok->astOperand1()) { if (tok->astOperand1()) {
outs += " astOperand1=\""; outs += " astOperand1=\"";
outs += ptr_to_string(tok->astOperand1()); outs += id_string(tok->astOperand1());
outs += '\"'; outs += '\"';
} }
if (tok->astOperand2()) { if (tok->astOperand2()) {
outs += " astOperand2=\""; outs += " astOperand2=\"";
outs += ptr_to_string(tok->astOperand2()); outs += id_string(tok->astOperand2());
outs += '\"'; outs += '\"';
} }
if (!tok->originalName().empty()) { if (!tok->originalName().empty()) {
@ -5963,7 +5963,7 @@ void Tokenizer::dump(std::ostream &out) const
outs += '\n'; outs += '\n';
for (const Library::Container* c: containers) { for (const Library::Container* c: containers) {
outs += " <container id=\""; outs += " <container id=\"";
outs += ptr_to_string(c); outs += id_string(c);
outs += "\" array-like-index-op=\""; outs += "\" array-like-index-op=\"";
outs += (c->arrayLike_indexOp ? "true" : "false"); outs += (c->arrayLike_indexOp ? "true" : "false");
outs += "\" "; outs += "\" ";

View File

@ -270,34 +270,26 @@ std::size_t getArrayLength(const T (& /*unused*/)[size])
return size; return size;
} }
/** this is meant as a replacement for when we cannot print a pointer via the stream insertion operator (operator<<) for performance reasons */ /**
// TODO: should give portable value / only used by Tokenizer::dump() and underlying functions - something deterministic would also help with comparing the output * @brief get id string. i.e. for dump files
static inline std::string ptr_to_string(const void* p) * it will be a hexadecimal output.
*/
static inline std::string id_string_i(std::uintptr_t l)
{ {
#if (defined(__APPLE__) && defined(__MACH__)) if (!l)
if (p == nullptr)
return "0x0";
#elif !defined(_WIN32) || defined(__MINGW32__)
if (p == nullptr)
return "0"; return "0";
#endif
static constexpr int ptr_size = sizeof(void*); static constexpr int ptr_size = sizeof(void*);
#if defined(_WIN32) && !defined(__MINGW32__)
// two characters of each byte / contains terminating \0 // two characters of each byte / contains terminating \0
static constexpr int buf_size = (ptr_size * 2) + 1; static constexpr int buf_size = (ptr_size * 2) + 1;
#else
// two characters of each byte / contains 0x prefix and contains terminating \0
static constexpr int buf_size = (ptr_size * 2) + 2 + 1;
#endif
char buf[buf_size]; char buf[buf_size];
// needs to be signed so we don't underflow in padding loop // needs to be signed so we don't underflow in padding loop
int idx = sizeof(buf) - 1; int idx = buf_size - 1;
buf[idx--] = '\0'; // terminate string buf[idx] = '\0';
uintptr_t l = reinterpret_cast<uintptr_t>(p);
while (l != 0) while (l != 0)
{ {
char c; char c;
@ -307,34 +299,19 @@ static inline std::string ptr_to_string(const void* p)
c = '0' + temp; c = '0' + temp;
} }
else { else {
#if !defined(_WIN32) || defined(__MINGW32__)
// a-f // a-f
c = 'a' + (temp - 10); c = 'a' + (temp - 10);
#else
// A-F
c = 'A' + (temp - 10);
#endif
} }
buf[idx--] = c; // store in reverse order buf[--idx] = c; // store in reverse order
l = l / 16; l = l / 16;
} }
#if defined(_WIN32) && !defined(__MINGW32__) return &buf[idx];
// pad address with 0 }
while (idx >= 0) {
buf[idx--] = '0';
}
// 000000F0A61FF122 or 0230FB33 static inline std::string id_string(const void* p)
return buf; {
#else return id_string_i(reinterpret_cast<uintptr_t>(p));
// add 0x prefix
buf[idx--] = 'x';
buf[idx--] = '0';
// 0x7ffc5aa334d8
return &buf[idx+1];
#endif
} }
static inline std::string bool_to_string(bool b) static inline std::string bool_to_string(bool b)

View File

@ -38,7 +38,7 @@ private:
TEST_CASE(isStringLiteral); TEST_CASE(isStringLiteral);
TEST_CASE(isCharLiteral); TEST_CASE(isCharLiteral);
TEST_CASE(strToInt); TEST_CASE(strToInt);
TEST_CASE(ptrToString); TEST_CASE(id_string);
} }
void isValidGlobPattern() const { void isValidGlobPattern() const {
@ -334,55 +334,15 @@ private:
} }
} }
void ptrToString() const void id_string() const
{ {
struct Dummy {}; ASSERT_EQUALS("0", id_string_i(0));
// stack address ASSERT_EQUALS("f1", id_string_i(0xF1));
{ ASSERT_EQUALS("123", id_string_i(0x123));
const Dummy d; ASSERT_EQUALS("1230", id_string_i(0x1230));
const Dummy* const dp = &d; ASSERT_EQUALS(std::string(8,'f'), id_string_i(0xffffffffU));
std::ostringstream oss; if (sizeof(void*) == 8) {
oss << dp; ASSERT_EQUALS(std::string(16,'f'), id_string_i(~0ULL));
ASSERT_EQUALS(oss.str(), ptr_to_string(dp));
}
// highest address
{
// NOLINTNEXTLINE(performance-no-int-to-ptr)
const void* const p = reinterpret_cast<void*>(std::numeric_limits<uintptr_t>::max());
std::ostringstream oss;
oss << p;
ASSERT_EQUALS(oss.str(), ptr_to_string(p));
}
// same in-between address
{
const Dummy d;
const Dummy* dp = &d;
dp = dp - ((unsigned long long)dp / 2);
std::ostringstream oss;
oss << dp;
ASSERT_EQUALS(oss.str(), ptr_to_string(dp));
}
// lowest address
{
// NOLINTNEXTLINE(performance-no-int-to-ptr)
const void* const p = reinterpret_cast<void*>(std::numeric_limits<uintptr_t>::min() + 1);
std::ostringstream oss;
oss << p;
ASSERT_EQUALS(oss.str(), ptr_to_string(p));
}
// heap address
{
const auto dp = std::unique_ptr<Dummy>(new Dummy);
std::ostringstream oss;
oss << dp.get();
ASSERT_EQUALS(oss.str(), ptr_to_string(dp.get()));
}
// NULL pointer
{
const Dummy* const dp = nullptr;
std::ostringstream oss;
oss << dp;
ASSERT_EQUALS(oss.str(), ptr_to_string(dp));
} }
} }
}; };