forked from qt-creator/qt-creator
C++: fix nested anonymous with __attribute__
Task-number: QTCREATORBUG-12345 Change-Id: Ib2316ebdc81393b38185b9cb659fb85b78753e7b Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com> Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
committed by
Nikolai Kosjar
parent
aae1abdacc
commit
b90452e309
12
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
12
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -1988,12 +1988,6 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
||||
NameAST *name = 0;
|
||||
parseName(name);
|
||||
|
||||
if (! name && LA() == T_LBRACE && (LA(0) == T_CLASS || LA(0) == T_STRUCT || LA(0) == T_UNION || LA(0) == T_ENUM)) {
|
||||
AnonymousNameAST *ast = new (_pool) AnonymousNameAST;
|
||||
ast->class_token = classkey_token;
|
||||
name = ast;
|
||||
}
|
||||
|
||||
bool parsed = false;
|
||||
|
||||
const bool previousInFunctionBody = _inFunctionBody;
|
||||
@@ -2010,6 +2004,12 @@ bool Parser::parseClassSpecifier(SpecifierListAST *&node)
|
||||
}
|
||||
|
||||
if (LA() == T_COLON || LA() == T_LBRACE) {
|
||||
if (!name) {
|
||||
AnonymousNameAST *ast = new (_pool) AnonymousNameAST;
|
||||
ast->class_token = classkey_token;
|
||||
name = ast;
|
||||
}
|
||||
|
||||
BaseSpecifierListAST *base_clause_list = 0;
|
||||
|
||||
if (LA() == T_COLON) {
|
||||
|
@@ -1856,6 +1856,20 @@ void CppToolsPlugin::test_completion_data()
|
||||
<< QLatin1String("val2")
|
||||
<< QLatin1String("val3"));
|
||||
|
||||
QTest::newRow("nested_anonymous_with___attribute__") << _(
|
||||
"struct Enclosing\n"
|
||||
"{\n"
|
||||
" struct __attribute__((aligned(8)))\n"
|
||||
" {\n"
|
||||
" int i;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"Enclosing e;\n"
|
||||
"@\n"
|
||||
) << _("e.") << (QStringList()
|
||||
<< QLatin1String("Enclosing")
|
||||
<< QLatin1String("i"));
|
||||
|
||||
QTest::newRow("enum_inside_namespace") << _(
|
||||
"namespace Ns\n"
|
||||
"{\n"
|
||||
|
@@ -183,6 +183,8 @@ private slots:
|
||||
void q_enum_1();
|
||||
|
||||
void incomplete_ast();
|
||||
void unnamed_class();
|
||||
void unnamed_class_data();
|
||||
};
|
||||
|
||||
void tst_AST::gcc_attributes_1()
|
||||
@@ -1743,6 +1745,42 @@ void tst_AST::incomplete_ast()
|
||||
QVERIFY(ast);
|
||||
}
|
||||
|
||||
static ClassSpecifierAST *classSpecifierInSimpleDeclaration(SimpleDeclarationAST *simpleDeclaration)
|
||||
{
|
||||
Q_ASSERT(simpleDeclaration);
|
||||
SpecifierListAST *specifier = simpleDeclaration->decl_specifier_list;
|
||||
Q_ASSERT(specifier);
|
||||
Q_ASSERT(specifier->value);
|
||||
return specifier->value->asClassSpecifier();
|
||||
}
|
||||
|
||||
void tst_AST::unnamed_class()
|
||||
{
|
||||
QFETCH(QByteArray, source);
|
||||
QVERIFY(!source.isEmpty());
|
||||
|
||||
QSharedPointer<TranslationUnit> unit(parseDeclaration(source));
|
||||
QVERIFY(unit->ast());
|
||||
SimpleDeclarationAST *simpleDeclaration = unit->ast()->asSimpleDeclaration();
|
||||
QVERIFY(simpleDeclaration);
|
||||
ClassSpecifierAST *clazz = classSpecifierInSimpleDeclaration(simpleDeclaration);
|
||||
|
||||
QVERIFY(clazz);
|
||||
QVERIFY(clazz->name);
|
||||
QVERIFY(clazz->name->asAnonymousName());
|
||||
|
||||
QCOMPARE(diag.errorCount, 0);
|
||||
}
|
||||
|
||||
void tst_AST::unnamed_class_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("source");
|
||||
|
||||
typedef QByteArray _;
|
||||
QTest::newRow("unnamed-only") << _("class {};");
|
||||
QTest::newRow("unnamed-derived") << _("class : B {};");
|
||||
}
|
||||
|
||||
void tst_AST::initTestCase()
|
||||
{
|
||||
control.setDiagnosticClient(&diag);
|
||||
|
Reference in New Issue
Block a user