diff options
author | Przemyslaw Gorszkowski <pgorszkowski@gmail.com> | 2015-02-09 09:44:00 +0100 |
---|---|---|
committer | Orgad Shaneh <orgads@gmail.com> | 2015-02-25 15:01:02 +0000 |
commit | 9e513774b112baaac1414eccc07c50661ce76452 (patch) | |
tree | c95484d03272df82e4cd13b042441fbe554ec2ad /src/libs/3rdparty/cplusplus/Bind.cpp | |
parent | e0eac5824bf911eff6d87d8b87ed057ee058fc4c (diff) |
C++: resolved self-value reference for enum
Added support for resolving case:
enum E
{
val1,
val2 = val1, // val2-4 are not resolved
val3,
val4
};
Task-number: QTCREATORBUG-13932
Change-Id: I122c5eb0b0397d6c02bc3db0a5c1ea1c28c5c6e7
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
Diffstat (limited to 'src/libs/3rdparty/cplusplus/Bind.cpp')
-rw-r--r-- | src/libs/3rdparty/cplusplus/Bind.cpp | 35 |
1 files changed, 31 insertions, 4 deletions
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 58e3815a8f..a0a0e1a065 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -510,6 +510,24 @@ void calculateConstantValue(const Symbol *symbol, EnumeratorDeclaration *e, Cont } } +const StringLiteral *valueOfEnumerator(const Enum *e, const Identifier *value) { + const int enumMemberCount = e->memberCount(); + for (int i = 0; i < enumMemberCount; ++i) { + const Symbol *member = e->memberAt(i); + if (const Declaration *decl = member->asDeclaration()) { + if (const EnumeratorDeclaration *enumDecl = decl->asEnumeratorDeclarator()) { + if (const Name *enumDeclName = enumDecl->name()) { + if (const Identifier *enumDeclIdentifier = enumDeclName->identifier()) { + if (enumDeclIdentifier->equalTo(value)) + return enumDecl->constantValue(); + } + } + } + } + } + return 0; +} + } // anonymous namespace void Bind::enumerator(EnumeratorAST *ast, Enum *symbol) @@ -528,12 +546,21 @@ void Bind::enumerator(EnumeratorAST *ast, Enum *symbol) EnumeratorDeclaration *e = control()->newEnumeratorDeclaration(ast->identifier_token, name); e->setType(control()->integerType(IntegerType::Int)); // ### introduce IntegerType::Enumerator - if (ExpressionAST *expr = ast->expression) - e->setConstantValue(asStringLiteral(expr->firstToken(), expr->lastToken())); - else if (!symbol->isEmpty()) + if (ExpressionAST *expr = ast->expression) { + const int firstToken = expr->firstToken(); + const int lastToken = expr->lastToken(); + const StringLiteral *constantValue = asStringLiteral(firstToken, lastToken); + const StringLiteral *resolvedValue = 0; + if (lastToken - firstToken == 1) { + if (const Identifier *constantId = identifier(firstToken)) + resolvedValue = valueOfEnumerator(symbol, constantId); + } + e->setConstantValue(resolvedValue ? resolvedValue : constantValue); + } else if (!symbol->isEmpty()) { calculateConstantValue(*(symbol->memberEnd()-1), e, control()); - else + } else { e->setConstantValue(control()->stringLiteral("0", 1)); + } symbol->addMember(e); } |