| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <QtTest>
 | 
					
						
							|  |  |  | #include <QtDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <Control.h>
 | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  | #include <Literals.h>
 | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | #include <Parser.h>
 | 
					
						
							|  |  |  | #include <AST.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 11:21:25 +02:00
										 |  |  | using namespace CPlusPlus; | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | class tst_AST: public QObject | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_OBJECT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Control control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |     TranslationUnit *parse(const QByteArray &source, | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  |                            TranslationUnit::ParseMode mode, | 
					
						
							|  |  |  |                            bool blockErrors = false) | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2009-06-19 11:19:41 +02:00
										 |  |  |         StringLiteral *fileId = control.findOrInsertStringLiteral("<stdin>"); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |         TranslationUnit *unit = new TranslationUnit(&control, fileId); | 
					
						
							| 
									
										
										
										
											2009-01-12 14:55:33 +01:00
										 |  |  |         unit->setObjCEnabled(true); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |         unit->setSource(source.constData(), source.length()); | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  |         unit->blockErrors(blockErrors); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |         unit->parse(mode); | 
					
						
							|  |  |  |         return unit; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  |     TranslationUnit *parseDeclaration(const QByteArray &source, bool blockErrors = false) | 
					
						
							|  |  |  |     { return parse(source, TranslationUnit::ParseDeclaration, blockErrors); } | 
					
						
							| 
									
										
										
										
											2009-01-12 14:55:33 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 13:37:10 +01:00
										 |  |  |     TranslationUnit *parseExpression(const QByteArray &source) | 
					
						
							|  |  |  |     { return parse(source, TranslationUnit::ParseExpression); } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |     TranslationUnit *parseStatement(const QByteArray &source) | 
					
						
							|  |  |  |     { return parse(source, TranslationUnit::ParseStatement); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | private slots: | 
					
						
							| 
									
										
										
										
											2009-01-14 15:16:02 +01:00
										 |  |  |     // declarations
 | 
					
						
							|  |  |  |     void gcc_attributes_1(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 13:37:10 +01:00
										 |  |  |     // expressions
 | 
					
						
							| 
									
										
										
										
											2009-10-20 15:29:58 +02:00
										 |  |  |     void simple_name_1(); | 
					
						
							|  |  |  |     void template_id_1(); | 
					
						
							| 
									
										
										
										
											2009-02-10 14:43:19 +01:00
										 |  |  |     void new_expression_1(); | 
					
						
							|  |  |  |     void new_expression_2(); | 
					
						
							| 
									
										
										
										
											2009-06-19 11:23:30 +02:00
										 |  |  |     void condition_1(); | 
					
						
							| 
									
										
										
										
											2009-06-19 12:39:11 +02:00
										 |  |  |     void init_1(); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:37:10 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // statements
 | 
					
						
							| 
									
										
										
										
											2009-10-20 15:29:58 +02:00
										 |  |  |     void if_statement_1(); | 
					
						
							|  |  |  |     void if_statement_2(); | 
					
						
							|  |  |  |     void if_statement_3(); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  |     void if_else_statement(); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:05:02 +01:00
										 |  |  |     void while_statement(); | 
					
						
							|  |  |  |     void while_condition_statement(); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:29:59 +01:00
										 |  |  |     void for_statement(); | 
					
						
							| 
									
										
										
										
											2008-12-15 12:50:21 +01:00
										 |  |  |     void cpp_initializer_or_function_declaration(); | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |     void simple_declaration_1(); | 
					
						
							|  |  |  |     void function_call_1(); | 
					
						
							|  |  |  |     void function_call_2(); | 
					
						
							|  |  |  |     void function_call_3(); | 
					
						
							| 
									
										
										
										
											2009-10-20 11:26:58 +02:00
										 |  |  |     void function_call_4(); | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |     void nested_deref_expression(); | 
					
						
							|  |  |  |     void assignment_1(); | 
					
						
							| 
									
										
										
										
											2009-10-20 11:26:58 +02:00
										 |  |  |     void assignment_2(); | 
					
						
							| 
									
										
										
										
											2009-01-12 14:55:33 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // objc++
 | 
					
						
							|  |  |  |     void objc_attributes_followed_by_at_keyword(); | 
					
						
							|  |  |  |     void objc_protocol_forward_declaration_1(); | 
					
						
							|  |  |  |     void objc_protocol_definition_1(); | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // expressions with (square) brackets
 | 
					
						
							|  |  |  |     void normal_array_access(); | 
					
						
							|  |  |  |     void array_access_with_nested_expression(); | 
					
						
							|  |  |  |     void objc_msg_send_expression(); | 
					
						
							|  |  |  |     void objc_msg_send_expression_without_selector(); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-14 15:16:02 +01:00
										 |  |  | 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);" | 
					
						
							|  |  |  |     )); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  | void tst_AST::simple_declaration_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("\n" | 
					
						
							|  |  |  | "a * b = 10;" | 
					
						
							|  |  |  |     )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DeclarationStatementAST *declStmt = ast->asDeclarationStatement(); | 
					
						
							|  |  |  |     QVERIFY(declStmt); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 15:29:58 +02:00
										 |  |  | void tst_AST::simple_name_1() | 
					
						
							| 
									
										
										
										
											2008-12-15 13:37:10 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseExpression("a")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asSimpleName() != 0); | 
					
						
							|  |  |  |     QCOMPARE(ast->asSimpleName()->identifier_token, 1U); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 15:29:58 +02:00
										 |  |  | void tst_AST::template_id_1() | 
					
						
							| 
									
										
										
										
											2008-12-15 13:37:10 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseExpression("list<10>")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asTemplateId() != 0); | 
					
						
							|  |  |  |     QCOMPARE(ast->asTemplateId()->identifier_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(ast->asTemplateId()->less_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(ast->asTemplateId()->template_arguments != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asTemplateId()->template_arguments->template_argument != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asTemplateId()->template_arguments->template_argument->asNumericLiteral() != 0); | 
					
						
							| 
									
										
										
										
											2009-06-19 11:19:41 +02:00
										 |  |  |     QCOMPARE(ast->asTemplateId()->template_arguments->template_argument->asNumericLiteral()->literal_token, 3U); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:37:10 +01:00
										 |  |  |     QVERIFY(ast->asTemplateId()->template_arguments->next == 0); | 
					
						
							|  |  |  |     QCOMPARE(ast->asTemplateId()->greater_token, 4U); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-10 14:43:19 +01:00
										 |  |  | void tst_AST::new_expression_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseExpression("\n" | 
					
						
							|  |  |  | "new char" | 
					
						
							|  |  |  |     )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NewExpressionAST *expr = ast->asNewExpression(); | 
					
						
							|  |  |  |     QVERIFY(expr != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QCOMPARE(expr->scope_token, 0U); | 
					
						
							|  |  |  |     QCOMPARE(expr->new_token, 1U); | 
					
						
							|  |  |  |     QVERIFY(expr->new_placement == 0); | 
					
						
							|  |  |  |     QCOMPARE(expr->lparen_token, 0U); | 
					
						
							|  |  |  |     QVERIFY(expr->type_id == 0); | 
					
						
							|  |  |  |     QCOMPARE(expr->rparen_token, 0U); | 
					
						
							|  |  |  |     QVERIFY(expr->new_type_id != 0); | 
					
						
							|  |  |  |     QVERIFY(expr->new_initializer == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(expr->new_type_id->type_specifier != 0); | 
					
						
							|  |  |  |     QVERIFY(expr->new_type_id->ptr_operators == 0); | 
					
						
							|  |  |  |     QVERIFY(expr->new_type_id->new_array_declarators == 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::new_expression_2() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("\n" | 
					
						
							|  |  |  | "::new(__p) _Tp(__val);" | 
					
						
							|  |  |  |     )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ExpressionStatementAST *stmt = ast->asExpressionStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  |     QVERIFY(stmt->expression != 0); | 
					
						
							|  |  |  |     QVERIFY(stmt->semicolon_token != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NewExpressionAST *expr = stmt->expression->asNewExpression(); | 
					
						
							|  |  |  |     QVERIFY(expr != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QCOMPARE(expr->scope_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(expr->new_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(expr->new_placement != 0); | 
					
						
							|  |  |  |     QCOMPARE(expr->lparen_token, 0U); | 
					
						
							|  |  |  |     QVERIFY(expr->type_id == 0); | 
					
						
							|  |  |  |     QCOMPARE(expr->rparen_token, 0U); | 
					
						
							|  |  |  |     QVERIFY(expr->new_type_id != 0); | 
					
						
							|  |  |  |     QVERIFY(expr->new_initializer != 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-19 11:23:30 +02:00
										 |  |  | void tst_AST::condition_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseExpression("\n" | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  | "(x < 0 && y > (int) a)" | 
					
						
							| 
									
										
										
										
											2009-06-19 11:23:30 +02:00
										 |  |  |     )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-19 12:39:11 +02:00
										 |  |  | void tst_AST::init_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" | 
					
						
							|  |  |  |                                                           "x y[] = { X<10>, y };" | 
					
						
							|  |  |  |     )); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  | void tst_AST::function_call_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("retranslateUi(blah);")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::function_call_2() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("retranslateUi(10);")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::function_call_3() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-10-20 11:26:58 +02:00
										 |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("advance();")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::function_call_4() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("checkPropertyAttribute(attrAst, propAttrs, ReadWrite);")); | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::nested_deref_expression() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("(*blah);")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::assignment_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("a(x) = 3;")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 11:26:58 +02:00
										 |  |  | void tst_AST::assignment_2() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("(*blah) = 10;")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  |     QVERIFY(ast->asExpressionStatement()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 15:29:58 +02:00
										 |  |  | void tst_AST::if_statement_1() | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b;")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IfStatementAST *stmt = ast->asIfStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->if_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(stmt->lparen_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(stmt->condition != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->rparen_token, 4U); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->else_token, 0U); | 
					
						
							|  |  |  |     QVERIFY(stmt->else_statement == 0); | 
					
						
							| 
									
										
										
										
											2008-12-15 12:24:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |     // check the `then' statement1
 | 
					
						
							| 
									
										
										
										
											2008-12-15 12:24:41 +01:00
										 |  |  |     ExpressionStatementAST *then_stmt = stmt->statement->asExpressionStatement(); | 
					
						
							|  |  |  |     QVERIFY(then_stmt != 0); | 
					
						
							|  |  |  |     QVERIFY(then_stmt->expression != 0); | 
					
						
							|  |  |  |     QCOMPARE(then_stmt->semicolon_token, 6U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SimpleNameAST *id_expr = then_stmt->expression->asSimpleName(); | 
					
						
							|  |  |  |     QVERIFY(id_expr != 0); | 
					
						
							|  |  |  |     QCOMPARE(id_expr->identifier_token, 5U); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 15:29:58 +02:00
										 |  |  | void tst_AST::if_statement_2() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("if (x<0 && y>a);")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IfStatementAST *stmt = ast->asIfStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(stmt->condition); | 
					
						
							|  |  |  |     QVERIFY(stmt->condition->asBinaryExpression()); | 
					
						
							|  |  |  |     QCOMPARE(unit->tokenKind(stmt->condition->asBinaryExpression()->binary_op_token), int(T_AMPER_AMPER)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::if_statement_3() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("if (x<0 && x<0 && x<0 && x<0 && x<0 && x<0 && x<0);")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IfStatementAST *stmt = ast->asIfStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(stmt->condition); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | void tst_AST::if_else_statement() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b; else c;")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     IfStatementAST *stmt = ast->asIfStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->if_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(stmt->lparen_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(stmt->condition != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->rparen_token, 4U); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->else_token, 7U); | 
					
						
							|  |  |  |     QVERIFY(stmt->else_statement != 0); | 
					
						
							| 
									
										
										
										
											2008-12-15 12:50:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // check the `then' statement
 | 
					
						
							|  |  |  |     ExpressionStatementAST *then_stmt = stmt->statement->asExpressionStatement(); | 
					
						
							|  |  |  |     QVERIFY(then_stmt != 0); | 
					
						
							|  |  |  |     QVERIFY(then_stmt->expression != 0); | 
					
						
							|  |  |  |     QCOMPARE(then_stmt->semicolon_token, 6U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SimpleNameAST *a_id_expr = then_stmt->expression->asSimpleName(); | 
					
						
							|  |  |  |     QVERIFY(a_id_expr != 0); | 
					
						
							|  |  |  |     QCOMPARE(a_id_expr->identifier_token, 5U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check the `then' statement
 | 
					
						
							|  |  |  |     ExpressionStatementAST *else_stmt = stmt->else_statement->asExpressionStatement(); | 
					
						
							|  |  |  |     QVERIFY(else_stmt != 0); | 
					
						
							|  |  |  |     QVERIFY(else_stmt->expression != 0); | 
					
						
							|  |  |  |     QCOMPARE(else_stmt->semicolon_token, 9U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SimpleNameAST *b_id_expr = else_stmt->expression->asSimpleName(); | 
					
						
							|  |  |  |     QVERIFY(b_id_expr != 0); | 
					
						
							|  |  |  |     QCOMPARE(b_id_expr->identifier_token, 8U); | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 13:05:02 +01:00
										 |  |  | void tst_AST::while_statement() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("while (a) { }")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WhileStatementAST *stmt = ast->asWhileStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->while_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(stmt->lparen_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(stmt->condition != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->rparen_token, 4U); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check condition
 | 
					
						
							|  |  |  |     QVERIFY(stmt->condition->asSimpleName() != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->condition->asSimpleName()->identifier_token, 3U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check the `body' statement
 | 
					
						
							|  |  |  |     CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement(); | 
					
						
							|  |  |  |     QVERIFY(body_stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(body_stmt->lbrace_token, 5U); | 
					
						
							|  |  |  |     QVERIFY(body_stmt->statements == 0); | 
					
						
							|  |  |  |     QCOMPARE(body_stmt->rbrace_token, 6U); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::while_condition_statement() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("while (int a = foo) { }")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     WhileStatementAST *stmt = ast->asWhileStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->while_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(stmt->lparen_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(stmt->condition != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->rparen_token, 7U); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check condition
 | 
					
						
							|  |  |  |     ConditionAST *condition = stmt->condition->asCondition(); | 
					
						
							|  |  |  |     QVERIFY(condition != 0); | 
					
						
							|  |  |  |     QVERIFY(condition->type_specifier != 0); | 
					
						
							|  |  |  |     QVERIFY(condition->type_specifier->asSimpleSpecifier() != 0); | 
					
						
							|  |  |  |     QCOMPARE(condition->type_specifier->asSimpleSpecifier()->specifier_token, 3U); | 
					
						
							|  |  |  |     QVERIFY(condition->type_specifier->next == 0); | 
					
						
							|  |  |  |     QVERIFY(condition->declarator != 0); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:08:21 +01:00
										 |  |  |     QVERIFY(condition->declarator->core_declarator != 0); | 
					
						
							|  |  |  |     QVERIFY(condition->declarator->core_declarator->asDeclaratorId() != 0); | 
					
						
							|  |  |  |     QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name != 0); | 
					
						
							|  |  |  |     QVERIFY(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName() != 0); | 
					
						
							|  |  |  |     QCOMPARE(condition->declarator->core_declarator->asDeclaratorId()->name->asSimpleName()->identifier_token, 4U); | 
					
						
							|  |  |  |     QVERIFY(condition->declarator->postfix_declarators == 0); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:05:02 +01:00
										 |  |  |     QVERIFY(condition->declarator->initializer != 0); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:08:21 +01:00
										 |  |  |     QVERIFY(condition->declarator->initializer->asSimpleName() != 0); | 
					
						
							|  |  |  |     QCOMPARE(condition->declarator->initializer->asSimpleName()->identifier_token, 6U); | 
					
						
							| 
									
										
										
										
											2008-12-15 13:05:02 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // check the `body' statement
 | 
					
						
							|  |  |  |     CompoundStatementAST *body_stmt = stmt->statement->asCompoundStatement(); | 
					
						
							|  |  |  |     QVERIFY(body_stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(body_stmt->lbrace_token, 8U); | 
					
						
							|  |  |  |     QVERIFY(body_stmt->statements == 0); | 
					
						
							|  |  |  |     QCOMPARE(body_stmt->rbrace_token, 9U); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 13:29:59 +01:00
										 |  |  | void tst_AST::for_statement() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("for (;;) {}")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ForStatementAST *stmt = ast->asForStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->for_token, 1U); | 
					
						
							|  |  |  |     QCOMPARE(stmt->lparen_token, 2U); | 
					
						
							|  |  |  |     QVERIFY(stmt->initializer != 0); | 
					
						
							|  |  |  |     QVERIFY(stmt->initializer->asExpressionStatement() != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->initializer->asExpressionStatement()->semicolon_token, 3U); | 
					
						
							|  |  |  |     QVERIFY(stmt->condition == 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->semicolon_token, 4U); | 
					
						
							|  |  |  |     QVERIFY(stmt->expression == 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->rparen_token, 5U); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement != 0); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement->asCompoundStatement() != 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->statement->asCompoundStatement()->lbrace_token, 6U); | 
					
						
							|  |  |  |     QVERIFY(stmt->statement->asCompoundStatement()->statements == 0); | 
					
						
							|  |  |  |     QCOMPARE(stmt->statement->asCompoundStatement()->rbrace_token, 7U); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 12:50:21 +01:00
										 |  |  | void tst_AST::cpp_initializer_or_function_declaration() | 
					
						
							| 
									
										
										
										
											2008-12-15 12:24:41 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseStatement("QFileInfo fileInfo(foo);")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast != 0); | 
					
						
							| 
									
										
										
										
											2008-12-15 12:50:21 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     DeclarationStatementAST *stmt = ast->asDeclarationStatement(); | 
					
						
							|  |  |  |     QVERIFY(stmt != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(stmt->declaration != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SimpleDeclarationAST *simple_decl = stmt->declaration->asSimpleDeclaration(); | 
					
						
							|  |  |  |     QVERIFY(simple_decl != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QVERIFY(simple_decl->decl_specifier_seq != 0); | 
					
						
							|  |  |  |     QVERIFY(simple_decl->decl_specifier_seq->next == 0); | 
					
						
							|  |  |  |     QVERIFY(simple_decl->declarators != 0); | 
					
						
							|  |  |  |     QVERIFY(simple_decl->declarators->next == 0); | 
					
						
							|  |  |  |     QCOMPARE(simple_decl->semicolon_token, 6U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NamedTypeSpecifierAST *named_ty = simple_decl->decl_specifier_seq->asNamedTypeSpecifier(); | 
					
						
							|  |  |  |     QVERIFY(named_ty != 0); | 
					
						
							|  |  |  |     QVERIFY(named_ty->name != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     SimpleNameAST *simple_named_ty = named_ty->name->asSimpleName(); | 
					
						
							|  |  |  |     QVERIFY(simple_named_ty != 0); | 
					
						
							|  |  |  |     QCOMPARE(simple_named_ty->identifier_token, 1U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DeclaratorAST *declarator = simple_decl->declarators->declarator; | 
					
						
							|  |  |  |     QVERIFY(declarator != 0); | 
					
						
							|  |  |  |     QVERIFY(declarator->core_declarator != 0); | 
					
						
							|  |  |  |     QVERIFY(declarator->postfix_declarators != 0); | 
					
						
							|  |  |  |     QVERIFY(declarator->postfix_declarators->next == 0); | 
					
						
							|  |  |  |     QVERIFY(declarator->initializer == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     DeclaratorIdAST *decl_id = declarator->core_declarator->asDeclaratorId(); | 
					
						
							|  |  |  |     QVERIFY(decl_id != 0); | 
					
						
							|  |  |  |     QVERIFY(decl_id->name != 0); | 
					
						
							|  |  |  |     QVERIFY(decl_id->name->asSimpleName() != 0); | 
					
						
							|  |  |  |     QCOMPARE(decl_id->name->asSimpleName()->identifier_token, 2U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FunctionDeclaratorAST *fun_declarator = declarator->postfix_declarators->asFunctionDeclarator(); | 
					
						
							|  |  |  |     QVERIFY(fun_declarator != 0); | 
					
						
							|  |  |  |     QCOMPARE(fun_declarator->lparen_token, 3U); | 
					
						
							|  |  |  |     QVERIFY(fun_declarator->parameters != 0); | 
					
						
							|  |  |  |     QCOMPARE(fun_declarator->rparen_token, 5U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check the formal arguments
 | 
					
						
							|  |  |  |     ParameterDeclarationClauseAST *param_clause = fun_declarator->parameters; | 
					
						
							|  |  |  |     QVERIFY(param_clause->parameter_declarations != 0); | 
					
						
							|  |  |  |     QVERIFY(param_clause->parameter_declarations->next == 0); | 
					
						
							|  |  |  |     QCOMPARE(param_clause->dot_dot_dot_token, 0U); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // check the parameter
 | 
					
						
							| 
									
										
										
										
											2009-06-19 11:19:41 +02:00
										 |  |  |     DeclarationListAST *declarations = param_clause->parameter_declarations->asDeclarationList(); | 
					
						
							|  |  |  |     QVERIFY(declarations); | 
					
						
							|  |  |  |     QVERIFY(declarations->declaration); | 
					
						
							|  |  |  |     QVERIFY(! declarations->next); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ParameterDeclarationAST *param = declarations->declaration->asParameterDeclaration(); | 
					
						
							|  |  |  |     QVERIFY(param); | 
					
						
							| 
									
										
										
										
											2008-12-15 12:50:21 +01:00
										 |  |  |     QVERIFY(param->type_specifier != 0); | 
					
						
							|  |  |  |     QVERIFY(param->type_specifier->next == 0); | 
					
						
							|  |  |  |     QVERIFY(param->type_specifier->asNamedTypeSpecifier() != 0); | 
					
						
							|  |  |  |     QVERIFY(param->type_specifier->asNamedTypeSpecifier()->name != 0); | 
					
						
							|  |  |  |     QVERIFY(param->type_specifier->asNamedTypeSpecifier()->name->asSimpleName() != 0); | 
					
						
							|  |  |  |     QCOMPARE(param->type_specifier->asNamedTypeSpecifier()->name->asSimpleName()->identifier_token, 4U); | 
					
						
							| 
									
										
										
										
											2008-12-15 12:24:41 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 14:55:33 +01:00
										 |  |  | void tst_AST::objc_attributes_followed_by_at_keyword() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" | 
					
						
							|  |  |  | "__attribute__((deprecated)) @interface foo <bar>\n" | 
					
						
							|  |  |  | "{\n" | 
					
						
							|  |  |  | " int a, b;\n" | 
					
						
							|  |  |  | "}\n" | 
					
						
							|  |  |  | "+ (id) init;\n" | 
					
						
							|  |  |  | "- (id) init:(int)a foo:(int)b, c;\n" | 
					
						
							|  |  |  | "@end\n" | 
					
						
							|  |  |  |     )); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::objc_protocol_forward_declaration_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo;")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::objc_protocol_definition_1() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n@protocol foo <ciao, bar> @end")); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-12-15 12:24:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  | void tst_AST::normal_array_access() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" | 
					
						
							|  |  |  |                                                           "int f() {\n" | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |                                                           "  int a[10];\n" | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  |                                                           "  int b = 1;\n" | 
					
						
							|  |  |  |                                                           "  return a[b];\n" | 
					
						
							|  |  |  |                                                           "}" | 
					
						
							|  |  |  |                                                           )); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FunctionDefinitionAST *func = ast->asFunctionDefinition(); | 
					
						
							|  |  |  |     QVERIFY(func); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |     QVERIFY(bodyStatements); | 
					
						
							|  |  |  |     QVERIFY(bodyStatements->next); | 
					
						
							|  |  |  |     QVERIFY(bodyStatements->next->next); | 
					
						
							|  |  |  |     QVERIFY(bodyStatements->next->next->statement); | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  |     ExpressionAST *expr = bodyStatements->next->next->statement->asReturnStatement()->expression; | 
					
						
							|  |  |  |     QVERIFY(expr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PostfixExpressionAST *postfixExpr = expr->asPostfixExpression(); | 
					
						
							|  |  |  |     QVERIFY(postfixExpr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ExpressionAST *lhs = postfixExpr->base_expression; | 
					
						
							|  |  |  |         QVERIFY(lhs); | 
					
						
							|  |  |  |         SimpleNameAST *a = lhs->asSimpleName(); | 
					
						
							|  |  |  |         QVERIFY(a); | 
					
						
							|  |  |  |         QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QVERIFY(postfixExpr->postfix_expressions && !postfixExpr->postfix_expressions->next); | 
					
						
							|  |  |  |         ArrayAccessAST *rhs = postfixExpr->postfix_expressions->asArrayAccess(); | 
					
						
							|  |  |  |         QVERIFY(rhs && rhs->expression); | 
					
						
							|  |  |  |         SimpleNameAST *b = rhs->expression->asSimpleName(); | 
					
						
							|  |  |  |         QVERIFY(b); | 
					
						
							|  |  |  |         QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::array_access_with_nested_expression() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" | 
					
						
							|  |  |  |                                                           "int f() {\n" | 
					
						
							|  |  |  |                                                           "  int a[15];\n" | 
					
						
							|  |  |  |                                                           "  int b = 1;\n" | 
					
						
							|  |  |  |                                                           "  return (a)[b];\n" | 
					
						
							|  |  |  |                                                           "}" | 
					
						
							|  |  |  |                                                           )); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FunctionDefinitionAST *func = ast->asFunctionDefinition(); | 
					
						
							|  |  |  |     QVERIFY(func); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; | 
					
						
							|  |  |  |     QVERIFY(bodyStatements && bodyStatements->next && bodyStatements->next->next && bodyStatements->next->next->statement); | 
					
						
							|  |  |  |     ExpressionAST *expr = bodyStatements->next->next->statement->asReturnStatement()->expression; | 
					
						
							|  |  |  |     QVERIFY(expr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     CastExpressionAST *castExpr = expr->asCastExpression(); | 
					
						
							|  |  |  |     QVERIFY(!castExpr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     PostfixExpressionAST *postfixExpr = expr->asPostfixExpression(); | 
					
						
							|  |  |  |     QVERIFY(postfixExpr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         ExpressionAST *lhs = postfixExpr->base_expression; | 
					
						
							|  |  |  |         QVERIFY(lhs); | 
					
						
							|  |  |  |         NestedExpressionAST *nested_a = lhs->asNestedExpression(); | 
					
						
							|  |  |  |         QVERIFY(nested_a && nested_a->expression); | 
					
						
							|  |  |  |         SimpleNameAST *a = nested_a->expression->asSimpleName(); | 
					
						
							|  |  |  |         QVERIFY(a); | 
					
						
							|  |  |  |         QCOMPARE(QLatin1String(unit->identifier(a->identifier_token)->chars()), QLatin1String("a")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         QVERIFY(postfixExpr->postfix_expressions && !postfixExpr->postfix_expressions->next); | 
					
						
							|  |  |  |         ArrayAccessAST *rhs = postfixExpr->postfix_expressions->asArrayAccess(); | 
					
						
							|  |  |  |         QVERIFY(rhs && rhs->expression); | 
					
						
							|  |  |  |         SimpleNameAST *b = rhs->expression->asSimpleName(); | 
					
						
							|  |  |  |         QVERIFY(b); | 
					
						
							|  |  |  |         QCOMPARE(QLatin1String(unit->identifier(b->identifier_token)->chars()), QLatin1String("b")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::objc_msg_send_expression() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" | 
					
						
							|  |  |  |                                                           "int f() {\n" | 
					
						
							|  |  |  |                                                           "  NSObject *obj = [[[NSObject alloc] init] autorelease];\n" | 
					
						
							|  |  |  |                                                           "  return [obj description];\n" | 
					
						
							|  |  |  |                                                           "}" | 
					
						
							|  |  |  |                                                           )); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FunctionDefinitionAST *func = ast->asFunctionDefinition(); | 
					
						
							|  |  |  |     QVERIFY(func); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; | 
					
						
							|  |  |  |     QVERIFY(bodyStatements && bodyStatements->next && !bodyStatements->next->next && bodyStatements->next->statement); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {// check the NSObject declaration
 | 
					
						
							| 
									
										
										
										
											2009-10-19 17:47:49 +02:00
										 |  |  |         DeclarationStatementAST *firstStatement = bodyStatements->statement->asDeclarationStatement(); | 
					
						
							|  |  |  |         QVERIFY(firstStatement); | 
					
						
							|  |  |  |         DeclarationAST *objDecl = firstStatement->declaration; | 
					
						
							| 
									
										
										
										
											2009-10-19 14:49:51 +02:00
										 |  |  |         QVERIFY(objDecl); | 
					
						
							|  |  |  |         SimpleDeclarationAST *simpleDecl = objDecl->asSimpleDeclaration(); | 
					
						
							|  |  |  |         QVERIFY(simpleDecl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         {// check the type (NSObject)
 | 
					
						
							|  |  |  |             QVERIFY(simpleDecl->decl_specifier_seq && !simpleDecl->decl_specifier_seq->next); | 
					
						
							|  |  |  |             NamedTypeSpecifierAST *namedType = simpleDecl->decl_specifier_seq->asNamedTypeSpecifier(); | 
					
						
							|  |  |  |             QVERIFY(namedType && namedType->name); | 
					
						
							|  |  |  |             SimpleNameAST *typeName = namedType->name->asSimpleName(); | 
					
						
							|  |  |  |             QVERIFY(typeName); | 
					
						
							|  |  |  |             QCOMPARE(QLatin1String(unit->identifier(typeName->identifier_token)->chars()), QLatin1String("NSObject")); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         {// check the assignment
 | 
					
						
							|  |  |  |             QVERIFY(simpleDecl->declarators && !simpleDecl->declarators->next); | 
					
						
							|  |  |  |             DeclaratorAST *declarator = simpleDecl->declarators->declarator; | 
					
						
							|  |  |  |             QVERIFY(declarator); | 
					
						
							|  |  |  |             QVERIFY(!declarator->attributes); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QVERIFY(declarator->ptr_operators && !declarator->ptr_operators->next && declarator->ptr_operators->asPointer() && !declarator->ptr_operators->asPointer()->cv_qualifier_seq); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QVERIFY(declarator->core_declarator && declarator->core_declarator->asDeclaratorId()); | 
					
						
							|  |  |  |             NameAST *objNameId = declarator->core_declarator->asDeclaratorId()->name; | 
					
						
							|  |  |  |             QVERIFY(objNameId && objNameId->asSimpleName()); | 
					
						
							|  |  |  |             QCOMPARE(QLatin1String(unit->identifier(objNameId->asSimpleName()->identifier_token)->chars()), QLatin1String("obj")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             QVERIFY(!declarator->postfix_declarators); | 
					
						
							|  |  |  |             QVERIFY(!declarator->post_attributes); | 
					
						
							|  |  |  |             ExpressionAST *initializer = declarator->initializer; | 
					
						
							|  |  |  |             QVERIFY(initializer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ObjCMessageExpressionAST *expr1 = initializer->asObjCMessageExpression(); | 
					
						
							|  |  |  |             QVERIFY(expr1 && expr1->receiver_expression && expr1->selector && !expr1->argument_list); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ObjCMessageExpressionAST *expr2 = expr1->receiver_expression->asObjCMessageExpression(); | 
					
						
							|  |  |  |             QVERIFY(expr2 && expr2->receiver_expression && expr2->selector && !expr2->argument_list); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ObjCMessageExpressionAST *expr3 = expr2->receiver_expression->asObjCMessageExpression(); | 
					
						
							|  |  |  |             QVERIFY(expr3 && expr3->receiver_expression && expr3->selector && !expr3->argument_list); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     {// check the return statement
 | 
					
						
							|  |  |  |         ExpressionAST *expr = bodyStatements->next->statement->asReturnStatement()->expression; | 
					
						
							|  |  |  |         QVERIFY(expr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ObjCMessageExpressionAST *msgExpr = expr->asObjCMessageExpression(); | 
					
						
							|  |  |  |         QVERIFY(msgExpr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QVERIFY(msgExpr->receiver_expression); | 
					
						
							|  |  |  |         SimpleNameAST *receiver = msgExpr->receiver_expression->asSimpleName(); | 
					
						
							|  |  |  |         QVERIFY(receiver); | 
					
						
							|  |  |  |         QCOMPARE(QLatin1String(unit->identifier(receiver->identifier_token)->chars()), QLatin1String("obj")); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QVERIFY(msgExpr->argument_list == 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         QVERIFY(msgExpr->selector); | 
					
						
							|  |  |  |         ObjCSelectorWithoutArgumentsAST *sel = msgExpr->selector->asObjCSelectorWithoutArguments(); | 
					
						
							|  |  |  |         QVERIFY(sel); | 
					
						
							|  |  |  |         QCOMPARE(QLatin1String(unit->identifier(sel->name_token)->chars()), QLatin1String("description")); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void tst_AST::objc_msg_send_expression_without_selector() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // This test is to verify that no ObjCMessageExpressionAST element is created as the expression for the return statement.
 | 
					
						
							|  |  |  |     QSharedPointer<TranslationUnit> unit(parseDeclaration("\n" | 
					
						
							|  |  |  |                                                           "int f() {\n" | 
					
						
							|  |  |  |                                                           "  NSObject *obj = [[[NSObject alloc] init] autorelease];\n" | 
					
						
							|  |  |  |                                                           "  return [obj];\n" | 
					
						
							|  |  |  |                                                           "}", | 
					
						
							|  |  |  |                                                           true)); | 
					
						
							|  |  |  |     AST *ast = unit->ast(); | 
					
						
							|  |  |  |     QVERIFY(ast); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     FunctionDefinitionAST *func = ast->asFunctionDefinition(); | 
					
						
							|  |  |  |     QVERIFY(func); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     StatementListAST *bodyStatements = func->function_body->asCompoundStatement()->statements; | 
					
						
							|  |  |  |     QVERIFY(bodyStatements && bodyStatements->next); | 
					
						
							|  |  |  |     QVERIFY(bodyStatements->next->statement); | 
					
						
							|  |  |  |     QVERIFY(bodyStatements->next->statement->asReturnStatement()); | 
					
						
							|  |  |  |     QVERIFY(!bodyStatements->next->statement->asReturnStatement()->expression); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 11:35:38 +01:00
										 |  |  | QTEST_APPLESS_MAIN(tst_AST) | 
					
						
							|  |  |  | #include "tst_ast.moc"
 |