Commit a621c99a authored by Erik Verbruggen's avatar Erik Verbruggen
Browse files

[C++] Add error recovery for namespace declarations.



Change-Id: I884ff9901c95467524e5eba38e91f75992d30e14
Reviewed-by: default avatarRoberto Raggi <roberto.raggi@nokia.com>
Reviewed-by: default avatarFlex Ferrum <flexferrum@gmail.com>
parent 164db0fe
......@@ -766,8 +766,33 @@ bool Parser::parseNamespace(DeclarationAST *&node)
parseAttributeSpecifier(*attr_ptr);
attr_ptr = &(*attr_ptr)->next;
}
if (LA() == T_LBRACE)
if (LA() == T_LBRACE) {
parseLinkageBody(ast->linkage_body);
} else { // attempt to do error recovery
unsigned pos = cursor();
for (;LA() != T_EOF_SYMBOL; consumeToken()) {
switch (LA()) {
case T_IDENTIFIER:
case T_POUND:
case T_POUND_POUND:
case T___ATTRIBUTE__:
case T_LPAREN:
case T_RPAREN:
case T_DEFAULT:
case T_PUBLIC:
case T_PRIVATE:
case T_PROTECTED:
continue;
}
if (tok().isLiteral())
continue;
break;
}
if (LA() == T_LBRACE && parseLinkageBody(ast->linkage_body))
warning(pos, "expected '{' before '%s'", _translationUnit->tokenAt(pos).spell());
else
rewind(pos);
}
node = ast;
return true;
}
......
......@@ -99,6 +99,8 @@ private slots:
void initTestCase();
// declarations
void gcc_attributes_1();
void gcc_attributes_2();
void gcc_attributes_3();
// expressions
void simple_name_1();
......@@ -159,7 +161,55 @@ void tst_AST::gcc_attributes_1()
{
QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
"static inline void *__attribute__((__always_inline__)) _mm_malloc(size_t size, size_t align);"
));
));
}
void tst_AST::gcc_attributes_2()
{
QSharedPointer<TranslationUnit> unit(parseDeclaration(
"\nnamespace std __attribute__ ((__visibility__ (\"default\"))) {\n}\n"
));
AST *ast = unit->ast();
QVERIFY(ast);
NamespaceAST* ns = ast->asNamespace();
QVERIFY(ns);
QCOMPARE(unit->spell(ns->identifier_token), "std");
QVERIFY(ns->attribute_list);
QVERIFY(!ns->attribute_list->next);
QVERIFY(ns->attribute_list->value);
AttributeSpecifierAST *attrSpec = ns->attribute_list->value->asAttributeSpecifier();
QVERIFY(attrSpec);
QVERIFY(attrSpec->attribute_list);
QVERIFY(!attrSpec->attribute_list->next);
QVERIFY(attrSpec->attribute_list->value);
AttributeAST *attr = attrSpec->attribute_list->value->asAttribute();
QVERIFY(attr);
QCOMPARE(unit->spell(attr->identifier_token), "__visibility__");
QVERIFY(attr->expression_list);
QVERIFY(!attr->expression_list->next);
QVERIFY(attr->expression_list->value);
StringLiteralAST *e = attr->expression_list->value->asStringLiteral();
QVERIFY(e);
QVERIFY(!e->next);
QCOMPARE(unit->spell(e->literal_token), "default");
}
void tst_AST::gcc_attributes_3()
{
const char *inp = "\nnamespace std X {\n}\n";
QSharedPointer<TranslationUnit> unit(parseDeclaration(inp));
AST *ast = unit->ast();
QVERIFY(ast);
NamespaceAST* ns = ast->asNamespace();
QVERIFY(ns);
QCOMPARE(unit->spell(ns->identifier_token), "std");
QVERIFY(!ns->attribute_list);
QVERIFY(ns->linkage_body);
LinkageBodyAST *link = ns->linkage_body->asLinkageBody();
QVERIFY(link);
QCOMPARE(unit->tokenKind(link->lbrace_token), (int) T_LBRACE);
QVERIFY(!link->declaration_list);
QCOMPARE(unit->tokenKind(link->rbrace_token), (int) T_RBRACE);
}
void tst_AST::simple_declaration_1()
......
......@@ -43,6 +43,7 @@ Q_OBJECT
private Q_SLOTS:
void unfinished_function_like_macro_call();
void nasty_macro_expansion();
void tstst();
};
void tst_Preprocessor::unfinished_function_like_macro_call()
......@@ -111,5 +112,28 @@ void tst_Preprocessor::nasty_macro_expansion()
QVERIFY(!preprocessed.contains("FIELD32"));
}
void tst_Preprocessor::tstst()
{
Client *client = 0; // no client.
Environment env;
Preprocessor preprocess(client, &env);
QByteArray preprocessed = preprocess(
QLatin1String("<stdin>"),
QByteArray("\n"
"# define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))\n"
"namespace std _GLIBCXX_VISIBILITY(default) {\n"
"}\n"
));
qDebug() << preprocessed;
/*
# define _GLIBCXX_VISIBILITY(V) __attribute__ ((__visibility__ (#V)))
namespace std _GLIBCXX_VISIBILITY(default)
*/
}
QTEST_APPLESS_MAIN(tst_Preprocessor)
#include "tst_preprocessor.moc"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment