1 /**************************************************************************
3 ** This file is part of Qt Creator
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
32 **************************************************************************/
42 //TESTED_COMPONENT=src/libs/cplusplus
43 using namespace CPlusPlus;
45 class tst_AST: public QObject
53 TranslationUnit *parse(const QByteArray &source,
54 TranslationUnit::ParseMode mode,
55 bool blockErrors = false,
56 bool qtMocRun = false)
58 const StringLiteral *fileId = control.stringLiteral("<stdin>");
59 TranslationUnit *unit = new TranslationUnit(&control, fileId);
60 unit->setObjCEnabled(true);
61 unit->setQtMocRunEnabled(qtMocRun);
62 unit->setSource(source.constData(), source.length());
63 unit->blockErrors(blockErrors);
68 TranslationUnit *parseDeclaration(const QByteArray &source, bool blockErrors = false, bool qtMocRun = false)
69 { return parse(source, TranslationUnit::ParseDeclaration, blockErrors, qtMocRun); }
71 TranslationUnit *parseExpression(const QByteArray &source)
72 { return parse(source, TranslationUnit::ParseExpression); }
74 TranslationUnit *parseStatement(const QByteArray &source)
75 { return parse(source, TranslationUnit::ParseStatement); }
77 class Diagnostic: public DiagnosticClient {
85 virtual void report(int /*level*/,
86 const StringLiteral *fileName,
87 unsigned line, unsigned column,
88 const char *format, va_list ap)
92 qDebug() << fileName->chars()<<':'<<line<<':'<<column<<' '<<QString().vsprintf(format, ap);
102 void gcc_attributes_1();
105 void simple_name_1();
106 void template_id_1();
107 void new_expression_1();
108 void new_expression_2();
111 void conditional_1();
114 // possible declaration-or-expression statements
118 void if_statement_1();
119 void if_statement_2();
120 void if_statement_3();
121 void if_else_statement();
122 void while_statement();
123 void while_condition_statement();
124 void for_statement();
125 void cpp_initializer_or_function_declaration();
126 void simple_declaration_1();
127 void function_call_1();
128 void function_call_2();
129 void function_call_3();
130 void function_call_4();
131 void nested_deref_expression();
136 void objc_simple_class();
137 void objc_attributes_followed_by_at_keyword();
138 void objc_protocol_forward_declaration_1();
139 void objc_protocol_definition_1();
140 void objc_method_attributes_1();
141 void objc_selector_error_recovery_1();
142 void objc_selector_error_recovery_2();
144 // expressions with (square) brackets
145 void normal_array_access();
146 void array_access_with_nested_expression();
147 void objc_msg_send_expression();
148 void objc_msg_send_expression_without_selector();
154 void tst_AST::gcc_attributes_1()
156 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
157 "static inline void *__attribute__((__always_inline__)) _mm_malloc(size_t size, size_t align);"
161 void tst_AST::simple_declaration_1()
163 QSharedPointer<TranslationUnit> unit(parseStatement("\n"
167 AST *ast = unit->ast();
170 DeclarationStatementAST *declStmt = ast->asDeclarationStatement();
174 void tst_AST::simple_name_1()
176 QSharedPointer<TranslationUnit> unit(parseExpression("a"));
177 AST *ast = unit->ast();
180 QVERIFY(ast->asIdExpression()->name->asSimpleName() != 0);
181 QCOMPARE(ast->asIdExpression()->name->asSimpleName()->identifier_token, 1U);
184 void tst_AST::template_id_1()
186 QSharedPointer<TranslationUnit> unit(parseExpression("list<10>"));
187 AST *ast = unit->ast();
190 QVERIFY(ast->asIdExpression()->name->asTemplateId() != 0);
191 QCOMPARE(ast->asIdExpression()->name->asTemplateId()->identifier_token, 1U);
192 QCOMPARE(ast->asIdExpression()->name->asTemplateId()->less_token, 2U);
193 QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list != 0);
194 QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value != 0);
195 QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value->asNumericLiteral() != 0);
196 QCOMPARE(ast->asIdExpression()->name->asTemplateId()->template_argument_list->value->asNumericLiteral()->literal_token, 3U);
197 QVERIFY(ast->asIdExpression()->name->asTemplateId()->template_argument_list->next == 0);
198 QCOMPARE(ast->asIdExpression()->name->asTemplateId()->greater_token, 4U);
201 void tst_AST::new_expression_1()
203 QSharedPointer<TranslationUnit> unit(parseExpression("\n"
207 AST *ast = unit->ast();
210 NewExpressionAST *expr = ast->asNewExpression();
213 QCOMPARE(expr->scope_token, 0U);
214 QCOMPARE(expr->new_token, 1U);
215 QVERIFY(expr->new_placement == 0);
216 QCOMPARE(expr->lparen_token, 0U);
217 QVERIFY(expr->type_id == 0);
218 QCOMPARE(expr->rparen_token, 0U);
219 QVERIFY(expr->new_type_id != 0);
220 QVERIFY(expr->new_initializer == 0);
222 QVERIFY(expr->new_type_id->type_specifier_list != 0);
223 QVERIFY(expr->new_type_id->ptr_operator_list == 0);
224 QVERIFY(expr->new_type_id->new_array_declarator_list == 0);
227 void tst_AST::new_expression_2()
229 QSharedPointer<TranslationUnit> unit(parseStatement("\n"
230 "::new(__p) _Tp(__val);"
233 AST *ast = unit->ast();
236 ExpressionStatementAST *stmt = ast->asExpressionStatement();
238 QVERIFY(stmt->expression != 0);
239 QVERIFY(stmt->semicolon_token != 0);
241 NewExpressionAST *expr = stmt->expression->asNewExpression();
244 QCOMPARE(expr->scope_token, 1U);
245 QCOMPARE(expr->new_token, 2U);
246 QVERIFY(expr->new_placement != 0);
247 QCOMPARE(expr->lparen_token, 0U);
248 QVERIFY(expr->type_id == 0);
249 QCOMPARE(expr->rparen_token, 0U);
250 QVERIFY(expr->new_type_id != 0);
251 QVERIFY(expr->new_initializer != 0);
254 void tst_AST::condition_1()
256 QSharedPointer<TranslationUnit> unit(parseExpression("\n"
257 "(x < 0 && y > (int) a)"
260 AST *ast = unit->ast();
262 NestedExpressionAST *nestedExpr = ast->asNestedExpression();
264 QVERIFY(nestedExpr->expression);
265 BinaryExpressionAST *andExpr = nestedExpr->expression->asBinaryExpression();
267 QCOMPARE(unit->tokenKind(andExpr->binary_op_token), (int) T_AMPER_AMPER);
268 QVERIFY(andExpr->left_expression);
269 QVERIFY(andExpr->right_expression);
271 BinaryExpressionAST *ltExpr = andExpr->left_expression->asBinaryExpression();
273 QCOMPARE(unit->tokenKind(ltExpr->binary_op_token), (int) T_LESS);
274 QVERIFY(ltExpr->left_expression);
275 QVERIFY(ltExpr->right_expression);
277 SimpleNameAST *x = ltExpr->left_expression->asIdExpression()->name->asSimpleName();
279 QCOMPARE(unit->spell(x->identifier_token), "x");
281 NumericLiteralAST *zero = ltExpr->right_expression->asNumericLiteral();
283 QCOMPARE(unit->spell(zero->literal_token), "0");
285 BinaryExpressionAST *gtExpr = andExpr->right_expression->asBinaryExpression();
287 QCOMPARE(unit->tokenKind(gtExpr->binary_op_token), (int) T_GREATER);
288 QVERIFY(gtExpr->left_expression);
289 QVERIFY(gtExpr->right_expression);
291 SimpleNameAST *y = gtExpr->left_expression->asIdExpression()->name->asSimpleName();
293 QCOMPARE(unit->spell(y->identifier_token), "y");
295 CastExpressionAST *cast = gtExpr->right_expression->asCastExpression();
297 QVERIFY(cast->type_id);
298 QVERIFY(cast->expression);
300 TypeIdAST *intType = cast->type_id->asTypeId();
302 // ### here we could check if the type is an actual int
304 SimpleNameAST *a = cast->expression->asIdExpression()->name->asSimpleName();
306 QCOMPARE(unit->spell(a->identifier_token), "a");
309 void tst_AST::init_1()
311 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
312 "x y[] = { X<10>, y };"
315 AST *ast = unit->ast();
319 void tst_AST::conditional_1()
321 QSharedPointer<TranslationUnit> unit(parseExpression("\n"
322 "(x < 0 && y > (int) a) ? x == 1 : y = 1"
325 AST *ast = unit->ast();
328 ConditionalExpressionAST *conditional = ast->asConditionalExpression();
329 QVERIFY(conditional);
330 QVERIFY(conditional->condition);
331 QVERIFY(conditional->left_expression);
332 QVERIFY(conditional->right_expression);
334 NestedExpressionAST *nestedExpr = conditional->condition->asNestedExpression();
336 QVERIFY(nestedExpr->expression);
337 BinaryExpressionAST *andExpr = nestedExpr->expression->asBinaryExpression();
339 QCOMPARE(unit->tokenKind(andExpr->binary_op_token), (int) T_AMPER_AMPER);
340 QVERIFY(andExpr->left_expression);
341 QVERIFY(andExpr->right_expression);
343 BinaryExpressionAST *ltExpr = andExpr->left_expression->asBinaryExpression();
345 QCOMPARE(unit->tokenKind(ltExpr->binary_op_token), (int) T_LESS);
346 QVERIFY(ltExpr->left_expression);
347 QVERIFY(ltExpr->right_expression);
349 SimpleNameAST *x = ltExpr->left_expression->asIdExpression()->name->asSimpleName();
351 QCOMPARE(unit->spell(x->identifier_token), "x");
353 NumericLiteralAST *zero = ltExpr->right_expression->asNumericLiteral();
355 QCOMPARE(unit->spell(zero->literal_token), "0");
357 BinaryExpressionAST *gtExpr = andExpr->right_expression->asBinaryExpression();
359 QCOMPARE(unit->tokenKind(gtExpr->binary_op_token), (int) T_GREATER);
360 QVERIFY(gtExpr->left_expression);
361 QVERIFY(gtExpr->right_expression);
363 SimpleNameAST *y = gtExpr->left_expression->asIdExpression()->name->asSimpleName();
365 QCOMPARE(unit->spell(y->identifier_token), "y");
367 CastExpressionAST *cast = gtExpr->right_expression->asCastExpression();
369 QVERIFY(cast->type_id);
370 QVERIFY(cast->expression);
372 TypeIdAST *intType = cast->type_id->asTypeId();
374 QVERIFY(! (intType->declarator));
375 QVERIFY(intType->type_specifier_list);
376 QVERIFY(! (intType->type_specifier_list->next));
377 QVERIFY(intType->type_specifier_list->value);
378 SimpleSpecifierAST *intSpec = intType->type_specifier_list->value->asSimpleSpecifier();
380 QCOMPARE(unit->spell(intSpec->specifier_token), "int");
382 SimpleNameAST *a = cast->expression->asIdExpression()->name->asSimpleName();
384 QCOMPARE(unit->spell(a->identifier_token), "a");
386 BinaryExpressionAST *equals = conditional->left_expression->asBinaryExpression();
388 QCOMPARE(unit->tokenKind(equals->binary_op_token), (int) T_EQUAL_EQUAL);
390 x = equals->left_expression->asIdExpression()->name->asSimpleName();
392 QCOMPARE(unit->spell(x->identifier_token), "x");
394 NumericLiteralAST *one = equals->right_expression->asNumericLiteral();
396 QCOMPARE(unit->spell(one->literal_token), "1");
398 BinaryExpressionAST *assignment = conditional->right_expression->asBinaryExpression();
400 QCOMPARE(unit->tokenKind(assignment->binary_op_token), (int) T_EQUAL);
402 y = assignment->left_expression->asIdExpression()->name->asSimpleName();
404 QCOMPARE(unit->spell(y->identifier_token), "y");
406 one = assignment->right_expression->asNumericLiteral();
408 QCOMPARE(unit->spell(one->literal_token), "1");
411 void tst_AST::throw_1()
413 QSharedPointer<TranslationUnit> unit(parseStatement("throw 1;"));
414 AST *ast = unit->ast();
416 QVERIFY(ast->asExpressionStatement());
419 void tst_AST::call_call_1()
421 QSharedPointer<TranslationUnit> unit(parseStatement("method()->call();"));
422 AST *ast = unit->ast();
425 ExpressionStatementAST *exprStmt = ast->asExpressionStatement();
428 ExpressionAST *expr = exprStmt->expression;
431 CallAST *memberCall = expr->asCall();
433 QVERIFY(memberCall->base_expression);
434 QVERIFY(!memberCall->expression_list);
436 MemberAccessAST *member_xs = memberCall->base_expression->asMemberAccess();
438 QVERIFY(member_xs->member_name);
439 SimpleNameAST *member_name = member_xs->member_name->asSimpleName();
440 QVERIFY(member_name);
441 QVERIFY(member_name->identifier_token);
442 QCOMPARE(unit->spell(member_name->identifier_token), "call");
444 QCOMPARE(unit->tokenKind(member_xs->access_token), (int) T_ARROW);
446 QVERIFY(member_xs->base_expression);
447 CallAST *method_call = member_xs->base_expression->asCall();
448 QVERIFY(method_call);
449 QVERIFY(!method_call->expression_list);
450 QVERIFY(method_call->base_expression);
451 IdExpressionAST *member_expr = method_call->base_expression->asIdExpression();
452 QVERIFY(member_expr);
453 QVERIFY(member_expr->name);
454 SimpleNameAST *member_name2 = member_expr->name->asSimpleName();
455 QVERIFY(member_name2);
456 QVERIFY(member_name2->identifier_token);
457 QCOMPARE(unit->spell(member_name2->identifier_token), "method");
460 void tst_AST::function_call_1()
462 QSharedPointer<TranslationUnit> unit(parseStatement("retranslateUi(blah);"));
463 AST *ast = unit->ast();
465 QVERIFY(ast->asExpressionStatement());
468 void tst_AST::function_call_2()
470 QSharedPointer<TranslationUnit> unit(parseStatement("retranslateUi(10);"));
471 AST *ast = unit->ast();
473 QVERIFY(ast->asExpressionStatement());
476 void tst_AST::function_call_3()
478 QSharedPointer<TranslationUnit> unit(parseStatement("advance();"));
479 AST *ast = unit->ast();
481 QVERIFY(ast->asExpressionStatement());
484 void tst_AST::function_call_4()
486 QSharedPointer<TranslationUnit> unit(parseStatement("checkPropertyAttribute(attrAst, propAttrs, ReadWrite);"));
487 AST *ast = unit->ast();
489 QVERIFY(ast->asExpressionStatement());
492 void tst_AST::nested_deref_expression()
494 QSharedPointer<TranslationUnit> unit(parseStatement("(*blah);"));
495 AST *ast = unit->ast();
497 QVERIFY(ast->asExpressionStatement());
500 void tst_AST::assignment_1()
502 QSharedPointer<TranslationUnit> unit(parseStatement("a(x) = 3;"));
503 AST *ast = unit->ast();
505 QVERIFY(ast->asExpressionStatement());
508 void tst_AST::assignment_2()
510 QSharedPointer<TranslationUnit> unit(parseStatement("(*blah) = 10;"));
511 AST *ast = unit->ast();
513 QVERIFY(ast->asExpressionStatement());
516 void tst_AST::if_statement_1()
518 QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b;"));
520 AST *ast = unit->ast();
523 IfStatementAST *stmt = ast->asIfStatement();
525 QCOMPARE(stmt->if_token, 1U);
526 QCOMPARE(stmt->lparen_token, 2U);
527 QVERIFY(stmt->condition != 0);
528 QCOMPARE(stmt->rparen_token, 4U);
529 QVERIFY(stmt->statement != 0);
530 QCOMPARE(stmt->else_token, 0U);
531 QVERIFY(stmt->else_statement == 0);
533 // check the `then' statement1
534 ExpressionStatementAST *then_stmt = stmt->statement->asExpressionStatement();
535 QVERIFY(then_stmt != 0);
536 QVERIFY(then_stmt->expression != 0);
537 QCOMPARE(then_stmt->semicolon_token, 6U);
539 SimpleNameAST *id_expr = then_stmt->expression->asIdExpression()->name->asSimpleName();
540 QVERIFY(id_expr != 0);
541 QCOMPARE(id_expr->identifier_token, 5U);
544 void tst_AST::if_statement_2()
546 QSharedPointer<TranslationUnit> unit(parseStatement("if (x<0 && y>a);"));
548 AST *ast = unit->ast();
551 IfStatementAST *stmt = ast->asIfStatement();
554 QVERIFY(stmt->condition);
555 QVERIFY(stmt->condition->asBinaryExpression());
556 QCOMPARE(unit->tokenKind(stmt->condition->asBinaryExpression()->binary_op_token), int(T_AMPER_AMPER));
559 void tst_AST::if_statement_3()
561 QSharedPointer<TranslationUnit> unit(parseStatement("if (x<0 && x<0 && x<0 && x<0 && x<0 && x<0 && x<0);"));
563 AST *ast = unit->ast();
566 IfStatementAST *stmt = ast->asIfStatement();
569 QVERIFY(stmt->condition);
572 void tst_AST::if_else_statement()
574 QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b; else c;"));
576 AST *ast = unit->ast();
579 IfStatementAST *stmt = ast->asIfStatement();
581 QCOMPARE(stmt->if_token, 1U);
582 QCOMPARE(stmt->lparen_token, 2U);
583 QVERIFY(stmt->condition != 0);
584 QCOMPARE(stmt->rparen_token, 4U);
585 QVERIFY(stmt->statement != 0);
586 QCOMPARE(stmt->else_token, 7U);
587 QVERIFY(stmt->else_statement != 0);
589 // check the `then' statement
590 ExpressionStatementAST *then_stmt = stmt->statement->asExpressionStatement();
591 QVERIFY(then_stmt != 0);
592 QVERIFY(then_stmt->expression != 0);
593 QCOMPARE(then_stmt->semicolon_token, 6U);
595 SimpleNameAST *a_id_expr = then_stmt->expression->asIdExpression()->name->asSimpleName();
596 QVERIFY(a_id_expr != 0);
597 QCOMPARE(a_id_expr->identifier_token, 5U);
599 // check the `then' statement
600 ExpressionStatementAST *else_stmt = stmt->else_statement->asExpressionStatement();
601 QVERIFY(else_stmt != 0);
602 QVERIFY(else_stmt->expression != 0);
603 QCOMPARE(else_stmt->semicolon_token, 9U);
605 SimpleNameAST *b_id_expr = else_stmt->expression->asIdExpression()->name->asSimpleName();
606 QVERIFY(b_id_expr != 0);
607 QCOMPARE(b_id_expr->identifier_token, 8U);
610 void tst_AST::while_statement()
612 QSharedPointer<TranslationUnit> unit(parseStatement("while (a) { }"));
614 AST *ast = unit->ast();
617 WhileStatementAST *stmt = ast->asWhileStatement();
619 QCOMPARE(stmt->while_token, 1U);
620 QCOMPARE(stmt->lparen_token, 2U);
621 QVERIFY(stmt->condition != 0);
622 QCOMPARE(stmt->rparen_token, 4U);
623 QVERIFY(stmt->statement != 0);
626 QVERIFY(stmt->condition->asIdExpression()->name->asSimpleName() != 0);
627 QCOMPARE(stmt->condition->asIdExpression()->name->asSimpleName()->identifier_token, 3U);
629 // check the `body' statement
630 CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement();
631 QVERIFY(body_stmt != 0);
632 QCOMPARE(body_stmt->lbrace_token, 5U);
633 QVERIFY(body_stmt->statement_list == 0);
634 QCOMPARE(body_stmt->rbrace_token, 6U);
637 void tst_AST::while_condition_statement()
639 QSharedPointer<TranslationUnit> unit(parseStatement("while (int a = foo) { }"));
641 AST *ast = unit->ast();
644 WhileStatementAST *stmt = ast->asWhileStatement();
646 QCOMPARE(stmt->while_token, 1U);
647 QCOMPARE(stmt->lparen_token, 2U);
648 QVERIFY(stmt->condition != 0);
649 QCOMPARE(stmt->rparen_token, 7U);
650 QVERIFY(stmt->statement != 0);
653 ConditionAST *condition = stmt->condition->asCondition();
654 QVERIFY(condition != 0);
655 QVERIFY(condition->type_specifier_list != 0);
656 QVERIFY(condition->type_specifier_list->value->asSimpleSpecifier() != 0);
657 QCOMPARE(condition->type_specifier_list->value->asSimpleSpecifier()->specifier_token, 3U);
658 QVERIFY(condition->type_specifier_list->next == 0);
659 QVERIFY(condition->declarator != 0);
660 QVERIFY(condition->declarator->core_declarator != 0);
661 QVERIFY(condition->declarator->core_declarator->asDeclaratorId() != 0);
662 QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name != 0);
663 QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName() != 0);
664 QCOMPARE(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName()->identifier_token, 4U);
665 QVERIFY(condition->declarator->postfix_declarator_list == 0);
666 QVERIFY(condition->declarator->initializer != 0);
667 QVERIFY(condition->declarator->initializer->asIdExpression()->name->asSimpleName() != 0);
668 QCOMPARE(condition->declarator->initializer->asIdExpression()->name->asSimpleName()->identifier_token, 6U);
670 // check the `body' statement
671 CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement();
672 QVERIFY(body_stmt != 0);
673 QCOMPARE(body_stmt->lbrace_token, 8U);
674 QVERIFY(body_stmt->statement_list == 0);
675 QCOMPARE(body_stmt->rbrace_token, 9U);
678 void tst_AST::for_statement()
680 QSharedPointer<TranslationUnit> unit(parseStatement("for (;;) {}"));
681 AST *ast = unit->ast();
684 ForStatementAST *stmt = ast->asForStatement();
686 QCOMPARE(stmt->for_token, 1U);
687 QCOMPARE(stmt->lparen_token, 2U);
688 QVERIFY(stmt->initializer != 0);
689 QVERIFY(stmt->initializer->asExpressionStatement() != 0);
690 QCOMPARE(stmt->initializer->asExpressionStatement()->semicolon_token, 3U);
691 QVERIFY(stmt->condition == 0);
692 QCOMPARE(stmt->semicolon_token, 4U);
693 QVERIFY(stmt->expression == 0);
694 QCOMPARE(stmt->rparen_token, 5U);
695 QVERIFY(stmt->statement != 0);
696 QVERIFY(stmt->statement->asCompoundStatement() != 0);
697 QCOMPARE(stmt->statement->asCompoundStatement()->lbrace_token, 6U);
698 QVERIFY(stmt->statement->asCompoundStatement()->statement_list == 0);
699 QCOMPARE(stmt->statement->asCompoundStatement()->rbrace_token, 7U);
702 void tst_AST::cpp_initializer_or_function_declaration()
704 QSharedPointer<TranslationUnit> unit(parseStatement("QFileInfo fileInfo(foo);"));
705 AST *ast = unit->ast();
708 DeclarationStatementAST *stmt = ast->asDeclarationStatement();
711 QVERIFY(stmt->declaration != 0);
713 SimpleDeclarationAST *simple_decl = stmt->declaration->asSimpleDeclaration();
714 QVERIFY(simple_decl != 0);
716 QVERIFY(simple_decl->decl_specifier_list != 0);
717 QVERIFY(simple_decl->decl_specifier_list->next == 0);
718 QVERIFY(simple_decl->declarator_list != 0);
719 QVERIFY(simple_decl->declarator_list->next == 0);
720 QCOMPARE(simple_decl->semicolon_token, 6U);
722 NamedTypeSpecifierAST *named_ty = simple_decl->decl_specifier_list->value->asNamedTypeSpecifier();
723 QVERIFY(named_ty != 0);
724 QVERIFY(named_ty->name != 0);
726 SimpleNameAST *simple_named_ty = named_ty->name->asSimpleName();
727 QVERIFY(simple_named_ty != 0);
728 QCOMPARE(simple_named_ty->identifier_token, 1U);
730 DeclaratorAST *declarator = simple_decl->declarator_list->value;
731 QVERIFY(declarator != 0);
732 QVERIFY(declarator->core_declarator != 0);
733 QVERIFY(declarator->postfix_declarator_list != 0);
734 QVERIFY(declarator->postfix_declarator_list->next == 0);
735 QVERIFY(declarator->initializer == 0);
737 DeclaratorIdAST *decl_id = declarator->core_declarator->asDeclaratorId();
738 QVERIFY(decl_id != 0);
739 QVERIFY(decl_id->name != 0);
740 QVERIFY(decl_id->name->asSimpleName() != 0);
741 QCOMPARE(decl_id->name->asSimpleName()->identifier_token, 2U);
743 FunctionDeclaratorAST *fun_declarator = declarator->postfix_declarator_list->value->asFunctionDeclarator();
744 QVERIFY(fun_declarator != 0);
745 QCOMPARE(fun_declarator->lparen_token, 3U);
746 QVERIFY(fun_declarator->parameter_declaration_clause != 0);
747 QCOMPARE(fun_declarator->rparen_token, 5U);
749 // check the formal arguments
750 ParameterDeclarationClauseAST *param_clause = fun_declarator->parameter_declaration_clause;
751 QVERIFY(param_clause->parameter_declaration_list != 0);
752 QVERIFY(param_clause->parameter_declaration_list->next == 0);
753 QCOMPARE(param_clause->dot_dot_dot_token, 0U);
755 // check the parameter
756 ParameterDeclarationListAST *declarations = param_clause->parameter_declaration_list;
757 QVERIFY(declarations);
758 QVERIFY(declarations->value);
759 QVERIFY(! declarations->next);
761 ParameterDeclarationAST *param = declarations->value->asParameterDeclaration();
763 QVERIFY(param->type_specifier_list != 0);
764 QVERIFY(param->type_specifier_list->next == 0);
765 QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier() != 0);
766 QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier()->name != 0);
767 QVERIFY(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName() != 0);
768 QCOMPARE(param->type_specifier_list->value->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U);
771 void tst_AST::objc_simple_class()
773 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
774 "@interface Zoo {} +(id)alloc;-(id)init;@end\n"
775 "@implementation Zoo\n"
781 AST *ast = unit->ast();
785 void tst_AST::objc_attributes_followed_by_at_keyword()
787 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
788 "__attribute__((deprecated)) @interface foo <bar>\n"
793 "- (id) init:(int)a foo:(int)b, c;\n"
796 AST *ast = unit->ast();
800 void tst_AST::objc_protocol_forward_declaration_1()
802 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo;"));
803 AST *ast = unit->ast();
807 void tst_AST::objc_protocol_definition_1()
809 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo <ciao, bar> @end"));
810 AST *ast = unit->ast();
814 void tst_AST::objc_method_attributes_1()
816 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
818 "- (void) foo __attribute__((deprecated));\n"
819 "+ (void) bar __attribute__((unavailable));\n"
822 AST *ast = unit->ast();
824 ObjCClassDeclarationAST *zoo = ast->asObjCClassDeclaration();
826 QVERIFY(zoo->interface_token); QVERIFY(! (zoo->implementation_token));
827 QVERIFY(zoo->class_name); QVERIFY(zoo->class_name->asSimpleName());
828 QCOMPARE(unit->spell(zoo->class_name->asSimpleName()->identifier_token), "Zoo");
830 DeclarationListAST *decls = zoo->member_declaration_list;
831 QVERIFY(decls->value);
832 QVERIFY(decls->next);
833 QVERIFY(decls->next->value);
834 QVERIFY(! (decls->next->next));
836 ObjCMethodDeclarationAST *fooDecl = decls->value->asObjCMethodDeclaration();
838 QVERIFY(! (fooDecl->function_body));
839 QVERIFY(fooDecl->semicolon_token);
841 ObjCMethodPrototypeAST *foo = fooDecl->method_prototype;
843 QCOMPARE(unit->tokenKind(foo->method_type_token), (int) T_MINUS);
844 QVERIFY(foo->type_name);
845 QVERIFY(foo->selector);
846 QVERIFY(foo->selector->selector_argument_list->value);
847 QVERIFY(!foo->selector->selector_argument_list->next);
848 QCOMPARE(unit->spell(foo->selector->selector_argument_list->value->name_token), "foo");
849 QVERIFY(foo->attribute_list);
850 QVERIFY(foo->attribute_list->value);
851 QVERIFY(! (foo->attribute_list->next));
852 AttributeSpecifierAST *deprecatedSpec = foo->attribute_list->value->asAttributeSpecifier();
853 QVERIFY(deprecatedSpec);
854 QCOMPARE(unit->tokenKind(deprecatedSpec->attribute_token), (int) T___ATTRIBUTE__);
855 QVERIFY(deprecatedSpec->attribute_list);
856 QVERIFY(deprecatedSpec->attribute_list->value);
857 QVERIFY(! (deprecatedSpec->attribute_list->next));
858 AttributeAST *deprecatedAttr = deprecatedSpec->attribute_list->value->asAttribute();
859 QVERIFY(deprecatedAttr);
860 QVERIFY(! deprecatedAttr->expression_list);
861 QCOMPARE(unit->spell(deprecatedAttr->identifier_token), "deprecated");
863 ObjCMethodDeclarationAST *barDecl = decls->next->value->asObjCMethodDeclaration();
865 QVERIFY(! (barDecl->function_body));
866 QVERIFY(barDecl->semicolon_token);
868 ObjCMethodPrototypeAST *bar = barDecl->method_prototype;
870 QCOMPARE(unit->tokenKind(bar->method_type_token), (int) T_PLUS);
871 QVERIFY(bar->type_name);
872 QVERIFY(bar->selector);
873 QVERIFY(bar->selector->selector_argument_list);
874 QVERIFY(bar->selector->selector_argument_list->value);
875 QVERIFY(!bar->selector->selector_argument_list->next);
876 QCOMPARE(unit->spell(bar->selector->selector_argument_list->value->name_token), "bar");
877 QVERIFY(bar->attribute_list);
878 QVERIFY(bar->attribute_list->value);
879 QVERIFY(! (bar->attribute_list->next));
880 AttributeSpecifierAST *unavailableSpec = bar->attribute_list->value->asAttributeSpecifier();
881 QVERIFY(unavailableSpec);
882 QCOMPARE(unit->tokenKind(unavailableSpec->attribute_token), (int) T___ATTRIBUTE__);
883 QVERIFY(unavailableSpec->attribute_list);
884 QVERIFY(unavailableSpec->attribute_list->value);
885 QVERIFY(! (unavailableSpec->attribute_list->next));
886 AttributeAST *unavailableAttr = unavailableSpec->attribute_list->value->asAttribute();
887 QVERIFY(unavailableAttr);
888 QVERIFY(! unavailableAttr->expression_list);
889 QCOMPARE(unit->spell(unavailableAttr->identifier_token), "unavailable");
898 void tst_AST::objc_selector_error_recovery_1()
900 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
906 AST *ast = unit->ast();
910 void tst_AST::objc_selector_error_recovery_2()
912 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
914 " @selector(foo:bar);\n"
917 AST *ast = unit->ast();
921 void tst_AST::normal_array_access()
923 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
930 AST *ast = unit->ast();
933 FunctionDefinitionAST *func = ast->asFunctionDefinition();
936 StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list;
937 QVERIFY(bodyStatements);
938 QVERIFY(bodyStatements->next);
939 QVERIFY(bodyStatements->next->next);
940 QVERIFY(bodyStatements->next->next->value);
941 ExpressionAST *expr = bodyStatements->next->next->value->asReturnStatement()->expression;
944 ArrayAccessAST *arrayExpr = expr->asArrayAccess();
947 { // check the left-hand side:
948 ExpressionAST *lhs = arrayExpr->base_expression;
950 SimpleNameAST *a = lhs->asIdExpression()->name->asSimpleName();
952 QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a"));
955 { // check the right-hand side:
956 QVERIFY(arrayExpr->expression);
957 SimpleNameAST *b = arrayExpr->expression->asIdExpression()->name->asSimpleName();
959 QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b"));
963 void tst_AST::array_access_with_nested_expression()
965 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
972 AST *ast = unit->ast();
975 FunctionDefinitionAST *func = ast->asFunctionDefinition();
978 StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list;
979 QVERIFY(bodyStatements && bodyStatements->next && bodyStatements->next->next && bodyStatements->next->next->value);
980 ExpressionAST *expr = bodyStatements->next->next->value->asReturnStatement()->expression;
983 CastExpressionAST *castExpr = expr->asCastExpression();
986 ArrayAccessAST *arrayExpr = expr->asArrayAccess();
990 ExpressionAST *lhs = arrayExpr->base_expression;
992 NestedExpressionAST *nested_a = lhs->asNestedExpression();
993 QVERIFY(nested_a && nested_a->expression);
994 SimpleNameAST *a = nested_a->expression->asIdExpression()->name->asSimpleName();
996 QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a"));
1000 QVERIFY(arrayExpr->expression);
1001 SimpleNameAST *b = arrayExpr->expression->asIdExpression()->name->asSimpleName();
1003 QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b"));
1007 void tst_AST::objc_msg_send_expression()
1009 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
1011 " NSObject *obj = [[[NSObject alloc] init] autorelease];\n"
1012 " return [obj description];\n"
1015 AST *ast = unit->ast();
1018 FunctionDefinitionAST *func = ast->asFunctionDefinition();
1021 StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list;
1022 QVERIFY(bodyStatements && bodyStatements->next && !bodyStatements->next->next && bodyStatements->next->value);
1024 {// check the NSObject declaration
1025 DeclarationStatementAST *firstStatement = bodyStatements->value->asDeclarationStatement();
1026 QVERIFY(firstStatement);
1027 DeclarationAST *objDecl = firstStatement->declaration;
1029 SimpleDeclarationAST *simpleDecl = objDecl->asSimpleDeclaration();
1030 QVERIFY(simpleDecl);
1032 {// check the type (NSObject)
1033 QVERIFY(simpleDecl->decl_specifier_list && !simpleDecl->decl_specifier_list->next);
1034 NamedTypeSpecifierAST *namedType = simpleDecl->decl_specifier_list->value->asNamedTypeSpecifier();
1035 QVERIFY(namedType && namedType->name);
1036 SimpleNameAST *typeName = namedType->name->asSimpleName();
1038 QCOMPARE(QLatin1String(unit->identifier(typeName->identifier_token)->chars()), QLatin1String("NSObject"));
1041 {// check the assignment
1042 QVERIFY(simpleDecl->declarator_list && !simpleDecl->declarator_list->next);
1043 DeclaratorAST *declarator = simpleDecl->declarator_list->value;
1044 QVERIFY(declarator);
1045 QVERIFY(!declarator->attribute_list);
1047 QVERIFY(declarator->ptr_operator_list && !declarator->ptr_operator_list->next
1048 && declarator->ptr_operator_list->value->asPointer()
1049 && ! declarator->ptr_operator_list->value->asPointer()->cv_qualifier_list);
1051 QVERIFY(declarator->core_declarator && declarator->core_declarator->asDeclaratorId());
1052 NameAST *objNameId = declarator->core_declarator->asDeclaratorId()->name;
1053 QVERIFY(objNameId && objNameId->asSimpleName());
1054 QCOMPARE(QLatin1String(unit->identifier(objNameId->asSimpleName()->identifier_token)->chars()), QLatin1String("obj"));
1056 QVERIFY(!declarator->postfix_declarator_list);
1057 QVERIFY(!declarator->post_attribute_list);
1058 ExpressionAST *initializer = declarator->initializer;
1059 QVERIFY(initializer);
1061 ObjCMessageExpressionAST *expr1 = initializer->asObjCMessageExpression();
1062 QVERIFY(expr1 && expr1->receiver_expression && expr1->selector && !expr1->argument_list);
1064 ObjCMessageExpressionAST *expr2 = expr1->receiver_expression->asObjCMessageExpression();
1065 QVERIFY(expr2 && expr2->receiver_expression && expr2->selector && !expr2->argument_list);
1067 ObjCMessageExpressionAST *expr3 = expr2->receiver_expression->asObjCMessageExpression();
1068 QVERIFY(expr3 && expr3->receiver_expression && expr3->selector && !expr3->argument_list);
1072 {// check the return statement
1073 ExpressionAST *expr = bodyStatements->next->value->asReturnStatement()->expression;
1076 ObjCMessageExpressionAST *msgExpr = expr->asObjCMessageExpression();
1079 QVERIFY(msgExpr->receiver_expression);
1080 SimpleNameAST *receiver = msgExpr->receiver_expression->asIdExpression()->name->asSimpleName();
1082 QCOMPARE(QLatin1String(unit->identifier(receiver->identifier_token)->chars()), QLatin1String("obj"));
1084 QVERIFY(msgExpr->argument_list == 0);
1086 QVERIFY(msgExpr->selector);
1087 ObjCSelectorArgumentListAST *args = msgExpr->selector->selector_argument_list;
1089 QVERIFY(args->value);
1090 QVERIFY(! args->next);
1091 QCOMPARE(QLatin1String(unit->identifier(args->value->name_token)->chars()), QLatin1String("description"));
1095 void tst_AST::objc_msg_send_expression_without_selector()
1097 // This test is to verify that no ObjCMessageExpressionAST element is created as the expression for the return statement.
1098 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
1100 " NSObject *obj = [[[NSObject alloc] init] autorelease];\n"
1104 AST *ast = unit->ast();
1107 FunctionDefinitionAST *func = ast->asFunctionDefinition();
1110 StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list;
1111 QVERIFY(bodyStatements && bodyStatements->next);
1112 QVERIFY(bodyStatements->next->value);
1113 QVERIFY(bodyStatements->next->value->asReturnStatement());
1114 QVERIFY(!bodyStatements->next->value->asReturnStatement()->expression);
1117 void tst_AST::q_enum_1()
1119 QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
1123 "enum e { x, y };\n"
1126 QVERIFY(unit->ast());
1127 SimpleDeclarationAST *tstDecl = unit->ast()->asSimpleDeclaration();
1129 QVERIFY(! tstDecl->declarator_list);
1130 QVERIFY(tstDecl->decl_specifier_list);
1131 QVERIFY(tstDecl->decl_specifier_list->value);
1132 QVERIFY(! tstDecl->decl_specifier_list->next);
1133 ClassSpecifierAST *tst = tstDecl->decl_specifier_list->value->asClassSpecifier();
1136 QVERIFY(tst->member_specifier_list);
1137 QVERIFY(tst->member_specifier_list->value);
1138 QtEnumDeclarationAST *qtEnum = tst->member_specifier_list->value->asQtEnumDeclaration();
1140 QVERIFY(qtEnum->enumerator_list);
1141 QVERIFY(qtEnum->enumerator_list->value);
1142 QVERIFY(! qtEnum->enumerator_list->next);
1144 SimpleNameAST *e = qtEnum->enumerator_list->value->asSimpleName();
1146 QCOMPARE(unit->spell(e->identifier_token), "e");
1149 void tst_AST::initTestCase()
1151 control.setDiagnosticClient(&diag);
1154 QTEST_APPLESS_MAIN(tst_AST)
1155 #include "tst_ast.moc"