C++: display enum value in tooltip for simplest case

If it is possible lets calculate enum value for the simplest case.
Example where it works:
enum
{
  enum_val1, // tooltip = "enum_val1 = 0"
  enum_val2 // tooltip = "enum_val2 = 1"
};

enum
{
  enum_val1=10, // tooltip = "enum_val1 = 10"
  enum_val2 // tooltip = "enum_val2 = 11"
};

enum
{
  enum_val1, // tooltip = "enum_val1 = 0"
  enum_val2=10, // tooltip = "enum_val2 = 10"
  enum_val3 // tooltip = "enum_val3 = 11"
};

Example where it does not work:
enum
{
  enum_val1=10+1, // tooltip = "enum_val1 = 10+1"
  enum_val2 // tooltip = "enum_val2"
};

Task-number: QTCREATORBUG-4529
Change-Id: Idd85ed7304018f73f2b068bf1ac28f1abde02f93
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Przemyslaw Gorszkowski
2014-12-02 10:57:08 +01:00
parent f66ee66595
commit 9e159d87a8
3 changed files with 165 additions and 2 deletions

View File

@@ -33,7 +33,7 @@
#include <vector>
#include <string>
#include <memory>
#include <sstream>
using namespace CPlusPlus;
@@ -459,6 +459,58 @@ bool Bind::visit(EnumeratorAST *ast)
return false;
}
namespace {
bool isInteger(const StringLiteral *stringLiteral)
{
const int size = stringLiteral->size();
const char *chars = stringLiteral->chars();
for (int i = 0; i < size; ++i) {
if (!isdigit(chars[i]))
return false;
}
return true;
}
bool stringLiteralToInt(const StringLiteral *stringLiteral, int *output)
{
if (!output)
return false;
if (!isInteger(stringLiteral)) {
*output = 0;
return false;
}
std::stringstream ss(std::string(stringLiteral->chars(), stringLiteral->size()));
const bool ok = ss >> *output;
if (!ok)
*output = 0;
return ok;
}
void calculateConstantValue(const Symbol *symbol, EnumeratorDeclaration *e, Control *control)
{
if (symbol) {
if (const Declaration *decl = symbol->asDeclaration()) {
if (const EnumeratorDeclaration *previousEnumDecl = decl->asEnumeratorDeclarator()) {
if (const StringLiteral *constantValue = previousEnumDecl->constantValue()) {
int constantValueAsInt = 0;
if (stringLiteralToInt(constantValue, &constantValueAsInt)) {
++constantValueAsInt;
const std::string buffer = std::to_string(constantValueAsInt);
e->setConstantValue(control->stringLiteral(buffer.c_str(),
unsigned(buffer.size())));
}
}
}
}
}
}
} // anonymous namespace
void Bind::enumerator(EnumeratorAST *ast, Enum *symbol)
{
(void) symbol;
@@ -477,6 +529,10 @@ void Bind::enumerator(EnumeratorAST *ast, Enum *symbol)
if (ExpressionAST *expr = ast->expression)
e->setConstantValue(asStringLiteral(expr->firstToken(), expr->lastToken()));
else if (!symbol->isEmpty())
calculateConstantValue(*(symbol->lastMember()-1), e, control());
else
e->setConstantValue(control()->stringLiteral("0", 1));
symbol->addMember(e);
}