forked from qt-creator/qt-creator
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>
This commit is contained in:
committed by
Orgad Shaneh
parent
e0eac5824b
commit
9e513774b1
35
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
35
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -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
|
} // anonymous namespace
|
||||||
|
|
||||||
void Bind::enumerator(EnumeratorAST *ast, Enum *symbol)
|
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);
|
EnumeratorDeclaration *e = control()->newEnumeratorDeclaration(ast->identifier_token, name);
|
||||||
e->setType(control()->integerType(IntegerType::Int)); // ### introduce IntegerType::Enumerator
|
e->setType(control()->integerType(IntegerType::Int)); // ### introduce IntegerType::Enumerator
|
||||||
|
|
||||||
if (ExpressionAST *expr = ast->expression)
|
if (ExpressionAST *expr = ast->expression) {
|
||||||
e->setConstantValue(asStringLiteral(expr->firstToken(), expr->lastToken()));
|
const int firstToken = expr->firstToken();
|
||||||
else if (!symbol->isEmpty())
|
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());
|
calculateConstantValue(*(symbol->memberEnd()-1), e, control());
|
||||||
else
|
} else {
|
||||||
e->setConstantValue(control()->stringLiteral("0", 1));
|
e->setConstantValue(control()->stringLiteral("0", 1));
|
||||||
|
}
|
||||||
|
|
||||||
symbol->addMember(e);
|
symbol->addMember(e);
|
||||||
}
|
}
|
||||||
|
@@ -189,6 +189,7 @@ private slots:
|
|||||||
void enum_constantValue2();
|
void enum_constantValue2();
|
||||||
void enum_constantValue3();
|
void enum_constantValue3();
|
||||||
void enum_constantValue4();
|
void enum_constantValue4();
|
||||||
|
void enum_constantValue5();
|
||||||
};
|
};
|
||||||
|
|
||||||
void tst_Semantic::function_declaration_1()
|
void tst_Semantic::function_declaration_1()
|
||||||
@@ -890,5 +891,30 @@ void tst_Semantic::enum_constantValue4()
|
|||||||
testEnumaratorDeclarator(e, 4, "11");
|
testEnumaratorDeclarator(e, 4, "11");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_Semantic::enum_constantValue5()
|
||||||
|
{
|
||||||
|
QSharedPointer<Document> doc = document("\n"
|
||||||
|
"enum {\n"
|
||||||
|
"E1,\n"
|
||||||
|
"E2=E1,\n"
|
||||||
|
"E3,\n"
|
||||||
|
"E4=E3,\n"
|
||||||
|
"E5\n"
|
||||||
|
"};\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
QCOMPARE(doc->errorCount, 0U);
|
||||||
|
QCOMPARE(doc->globals->memberCount(), 1U);
|
||||||
|
Enum *e = doc->globals->memberAt(0)->asEnum();
|
||||||
|
QVERIFY(e);
|
||||||
|
QCOMPARE(e->memberCount(), 5U);
|
||||||
|
|
||||||
|
testEnumaratorDeclarator(e, 0, "0");
|
||||||
|
testEnumaratorDeclarator(e, 1, "0");
|
||||||
|
testEnumaratorDeclarator(e, 2, "1");
|
||||||
|
testEnumaratorDeclarator(e, 3, "1");
|
||||||
|
testEnumaratorDeclarator(e, 4, "2");
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_Semantic)
|
QTEST_MAIN(tst_Semantic)
|
||||||
#include "tst_semantic.moc"
|
#include "tst_semantic.moc"
|
||||||
|
Reference in New Issue
Block a user