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

View File

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

View File

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

View File

@ -270,34 +270,26 @@ std::size_t getArrayLength(const T (& /*unused*/)[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
static inline std::string ptr_to_string(const void* p)
/**
* @brief get id string. i.e. for dump files
* it will be a hexadecimal output.
*/
static inline std::string id_string_i(std::uintptr_t l)
{
#if (defined(__APPLE__) && defined(__MACH__))
if (p == nullptr)
return "0x0";
#elif !defined(_WIN32) || defined(__MINGW32__)
if (p == nullptr)
if (!l)
return "0";
#endif
static constexpr int ptr_size = sizeof(void*);
#if defined(_WIN32) && !defined(__MINGW32__)
// two characters of each byte / contains terminating \0
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];
// needs to be signed so we don't underflow in padding loop
int idx = sizeof(buf) - 1;
buf[idx--] = '\0'; // terminate string
int idx = buf_size - 1;
buf[idx] = '\0';
uintptr_t l = reinterpret_cast<uintptr_t>(p);
while (l != 0)
{
char c;
@ -307,34 +299,19 @@ static inline std::string ptr_to_string(const void* p)
c = '0' + temp;
}
else {
#if !defined(_WIN32) || defined(__MINGW32__)
// a-f
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;
}
#if defined(_WIN32) && !defined(__MINGW32__)
// pad address with 0
while (idx >= 0) {
buf[idx--] = '0';
}
return &buf[idx];
}
// 000000F0A61FF122 or 0230FB33
return buf;
#else
// add 0x prefix
buf[idx--] = 'x';
buf[idx--] = '0';
// 0x7ffc5aa334d8
return &buf[idx+1];
#endif
static inline std::string id_string(const void* p)
{
return id_string_i(reinterpret_cast<uintptr_t>(p));
}
static inline std::string bool_to_string(bool b)

View File

@ -38,7 +38,7 @@ private:
TEST_CASE(isStringLiteral);
TEST_CASE(isCharLiteral);
TEST_CASE(strToInt);
TEST_CASE(ptrToString);
TEST_CASE(id_string);
}
void isValidGlobPattern() const {
@ -334,55 +334,15 @@ private:
}
}
void ptrToString() const
void id_string() const
{
struct Dummy {};
// stack address
{
const Dummy d;
const Dummy* const dp = &d;
std::ostringstream oss;
oss << dp;
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));
ASSERT_EQUALS("0", id_string_i(0));
ASSERT_EQUALS("f1", id_string_i(0xF1));
ASSERT_EQUALS("123", id_string_i(0x123));
ASSERT_EQUALS("1230", id_string_i(0x1230));
ASSERT_EQUALS(std::string(8,'f'), id_string_i(0xffffffffU));
if (sizeof(void*) == 8) {
ASSERT_EQUALS(std::string(16,'f'), id_string_i(~0ULL));
}
}
};