Refactor: The code to generate id string from pointer can be simplified (#5382)
This commit is contained in:
parent
85332b2af6
commit
c3136dbc2a
|
@ -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 += '\"';
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 += "\" ";
|
||||
|
|
53
lib/utils.h
53
lib/utils.h
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue