OSDN Git Service

1d4c3e434febae84a0d274e3e9659e43a2735d85
[qt-creator-jp/qt-creator-jp.git] / tests / auto / cplusplus / ast / tst_ast.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
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
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
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.
24 **
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.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include <QtTest>
35 #include <QtDebug>
36
37 #include <Control.h>
38 #include <Literals.h>
39 #include <Parser.h>
40 #include <AST.h>
41
42 //TESTED_COMPONENT=src/libs/cplusplus
43 using namespace CPlusPlus;
44
45 class tst_AST: public QObject
46 {
47     Q_OBJECT
48
49     Control control;
50
51 public:
52
53     TranslationUnit *parse(const QByteArray &source,
54                            TranslationUnit::ParseMode mode,
55                            bool blockErrors = false,
56                            bool qtMocRun = false)
57     {
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);
64         unit->parse(mode);
65         return unit;
66     }
67
68     TranslationUnit *parseDeclaration(const QByteArray &source, bool blockErrors = false, bool qtMocRun = false)
69     { return parse(source, TranslationUnit::ParseDeclaration, blockErrors, qtMocRun); }
70
71     TranslationUnit *parseExpression(const QByteArray &source)
72     { return parse(source, TranslationUnit::ParseExpression); }
73
74     TranslationUnit *parseStatement(const QByteArray &source)
75     { return parse(source, TranslationUnit::ParseStatement); }
76     
77     class Diagnostic: public DiagnosticClient {
78     public:
79         int errorCount;
80
81         Diagnostic()
82             : errorCount(0)
83         { }
84
85         virtual void report(int /*level*/,
86                             const StringLiteral *fileName,
87                             unsigned line, unsigned column,
88                             const char *format, va_list ap)
89         {
90             ++errorCount;
91
92             qDebug() << fileName->chars()<<':'<<line<<':'<<column<<' '<<QString().vsprintf(format, ap);
93         }
94     };
95
96     Diagnostic diag;    
97     
98
99 private slots:
100     void initTestCase();
101     // declarations
102     void gcc_attributes_1();
103
104     // expressions
105     void simple_name_1();
106     void template_id_1();
107     void new_expression_1();
108     void new_expression_2();
109     void condition_1();
110     void init_1();
111     void conditional_1();
112     void throw_1();
113
114     // possible declaration-or-expression statements
115     void call_call_1();
116
117     // 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();
132     void assignment_1();
133     void assignment_2();
134
135     // objc++
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();
143
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();
149
150     // Qt "keywords"
151     void q_enum_1();
152 };
153
154 void tst_AST::gcc_attributes_1()
155 {
156     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
157 "static inline void *__attribute__((__always_inline__)) _mm_malloc(size_t size, size_t align);"
158     ));
159 }
160
161 void tst_AST::simple_declaration_1()
162 {
163     QSharedPointer<TranslationUnit> unit(parseStatement("\n"
164 "a * b = 10;"
165     ));
166
167     AST *ast = unit->ast();
168     QVERIFY(ast);
169
170     DeclarationStatementAST *declStmt = ast->asDeclarationStatement();
171     QVERIFY(declStmt);
172 }
173
174 void tst_AST::simple_name_1()
175 {
176     QSharedPointer<TranslationUnit> unit(parseExpression("a"));
177     AST *ast = unit->ast();
178
179     QVERIFY(ast != 0);
180     QVERIFY(ast->asIdExpression()->name->asSimpleName() != 0);
181     QCOMPARE(ast->asIdExpression()->name->asSimpleName()->identifier_token, 1U);
182 }
183
184 void tst_AST::template_id_1()
185 {
186     QSharedPointer<TranslationUnit> unit(parseExpression("list<10>"));
187     AST *ast = unit->ast();
188
189     QVERIFY(ast != 0);
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);
199 }
200
201 void tst_AST::new_expression_1()
202 {
203     QSharedPointer<TranslationUnit> unit(parseExpression("\n"
204 "new char"
205     ));
206
207     AST *ast = unit->ast();
208     QVERIFY(ast != 0);
209
210     NewExpressionAST *expr = ast->asNewExpression();
211     QVERIFY(expr != 0);
212
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);
221
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);
225 }
226
227 void tst_AST::new_expression_2()
228 {
229     QSharedPointer<TranslationUnit> unit(parseStatement("\n"
230 "::new(__p) _Tp(__val);"
231     ));
232
233     AST *ast = unit->ast();
234     QVERIFY(ast != 0);
235
236     ExpressionStatementAST *stmt = ast->asExpressionStatement();
237     QVERIFY(stmt != 0);
238     QVERIFY(stmt->expression != 0);
239     QVERIFY(stmt->semicolon_token != 0);
240
241     NewExpressionAST *expr = stmt->expression->asNewExpression();
242     QVERIFY(expr != 0);
243
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);
252 }
253
254 void tst_AST::condition_1()
255 {
256     QSharedPointer<TranslationUnit> unit(parseExpression("\n"
257                                                          "(x < 0 && y > (int) a)"
258     ));
259
260     AST *ast = unit->ast();
261     QVERIFY(ast != 0);
262     NestedExpressionAST *nestedExpr = ast->asNestedExpression();
263     QVERIFY(nestedExpr);
264     QVERIFY(nestedExpr->expression);
265     BinaryExpressionAST *andExpr = nestedExpr->expression->asBinaryExpression();
266     QVERIFY(andExpr);
267     QCOMPARE(unit->tokenKind(andExpr->binary_op_token), (int) T_AMPER_AMPER);
268     QVERIFY(andExpr->left_expression);
269     QVERIFY(andExpr->right_expression);
270
271     BinaryExpressionAST *ltExpr = andExpr->left_expression->asBinaryExpression();
272     QVERIFY(ltExpr);
273     QCOMPARE(unit->tokenKind(ltExpr->binary_op_token), (int) T_LESS);
274     QVERIFY(ltExpr->left_expression);
275     QVERIFY(ltExpr->right_expression);
276
277     SimpleNameAST *x = ltExpr->left_expression->asIdExpression()->name->asSimpleName();
278     QVERIFY(x);
279     QCOMPARE(unit->spell(x->identifier_token), "x");
280
281     NumericLiteralAST *zero = ltExpr->right_expression->asNumericLiteral();
282     QVERIFY(zero);
283     QCOMPARE(unit->spell(zero->literal_token), "0");
284
285     BinaryExpressionAST *gtExpr = andExpr->right_expression->asBinaryExpression();
286     QVERIFY(gtExpr);
287     QCOMPARE(unit->tokenKind(gtExpr->binary_op_token), (int) T_GREATER);
288     QVERIFY(gtExpr->left_expression);
289     QVERIFY(gtExpr->right_expression);
290
291     SimpleNameAST *y = gtExpr->left_expression->asIdExpression()->name->asSimpleName();
292     QVERIFY(y);
293     QCOMPARE(unit->spell(y->identifier_token), "y");
294
295     CastExpressionAST *cast = gtExpr->right_expression->asCastExpression();
296     QVERIFY(cast);
297     QVERIFY(cast->type_id);
298     QVERIFY(cast->expression);
299
300     TypeIdAST *intType = cast->type_id->asTypeId();
301     QVERIFY(intType);
302     // ### here we could check if the type is an actual int
303
304     SimpleNameAST *a = cast->expression->asIdExpression()->name->asSimpleName();
305     QVERIFY(a);
306     QCOMPARE(unit->spell(a->identifier_token), "a");
307 }
308
309 void tst_AST::init_1()
310 {
311     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
312                                                           "x y[] = { X<10>, y };"
313     ));
314
315     AST *ast = unit->ast();
316     QVERIFY(ast != 0);
317 }
318
319 void tst_AST::conditional_1()
320 {
321     QSharedPointer<TranslationUnit> unit(parseExpression("\n"
322                                                          "(x < 0 && y > (int) a) ? x == 1 : y = 1"
323     ));
324
325     AST *ast = unit->ast();
326     QVERIFY(ast != 0);
327
328     ConditionalExpressionAST *conditional = ast->asConditionalExpression();
329     QVERIFY(conditional);
330     QVERIFY(conditional->condition);
331     QVERIFY(conditional->left_expression);
332     QVERIFY(conditional->right_expression);
333
334     NestedExpressionAST *nestedExpr = conditional->condition->asNestedExpression();
335     QVERIFY(nestedExpr);
336     QVERIFY(nestedExpr->expression);
337     BinaryExpressionAST *andExpr = nestedExpr->expression->asBinaryExpression();
338     QVERIFY(andExpr);
339     QCOMPARE(unit->tokenKind(andExpr->binary_op_token), (int) T_AMPER_AMPER);
340     QVERIFY(andExpr->left_expression);
341     QVERIFY(andExpr->right_expression);
342
343     BinaryExpressionAST *ltExpr = andExpr->left_expression->asBinaryExpression();
344     QVERIFY(ltExpr);
345     QCOMPARE(unit->tokenKind(ltExpr->binary_op_token), (int) T_LESS);
346     QVERIFY(ltExpr->left_expression);
347     QVERIFY(ltExpr->right_expression);
348
349     SimpleNameAST *x = ltExpr->left_expression->asIdExpression()->name->asSimpleName();
350     QVERIFY(x);
351     QCOMPARE(unit->spell(x->identifier_token), "x");
352
353     NumericLiteralAST *zero = ltExpr->right_expression->asNumericLiteral();
354     QVERIFY(zero);
355     QCOMPARE(unit->spell(zero->literal_token), "0");
356
357     BinaryExpressionAST *gtExpr = andExpr->right_expression->asBinaryExpression();
358     QVERIFY(gtExpr);
359     QCOMPARE(unit->tokenKind(gtExpr->binary_op_token), (int) T_GREATER);
360     QVERIFY(gtExpr->left_expression);
361     QVERIFY(gtExpr->right_expression);
362
363     SimpleNameAST *y = gtExpr->left_expression->asIdExpression()->name->asSimpleName();
364     QVERIFY(y);
365     QCOMPARE(unit->spell(y->identifier_token), "y");
366
367     CastExpressionAST *cast = gtExpr->right_expression->asCastExpression();
368     QVERIFY(cast);
369     QVERIFY(cast->type_id);
370     QVERIFY(cast->expression);
371
372     TypeIdAST *intType = cast->type_id->asTypeId();
373     QVERIFY(intType);
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();
379     QVERIFY(intSpec);
380     QCOMPARE(unit->spell(intSpec->specifier_token), "int");
381
382     SimpleNameAST *a = cast->expression->asIdExpression()->name->asSimpleName();
383     QVERIFY(a);
384     QCOMPARE(unit->spell(a->identifier_token), "a");
385
386     BinaryExpressionAST *equals = conditional->left_expression->asBinaryExpression();
387     QVERIFY(equals);
388     QCOMPARE(unit->tokenKind(equals->binary_op_token), (int) T_EQUAL_EQUAL);
389
390     x = equals->left_expression->asIdExpression()->name->asSimpleName();
391     QVERIFY(x);
392     QCOMPARE(unit->spell(x->identifier_token), "x");
393
394     NumericLiteralAST *one = equals->right_expression->asNumericLiteral();
395     QVERIFY(one);
396     QCOMPARE(unit->spell(one->literal_token), "1");
397
398     BinaryExpressionAST *assignment = conditional->right_expression->asBinaryExpression();
399     QVERIFY(assignment);
400     QCOMPARE(unit->tokenKind(assignment->binary_op_token), (int) T_EQUAL);
401
402     y = assignment->left_expression->asIdExpression()->name->asSimpleName();
403     QVERIFY(y);
404     QCOMPARE(unit->spell(y->identifier_token), "y");
405
406     one = assignment->right_expression->asNumericLiteral();
407     QVERIFY(one);
408     QCOMPARE(unit->spell(one->literal_token), "1");
409 }
410
411 void tst_AST::throw_1()
412 {
413     QSharedPointer<TranslationUnit> unit(parseStatement("throw 1;"));
414     AST *ast = unit->ast();
415     QVERIFY(ast != 0);
416     QVERIFY(ast->asExpressionStatement());
417 }
418
419 void tst_AST::call_call_1()
420 {
421     QSharedPointer<TranslationUnit> unit(parseStatement("method()->call();"));
422     AST *ast = unit->ast();
423     QVERIFY(ast != 0);
424
425     ExpressionStatementAST *exprStmt = ast->asExpressionStatement();
426     QVERIFY(exprStmt);
427
428     ExpressionAST *expr = exprStmt->expression;
429     QVERIFY(expr);
430
431     CallAST *memberCall = expr->asCall();
432     QVERIFY(memberCall);
433     QVERIFY(memberCall->base_expression);
434     QVERIFY(!memberCall->expression_list);
435
436     MemberAccessAST *member_xs = memberCall->base_expression->asMemberAccess();
437     QVERIFY(member_xs);
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");
443
444     QCOMPARE(unit->tokenKind(member_xs->access_token), (int) T_ARROW);
445
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");
458 }
459
460 void tst_AST::function_call_1()
461 {
462     QSharedPointer<TranslationUnit> unit(parseStatement("retranslateUi(blah);"));
463     AST *ast = unit->ast();
464     QVERIFY(ast != 0);
465     QVERIFY(ast->asExpressionStatement());
466 }
467
468 void tst_AST::function_call_2()
469 {
470     QSharedPointer<TranslationUnit> unit(parseStatement("retranslateUi(10);"));
471     AST *ast = unit->ast();
472     QVERIFY(ast != 0);
473     QVERIFY(ast->asExpressionStatement());
474 }
475
476 void tst_AST::function_call_3()
477 {
478     QSharedPointer<TranslationUnit> unit(parseStatement("advance();"));
479     AST *ast = unit->ast();
480     QVERIFY(ast != 0);
481     QVERIFY(ast->asExpressionStatement());
482 }
483
484 void tst_AST::function_call_4()
485 {
486     QSharedPointer<TranslationUnit> unit(parseStatement("checkPropertyAttribute(attrAst, propAttrs, ReadWrite);"));
487     AST *ast = unit->ast();
488     QVERIFY(ast != 0);
489     QVERIFY(ast->asExpressionStatement());
490 }
491
492 void tst_AST::nested_deref_expression()
493 {
494     QSharedPointer<TranslationUnit> unit(parseStatement("(*blah);"));
495     AST *ast = unit->ast();
496     QVERIFY(ast != 0);
497     QVERIFY(ast->asExpressionStatement());
498 }
499
500 void tst_AST::assignment_1()
501 {
502     QSharedPointer<TranslationUnit> unit(parseStatement("a(x) = 3;"));
503     AST *ast = unit->ast();
504     QVERIFY(ast != 0);
505     QVERIFY(ast->asExpressionStatement());
506 }
507
508 void tst_AST::assignment_2()
509 {
510     QSharedPointer<TranslationUnit> unit(parseStatement("(*blah) = 10;"));
511     AST *ast = unit->ast();
512     QVERIFY(ast != 0);
513     QVERIFY(ast->asExpressionStatement());
514 }
515
516 void tst_AST::if_statement_1()
517 {
518     QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b;"));
519
520     AST *ast = unit->ast();
521     QVERIFY(ast != 0);
522
523     IfStatementAST *stmt = ast->asIfStatement();
524     QVERIFY(stmt != 0);
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);
532
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);
538
539     SimpleNameAST *id_expr = then_stmt->expression->asIdExpression()->name->asSimpleName();
540     QVERIFY(id_expr != 0);
541     QCOMPARE(id_expr->identifier_token, 5U);
542 }
543
544 void tst_AST::if_statement_2()
545 {
546     QSharedPointer<TranslationUnit> unit(parseStatement("if (x<0 && y>a);"));
547
548     AST *ast = unit->ast();
549     QVERIFY(ast != 0);
550
551     IfStatementAST *stmt = ast->asIfStatement();
552     QVERIFY(stmt != 0);
553
554     QVERIFY(stmt->condition);
555     QVERIFY(stmt->condition->asBinaryExpression());
556     QCOMPARE(unit->tokenKind(stmt->condition->asBinaryExpression()->binary_op_token), int(T_AMPER_AMPER));
557 }
558
559 void tst_AST::if_statement_3()
560 {
561     QSharedPointer<TranslationUnit> unit(parseStatement("if (x<0 && x<0 && x<0 && x<0 && x<0 && x<0 && x<0);"));
562
563     AST *ast = unit->ast();
564     QVERIFY(ast != 0);
565
566     IfStatementAST *stmt = ast->asIfStatement();
567     QVERIFY(stmt != 0);
568
569     QVERIFY(stmt->condition);
570 }
571
572 void tst_AST::if_else_statement()
573 {
574     QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b; else c;"));
575
576     AST *ast = unit->ast();
577     QVERIFY(ast != 0);
578
579     IfStatementAST *stmt = ast->asIfStatement();
580     QVERIFY(stmt != 0);
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);
588
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);
594
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);
598
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);
604
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);
608 }
609
610 void tst_AST::while_statement()
611 {
612     QSharedPointer<TranslationUnit> unit(parseStatement("while (a) { }"));
613
614     AST *ast = unit->ast();
615     QVERIFY(ast != 0);
616
617     WhileStatementAST *stmt = ast->asWhileStatement();
618     QVERIFY(stmt != 0);
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);
624
625     // check condition
626     QVERIFY(stmt->condition->asIdExpression()->name->asSimpleName() != 0);
627     QCOMPARE(stmt->condition->asIdExpression()->name->asSimpleName()->identifier_token, 3U);
628
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);
635 }
636
637 void tst_AST::while_condition_statement()
638 {
639     QSharedPointer<TranslationUnit> unit(parseStatement("while (int a = foo) { }"));
640
641     AST *ast = unit->ast();
642     QVERIFY(ast != 0);
643
644     WhileStatementAST *stmt = ast->asWhileStatement();
645     QVERIFY(stmt != 0);
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);
651
652     // check condition
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);
669
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);
676 }
677
678 void tst_AST::for_statement()
679 {
680     QSharedPointer<TranslationUnit> unit(parseStatement("for (;;) {}"));
681     AST *ast = unit->ast();
682     QVERIFY(ast != 0);
683
684     ForStatementAST *stmt = ast->asForStatement();
685     QVERIFY(stmt != 0);
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);
700 }
701
702 void tst_AST::cpp_initializer_or_function_declaration()
703 {
704     QSharedPointer<TranslationUnit> unit(parseStatement("QFileInfo fileInfo(foo);"));
705     AST *ast = unit->ast();
706     QVERIFY(ast != 0);
707
708     DeclarationStatementAST *stmt = ast->asDeclarationStatement();
709     QVERIFY(stmt != 0);
710
711     QVERIFY(stmt->declaration != 0);
712
713     SimpleDeclarationAST *simple_decl = stmt->declaration->asSimpleDeclaration();
714     QVERIFY(simple_decl != 0);
715
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);
721
722     NamedTypeSpecifierAST *named_ty = simple_decl->decl_specifier_list->value->asNamedTypeSpecifier();
723     QVERIFY(named_ty != 0);
724     QVERIFY(named_ty->name != 0);
725
726     SimpleNameAST *simple_named_ty = named_ty->name->asSimpleName();
727     QVERIFY(simple_named_ty != 0);
728     QCOMPARE(simple_named_ty->identifier_token, 1U);
729
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);
736
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);
742
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);
748
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);
754
755     // check the parameter
756     ParameterDeclarationListAST *declarations = param_clause->parameter_declaration_list;
757     QVERIFY(declarations);
758     QVERIFY(declarations->value);
759     QVERIFY(! declarations->next);
760
761     ParameterDeclarationAST *param = declarations->value->asParameterDeclaration();
762     QVERIFY(param);
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);
769 }
770
771 void tst_AST::objc_simple_class()
772 {
773     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
774                                                           "@interface Zoo {} +(id)alloc;-(id)init;@end\n"
775                                                           "@implementation Zoo\n"
776                                                           "+(id)alloc{}\n"
777                                                           "-(id)init{}\n"
778                                                           "@end\n"
779                                                           ));
780
781     AST *ast = unit->ast();
782     QVERIFY(ast);
783 }
784
785 void tst_AST::objc_attributes_followed_by_at_keyword()
786 {
787     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
788 "__attribute__((deprecated)) @interface foo <bar>\n"
789 "{\n"
790 " int a, b;\n"
791 "}\n"
792 "+ (id) init;\n"
793 "- (id) init:(int)a foo:(int)b, c;\n"
794 "@end\n"
795     ));
796     AST *ast = unit->ast();
797     QVERIFY(ast);
798 }
799
800 void tst_AST::objc_protocol_forward_declaration_1()
801 {
802     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo;"));
803     AST *ast = unit->ast();
804     QVERIFY(ast);
805 }
806
807 void tst_AST::objc_protocol_definition_1()
808 {
809     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo <ciao, bar> @end"));
810     AST *ast = unit->ast();
811     QVERIFY(ast);
812 }
813
814 void tst_AST::objc_method_attributes_1()
815 {
816     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
817                                                           "@interface Zoo\n"
818                                                           "- (void) foo __attribute__((deprecated));\n"
819                                                           "+ (void) bar __attribute__((unavailable));\n"
820                                                           "@end\n"
821                                                           ));
822     AST *ast = unit->ast();
823     QVERIFY(ast);
824     ObjCClassDeclarationAST *zoo = ast->asObjCClassDeclaration();
825     QVERIFY(zoo);
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");
829
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));
835
836     ObjCMethodDeclarationAST *fooDecl = decls->value->asObjCMethodDeclaration();
837     QVERIFY(fooDecl);
838     QVERIFY(! (fooDecl->function_body));
839     QVERIFY(fooDecl->semicolon_token);
840
841     ObjCMethodPrototypeAST *foo = fooDecl->method_prototype;
842     QVERIFY(foo);
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");
862
863     ObjCMethodDeclarationAST *barDecl = decls->next->value->asObjCMethodDeclaration();
864     QVERIFY(barDecl);
865     QVERIFY(! (barDecl->function_body));
866     QVERIFY(barDecl->semicolon_token);
867
868     ObjCMethodPrototypeAST *bar = barDecl->method_prototype;
869     QVERIFY(bar);
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");
890 }
891
892 /*
893   @selector(foo)
894   @selector(foo:)
895   @selector(foo:bar:)
896   ...
897  */
898 void tst_AST::objc_selector_error_recovery_1()
899 {
900     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
901                                                           "void tst() {\n"
902                                                           "    @selector(foo:\n"
903                                                           "    int i = 1;\n"
904                                                           "}\n"
905                                                           ));
906     AST *ast = unit->ast();
907     QVERIFY(ast);
908 }
909
910 void tst_AST::objc_selector_error_recovery_2()
911 {
912     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
913                                                           "void tst() {\n"
914                                                           "    @selector(foo:bar);\n"
915                                                           "}\n"
916                                                           ));
917     AST *ast = unit->ast();
918     QVERIFY(ast);
919 }
920
921 void tst_AST::normal_array_access()
922 {
923     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
924                                                           "int f() {\n"
925                                                           "  int a[10];\n"
926                                                           "  int b = 1;\n"
927                                                           "  return a[b];\n"
928                                                           "}"
929                                                           ));
930     AST *ast = unit->ast();
931     QVERIFY(ast);
932
933     FunctionDefinitionAST *func = ast->asFunctionDefinition();
934     QVERIFY(func);
935
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;
942     QVERIFY(expr);
943
944     ArrayAccessAST *arrayExpr = expr->asArrayAccess();
945     QVERIFY(arrayExpr);
946
947     { // check the left-hand side:
948         ExpressionAST *lhs = arrayExpr->base_expression;
949         QVERIFY(lhs);
950         SimpleNameAST *a = lhs->asIdExpression()->name->asSimpleName();
951         QVERIFY(a);
952         QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a"));
953     }
954
955     { // check the right-hand side:
956         QVERIFY(arrayExpr->expression);
957         SimpleNameAST *b = arrayExpr->expression->asIdExpression()->name->asSimpleName();
958         QVERIFY(b);
959         QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b"));
960     }
961 }
962
963 void tst_AST::array_access_with_nested_expression()
964 {
965     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
966                                                           "int f() {\n"
967                                                           "  int a[15];\n"
968                                                           "  int b = 1;\n"
969                                                           "  return (a)[b];\n"
970                                                           "}"
971                                                           ));
972     AST *ast = unit->ast();
973     QVERIFY(ast);
974
975     FunctionDefinitionAST *func = ast->asFunctionDefinition();
976     QVERIFY(func);
977
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;
981     QVERIFY(expr);
982
983     CastExpressionAST *castExpr = expr->asCastExpression();
984     QVERIFY(!castExpr);
985
986     ArrayAccessAST *arrayExpr = expr->asArrayAccess();
987     QVERIFY(arrayExpr);
988
989     { // check the LHS:
990         ExpressionAST *lhs = arrayExpr->base_expression;
991         QVERIFY(lhs);
992         NestedExpressionAST *nested_a = lhs->asNestedExpression();
993         QVERIFY(nested_a && nested_a->expression);
994         SimpleNameAST *a = nested_a->expression->asIdExpression()->name->asSimpleName();
995         QVERIFY(a);
996         QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a"));
997     }
998
999     { // check the RHS:
1000         QVERIFY(arrayExpr->expression);
1001         SimpleNameAST *b = arrayExpr->expression->asIdExpression()->name->asSimpleName();
1002         QVERIFY(b);
1003         QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b"));
1004     }
1005 }
1006
1007 void tst_AST::objc_msg_send_expression()
1008 {
1009     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
1010                                                           "int f() {\n"
1011                                                           "  NSObject *obj = [[[NSObject alloc] init] autorelease];\n"
1012                                                           "  return [obj description];\n"
1013                                                           "}"
1014                                                           ));
1015     AST *ast = unit->ast();
1016     QVERIFY(ast);
1017
1018     FunctionDefinitionAST *func = ast->asFunctionDefinition();
1019     QVERIFY(func);
1020
1021     StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statement_list;
1022     QVERIFY(bodyStatements && bodyStatements->next && !bodyStatements->next->next && bodyStatements->next->value);
1023
1024     {// check the NSObject declaration
1025         DeclarationStatementAST *firstStatement = bodyStatements->value->asDeclarationStatement();
1026         QVERIFY(firstStatement);
1027         DeclarationAST *objDecl = firstStatement->declaration;
1028         QVERIFY(objDecl);
1029         SimpleDeclarationAST *simpleDecl = objDecl->asSimpleDeclaration();
1030         QVERIFY(simpleDecl);
1031
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();
1037             QVERIFY(typeName);
1038             QCOMPARE(QLatin1String(unit->identifier(typeName->identifier_token)->chars()), QLatin1String("NSObject"));
1039         }
1040
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);
1046
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);
1050
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"));
1055
1056             QVERIFY(!declarator->postfix_declarator_list);
1057             QVERIFY(!declarator->post_attribute_list);
1058             ExpressionAST *initializer = declarator->initializer;
1059             QVERIFY(initializer);
1060
1061             ObjCMessageExpressionAST *expr1 = initializer->asObjCMessageExpression();
1062             QVERIFY(expr1 && expr1->receiver_expression && expr1->selector && !expr1->argument_list);
1063
1064             ObjCMessageExpressionAST *expr2 = expr1->receiver_expression->asObjCMessageExpression();
1065             QVERIFY(expr2 && expr2->receiver_expression && expr2->selector && !expr2->argument_list);
1066
1067             ObjCMessageExpressionAST *expr3 = expr2->receiver_expression->asObjCMessageExpression();
1068             QVERIFY(expr3 && expr3->receiver_expression && expr3->selector && !expr3->argument_list);
1069         }
1070     }
1071
1072     {// check the return statement
1073         ExpressionAST *expr = bodyStatements->next->value->asReturnStatement()->expression;
1074         QVERIFY(expr);
1075
1076         ObjCMessageExpressionAST *msgExpr = expr->asObjCMessageExpression();
1077         QVERIFY(msgExpr);
1078
1079         QVERIFY(msgExpr->receiver_expression);
1080         SimpleNameAST *receiver = msgExpr->receiver_expression->asIdExpression()->name->asSimpleName();
1081         QVERIFY(receiver);
1082         QCOMPARE(QLatin1String(unit->identifier(receiver->identifier_token)->chars()), QLatin1String("obj"));
1083
1084         QVERIFY(msgExpr->argument_list == 0);
1085
1086         QVERIFY(msgExpr->selector);
1087         ObjCSelectorArgumentListAST *args = msgExpr->selector->selector_argument_list;
1088         QVERIFY(args);
1089         QVERIFY(args->value);
1090         QVERIFY(! args->next);
1091         QCOMPARE(QLatin1String(unit->identifier(args->value->name_token)->chars()), QLatin1String("description"));
1092     }
1093 }
1094
1095 void tst_AST::objc_msg_send_expression_without_selector()
1096 {
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"
1099                                                           "int f() {\n"
1100                                                           "  NSObject *obj = [[[NSObject alloc] init] autorelease];\n"
1101                                                           "  return [obj];\n"
1102                                                           "}",
1103                                                           true));
1104     AST *ast = unit->ast();
1105     QVERIFY(ast);
1106
1107     FunctionDefinitionAST *func = ast->asFunctionDefinition();
1108     QVERIFY(func);
1109
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);
1115 }
1116
1117 void tst_AST::q_enum_1()
1118 {
1119     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n"
1120                                                           "class Tst {\n"
1121                                                           "Q_ENUMS(e)\n"
1122                                                           "public:\n"
1123                                                           "enum e { x, y };\n"
1124                                                           "};\n",
1125                                                           false, true));
1126     QVERIFY(unit->ast());
1127     SimpleDeclarationAST *tstDecl = unit->ast()->asSimpleDeclaration();
1128     QVERIFY(tstDecl);
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();
1134     QVERIFY(tst);
1135
1136     QVERIFY(tst->member_specifier_list);
1137     QVERIFY(tst->member_specifier_list->value);
1138     QtEnumDeclarationAST *qtEnum = tst->member_specifier_list->value->asQtEnumDeclaration();
1139     QVERIFY(qtEnum);
1140     QVERIFY(qtEnum->enumerator_list);
1141     QVERIFY(qtEnum->enumerator_list->value);
1142     QVERIFY(! qtEnum->enumerator_list->next);
1143
1144     SimpleNameAST *e = qtEnum->enumerator_list->value->asSimpleName();
1145     QVERIFY(e);
1146     QCOMPARE(unit->spell(e->identifier_token), "e");
1147 }
1148
1149 void tst_AST::initTestCase()
1150 {
1151     control.setDiagnosticClient(&diag);
1152 }
1153
1154 QTEST_APPLESS_MAIN(tst_AST)
1155 #include "tst_ast.moc"