aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/cplusplus/Bind.cpp
diff options
context:
space:
mode:
authorPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2015-02-09 09:44:00 +0100
committerOrgad Shaneh <orgads@gmail.com>2015-02-25 15:01:02 +0000
commit9e513774b112baaac1414eccc07c50661ce76452 (patch)
treec95484d03272df82e4cd13b042441fbe554ec2ad /src/libs/3rdparty/cplusplus/Bind.cpp
parente0eac5824bf911eff6d87d8b87ed057ee058fc4c (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.cpp35
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);
}