| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | /**************************************************************************
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							| 
									
										
										
										
											2010-03-05 11:25:49 +01:00
										 |  |  | ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-06-17 00:01:27 +10:00
										 |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Commercial Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Licensees holding valid Qt Commercial licenses may use this file in | 
					
						
							|  |  |  | ** accordance with the Qt Commercial License Agreement provided with the | 
					
						
							|  |  |  | ** Software or, alternatively, in accordance with the terms contained in | 
					
						
							|  |  |  | ** a written agreement between you and Nokia. | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** GNU Lesser General Public License Usage | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** Alternatively, this file may be used under the terms of the GNU Lesser | 
					
						
							|  |  |  | ** General Public License version 2.1 as published by the Free Software | 
					
						
							|  |  |  | ** Foundation and appearing in the file LICENSE.LGPL included in the | 
					
						
							|  |  |  | ** packaging of this file.  Please review the following information to | 
					
						
							|  |  |  | ** ensure the GNU Lesser General Public License version 2.1 requirements | 
					
						
							|  |  |  | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 14:17:16 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | ** If you are unsure which license is appropriate for your use, please | 
					
						
							| 
									
										
										
										
											2009-08-14 09:30:56 +02:00
										 |  |  | ** contact the sales department at http://qt.nokia.com/contact.
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | ** | 
					
						
							| 
									
										
										
										
											2009-02-25 09:15:00 +01:00
										 |  |  | **************************************************************************/ | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | // Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
					
						
							|  |  |  | // of this software and associated documentation files (the "Software"), to deal
 | 
					
						
							|  |  |  | // in the Software without restriction, including without limitation the rights
 | 
					
						
							|  |  |  | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
					
						
							|  |  |  | // copies of the Software, and to permit persons to whom the Software is
 | 
					
						
							|  |  |  | // furnished to do so, subject to the following conditions:
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // The above copyright notice and this permission notice shall be included in
 | 
					
						
							|  |  |  | // all copies or substantial portions of the Software.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
					
						
							|  |  |  | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
					
						
							|  |  |  | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
					
						
							|  |  |  | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
					
						
							|  |  |  | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
					
						
							|  |  |  | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					
						
							|  |  |  | // THE SOFTWARE.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "CheckDeclaration.h"
 | 
					
						
							|  |  |  | #include "Semantic.h"
 | 
					
						
							|  |  |  | #include "AST.h"
 | 
					
						
							|  |  |  | #include "TranslationUnit.h"
 | 
					
						
							|  |  |  | #include "Scope.h"
 | 
					
						
							|  |  |  | #include "Names.h"
 | 
					
						
							|  |  |  | #include "CoreTypes.h"
 | 
					
						
							|  |  |  | #include "Symbols.h"
 | 
					
						
							|  |  |  | #include "Control.h"
 | 
					
						
							| 
									
										
										
										
											2009-03-31 13:56:28 +02:00
										 |  |  | #include "Literals.h"
 | 
					
						
							| 
									
										
										
										
											2010-02-16 16:54:39 +01:00
										 |  |  | #include "QtContextKeywords.h"
 | 
					
						
							| 
									
										
										
										
											2009-12-08 11:34:22 +01:00
										 |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | #include <cassert>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 11:21:25 +02:00
										 |  |  | using namespace CPlusPlus; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | CheckDeclaration::CheckDeclaration(Semantic *semantic) | 
					
						
							|  |  |  |     : SemanticCheck(semantic), | 
					
						
							|  |  |  |       _declaration(0), | 
					
						
							|  |  |  |       _scope(0), | 
					
						
							|  |  |  |       _templateParameters(0), | 
					
						
							|  |  |  |       _checkAnonymousArguments(false) | 
					
						
							|  |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CheckDeclaration::~CheckDeclaration() | 
					
						
							|  |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CheckDeclaration::check(DeclarationAST *declaration, | 
					
						
							| 
									
										
										
										
											2009-08-26 11:41:20 +02:00
										 |  |  |                              Scope *scope, TemplateParameters *templateParameters) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							|  |  |  |     Scope *previousScope = switchScope(scope); | 
					
						
							| 
									
										
										
										
											2009-08-26 11:41:20 +02:00
										 |  |  |     TemplateParameters *previousTemplateParameters = switchTemplateParameters(templateParameters); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     DeclarationAST *previousDeclaration = switchDeclaration(declaration); | 
					
						
							|  |  |  |     accept(declaration); | 
					
						
							|  |  |  |     (void) switchDeclaration(previousDeclaration); | 
					
						
							|  |  |  |     (void) switchTemplateParameters(previousTemplateParameters); | 
					
						
							|  |  |  |     (void) switchScope(previousScope); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-30 16:52:20 +02:00
										 |  |  | void CheckDeclaration::check(CtorInitializerAST *ast, Scope *scope) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Scope *previousScope = switchScope(scope); | 
					
						
							|  |  |  |     accept(ast); | 
					
						
							|  |  |  |     (void) switchScope(previousScope); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | DeclarationAST *CheckDeclaration::switchDeclaration(DeclarationAST *declaration) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     DeclarationAST *previousDeclaration = _declaration; | 
					
						
							|  |  |  |     _declaration = declaration; | 
					
						
							|  |  |  |     return previousDeclaration; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Scope *CheckDeclaration::switchScope(Scope *scope) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Scope *previousScope = _scope; | 
					
						
							|  |  |  |     _scope = scope; | 
					
						
							|  |  |  |     return previousScope; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-26 11:41:20 +02:00
										 |  |  | TemplateParameters *CheckDeclaration::switchTemplateParameters(TemplateParameters *templateParameters) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-26 11:41:20 +02:00
										 |  |  |     TemplateParameters *previousTemplateParameters = _templateParameters; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _templateParameters = templateParameters; | 
					
						
							|  |  |  |     return previousTemplateParameters; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CheckDeclaration::checkFunctionArguments(Function *fun) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! _checkAnonymousArguments) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (_scope->isClassScope() && fun->isPublic()) { | 
					
						
							|  |  |  |         for (unsigned argc = 0; argc < fun->argumentCount(); ++argc) { | 
					
						
							|  |  |  |             Argument *arg = fun->argumentAt(argc)->asArgument(); | 
					
						
							|  |  |  |             assert(arg != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (! arg->name()) { | 
					
						
							|  |  |  |                 translationUnit()->warning(arg->sourceLocation(), | 
					
						
							|  |  |  |                                            "anonymous argument"); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-25 11:02:02 +02:00
										 |  |  | unsigned CheckDeclaration::locationOfDeclaratorId(DeclaratorAST *declarator) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (declarator && declarator->core_declarator) { | 
					
						
							|  |  |  |         if (DeclaratorIdAST *declaratorId = declarator->core_declarator->asDeclaratorId()) | 
					
						
							|  |  |  |             return declaratorId->firstToken(); | 
					
						
							|  |  |  |         else if (NestedDeclaratorAST *nested = declarator->core_declarator->asNestedDeclarator()) | 
					
						
							|  |  |  |             return locationOfDeclaratorId(nested->declarator); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | bool CheckDeclaration::visit(SimpleDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     FullySpecifiedType ty = semantic()->check(ast->decl_specifier_list, _scope); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     FullySpecifiedType qualTy = ty.qualifiedType(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 17:44:06 +01:00
										 |  |  |     if (_templateParameters && ty) { | 
					
						
							|  |  |  |         if (Class *klass = ty->asClassType()) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             klass->setTemplateParameters(_templateParameters); | 
					
						
							| 
									
										
										
										
											2010-03-19 11:08:58 +01:00
										 |  |  |             _templateParameters = 0; // consume the template parameters
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-19 11:08:58 +01:00
										 |  |  |     if (ast->decl_specifier_list && ! ast->declarator_list) { | 
					
						
							|  |  |  |         ElaboratedTypeSpecifierAST *elab_type_spec = ast->decl_specifier_list->value->asElaboratedTypeSpecifier(); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-19 11:08:58 +01:00
										 |  |  |         if (! elab_type_spec && ty.isFriend() && ast->decl_specifier_list->next && ! ast->decl_specifier_list->next->next) { | 
					
						
							|  |  |  |             // friend template class
 | 
					
						
							|  |  |  |             elab_type_spec = ast->decl_specifier_list->next->value->asElaboratedTypeSpecifier(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-19 11:08:58 +01:00
										 |  |  |         if (elab_type_spec) { | 
					
						
							|  |  |  |             unsigned sourceLocation = ast->decl_specifier_list->firstToken(); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |             const Name *name = semantic()->check(elab_type_spec->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-02-16 15:43:24 +01:00
										 |  |  |             ForwardClassDeclaration *symbol = | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |                     control()->newForwardClassDeclaration(sourceLocation, name); | 
					
						
							| 
									
										
										
										
											2009-02-16 15:43:24 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (_templateParameters) { | 
					
						
							|  |  |  |                 symbol->setTemplateParameters(_templateParameters); | 
					
						
							|  |  |  |                 _templateParameters = 0; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-05-10 09:47:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-23 12:04:44 +01:00
										 |  |  |             if (ty.isDeprecated()) | 
					
						
							|  |  |  |                 symbol->setDeprecated(true); | 
					
						
							| 
									
										
										
										
											2010-05-26 13:56:25 +02:00
										 |  |  |             if (ty.isUnavailable()) | 
					
						
							|  |  |  |                 symbol->setUnavailable(true); | 
					
						
							| 
									
										
										
										
											2009-02-16 15:43:24 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 09:47:11 +02:00
										 |  |  |             if (ty.isFriend()) | 
					
						
							|  |  |  |                 symbol->setStorage(Symbol::Friend); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-16 15:43:24 +01:00
										 |  |  |             _scope->enterSymbol(symbol); | 
					
						
							|  |  |  |             return false; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-25 11:50:17 +01:00
										 |  |  |     const bool isQ_SLOT   = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; | 
					
						
							|  |  |  |     const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; | 
					
						
							| 
									
										
										
										
											2010-02-04 12:03:34 +01:00
										 |  |  |     const bool isQ_INVOKABLE = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_INVOKABLE; | 
					
						
							| 
									
										
										
										
											2009-03-25 11:50:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     List<Declaration *> **decl_it = &ast->symbols; | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *name = 0; | 
					
						
							| 
									
										
										
										
											2009-11-10 12:34:29 +01:00
										 |  |  |         FullySpecifiedType declTy = semantic()->check(it->value, qualTy, | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |                                                       _scope, &name); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 12:34:29 +01:00
										 |  |  |         unsigned location = locationOfDeclaratorId(it->value); | 
					
						
							| 
									
										
										
										
											2009-06-25 11:02:02 +02:00
										 |  |  |         if (! location) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:34:29 +01:00
										 |  |  |             if (it->value) | 
					
						
							|  |  |  |                 location = it->value->firstToken(); | 
					
						
							| 
									
										
										
										
											2009-06-25 11:02:02 +02:00
										 |  |  |             else | 
					
						
							|  |  |  |                 location = ast->firstToken(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 17:44:06 +01:00
										 |  |  |         Function *fun = 0; | 
					
						
							|  |  |  |         if (declTy && 0 != (fun = declTy->asFunctionType())) { | 
					
						
							| 
									
										
										
										
											2010-05-10 13:45:27 +02:00
										 |  |  |             fun->setSourceLocation(location, translationUnit()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             fun->setScope(_scope); | 
					
						
							|  |  |  |             fun->setName(name); | 
					
						
							|  |  |  |             fun->setMethodKey(semantic()->currentMethodKey()); | 
					
						
							| 
									
										
										
										
											2009-10-27 14:59:27 +01:00
										 |  |  |             fun->setVirtual(ty.isVirtual()); | 
					
						
							| 
									
										
										
										
											2010-03-23 12:04:44 +01:00
										 |  |  |             if (ty.isDeprecated()) | 
					
						
							|  |  |  |                 fun->setDeprecated(true); | 
					
						
							| 
									
										
										
										
											2010-05-26 13:56:25 +02:00
										 |  |  |             if (ty.isUnavailable()) | 
					
						
							|  |  |  |                 fun->setUnavailable(true); | 
					
						
							| 
									
										
										
										
											2009-03-25 11:50:17 +01:00
										 |  |  |             if (isQ_SIGNAL) | 
					
						
							|  |  |  |                 fun->setMethodKey(Function::SignalMethod); | 
					
						
							|  |  |  |             else if (isQ_SLOT) | 
					
						
							|  |  |  |                 fun->setMethodKey(Function::SlotMethod); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  |             else if (isQ_INVOKABLE) | 
					
						
							| 
									
										
										
										
											2010-02-06 14:32:25 +01:00
										 |  |  |                 fun->setMethodKey(Function::InvokableMethod); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             fun->setVisibility(semantic()->currentVisibility()); | 
					
						
							|  |  |  |         } else if (semantic()->currentMethodKey() != Function::NormalMethod) { | 
					
						
							|  |  |  |             translationUnit()->warning(ast->firstToken(), | 
					
						
							|  |  |  |                                        "expected a function declaration"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         Declaration *symbol = control()->newDeclaration(location, name); | 
					
						
							| 
									
										
										
										
											2009-03-31 13:56:28 +02:00
										 |  |  |         symbol->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |         symbol->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-03-31 13:56:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         symbol->setType(declTy); | 
					
						
							| 
									
										
										
										
											2010-03-23 12:04:44 +01:00
										 |  |  |         if (declTy.isDeprecated()) | 
					
						
							|  |  |  |             symbol->setDeprecated(true); | 
					
						
							| 
									
										
										
										
											2010-05-26 13:56:25 +02:00
										 |  |  |         if (declTy.isUnavailable()) | 
					
						
							|  |  |  |             symbol->setUnavailable(true); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-19 11:08:58 +01:00
										 |  |  |         if (_templateParameters && it == ast->declarator_list) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |             symbol->setTemplateParameters(_templateParameters); | 
					
						
							| 
									
										
										
										
											2010-03-19 11:08:58 +01:00
										 |  |  |             _templateParameters = 0; // consume the template parameters
 | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         symbol->setVisibility(semantic()->currentVisibility()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (ty.isFriend()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Friend); | 
					
						
							| 
									
										
										
										
											2010-03-24 15:02:46 +01:00
										 |  |  |         else if (ty.isAuto()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Auto); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         else if (ty.isRegister()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Register); | 
					
						
							|  |  |  |         else if (ty.isStatic()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Static); | 
					
						
							|  |  |  |         else if (ty.isExtern()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Extern); | 
					
						
							|  |  |  |         else if (ty.isMutable()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Mutable); | 
					
						
							|  |  |  |         else if (ty.isTypedef()) | 
					
						
							|  |  |  |             symbol->setStorage(Symbol::Typedef); | 
					
						
							| 
									
										
										
										
											2010-03-24 15:02:46 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (ty.isDeprecated()) | 
					
						
							| 
									
										
										
										
											2010-03-23 12:04:44 +01:00
										 |  |  |             symbol->setDeprecated(true); | 
					
						
							| 
									
										
										
										
											2010-05-26 13:56:25 +02:00
										 |  |  |         if (ty.isUnavailable()) | 
					
						
							|  |  |  |             symbol->setUnavailable(true); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 12:34:29 +01:00
										 |  |  |         if (it->value && it->value->initializer) { | 
					
						
							|  |  |  |             FullySpecifiedType initTy = semantic()->check(it->value->initializer, _scope); | 
					
						
							| 
									
										
										
										
											2009-06-04 13:26:11 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |         *decl_it = new (translationUnit()->memoryPool()) List<Declaration *>(); | 
					
						
							|  |  |  |         (*decl_it)->value = symbol; | 
					
						
							|  |  |  |         decl_it = &(*decl_it)->next; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         _scope->enterSymbol(symbol); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(EmptyDeclarationAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(AccessDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int accessSpecifier = tokenKind(ast->access_specifier_token); | 
					
						
							|  |  |  |     int visibility = semantic()->visibilityForAccessSpecifier(accessSpecifier); | 
					
						
							|  |  |  |     semantic()->switchVisibility(visibility); | 
					
						
							|  |  |  |     if (ast->slots_token) | 
					
						
							|  |  |  |         semantic()->switchMethodKey(Function::SlotMethod); | 
					
						
							| 
									
										
										
										
											2009-07-03 09:11:52 +02:00
										 |  |  |     else if (accessSpecifier == T_Q_SIGNALS) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         semantic()->switchMethodKey(Function::SignalMethod); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         semantic()->switchMethodKey(Function::NormalMethod); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(AsmDefinitionAST *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-28 16:06:26 +01:00
										 |  |  | bool CheckDeclaration::visit(ExceptionDeclarationAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); | 
					
						
							| 
									
										
										
										
											2009-10-28 16:06:26 +01:00
										 |  |  |     FullySpecifiedType qualTy = ty.qualifiedType(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = 0; | 
					
						
							| 
									
										
										
										
											2009-10-28 16:06:26 +01:00
										 |  |  |     FullySpecifiedType declTy = semantic()->check(ast->declarator, qualTy, | 
					
						
							|  |  |  |                                                   _scope, &name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned location = locationOfDeclaratorId(ast->declarator); | 
					
						
							|  |  |  |     if (! location) { | 
					
						
							|  |  |  |         if (ast->declarator) | 
					
						
							|  |  |  |             location = ast->declarator->firstToken(); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             location = ast->firstToken(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Declaration *symbol = control()->newDeclaration(location, name); | 
					
						
							|  |  |  |     symbol->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     symbol->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-10-28 16:06:26 +01:00
										 |  |  |     symbol->setType(declTy); | 
					
						
							|  |  |  |     _scope->enterSymbol(symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(FunctionDefinitionAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     FullySpecifiedType ty = semantic()->check(ast->decl_specifier_list, _scope); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     FullySpecifiedType qualTy = ty.qualifiedType(); | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = 0; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     FullySpecifiedType funTy = semantic()->check(ast->declarator, qualTy, | 
					
						
							|  |  |  |                                                  _scope, &name); | 
					
						
							| 
									
										
										
										
											2009-02-09 17:44:06 +01:00
										 |  |  |     if (! (funTy && funTy->isFunctionType())) { | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |         translationUnit()->error(ast->firstToken(), | 
					
						
							|  |  |  |                                  "expected a function prototype"); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 17:44:06 +01:00
										 |  |  |     Function *fun = funTy->asFunctionType(); | 
					
						
							| 
									
										
										
										
											2009-10-27 14:59:27 +01:00
										 |  |  |     fun->setVirtual(ty.isVirtual()); | 
					
						
							| 
									
										
										
										
											2010-03-23 12:04:44 +01:00
										 |  |  |     if (ty.isDeprecated()) | 
					
						
							|  |  |  |         fun->setDeprecated(true); | 
					
						
							| 
									
										
										
										
											2010-05-26 13:56:25 +02:00
										 |  |  |     if (ty.isUnavailable()) | 
					
						
							|  |  |  |         fun->setUnavailable(true); | 
					
						
							| 
									
										
										
										
											2009-03-31 13:56:28 +02:00
										 |  |  |     fun->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     fun->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |     if (ast->declarator) | 
					
						
							| 
									
										
										
										
											2010-05-10 13:45:27 +02:00
										 |  |  |         fun->setSourceLocation(ast->declarator->firstToken(), translationUnit()); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     fun->setName(name); | 
					
						
							|  |  |  |     fun->setTemplateParameters(_templateParameters); | 
					
						
							|  |  |  |     fun->setVisibility(semantic()->currentVisibility()); | 
					
						
							|  |  |  |     fun->setMethodKey(semantic()->currentMethodKey()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-03-25 11:50:17 +01:00
										 |  |  |     const bool isQ_SLOT   = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SLOT; | 
					
						
							|  |  |  |     const bool isQ_SIGNAL = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_SIGNAL; | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  |     const bool isQ_INVOKABLE = ast->qt_invokable_token && tokenKind(ast->qt_invokable_token) == T_Q_INVOKABLE; | 
					
						
							| 
									
										
										
										
											2009-03-25 11:50:17 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (isQ_SIGNAL) | 
					
						
							|  |  |  |         fun->setMethodKey(Function::SignalMethod); | 
					
						
							|  |  |  |     else if (isQ_SLOT) | 
					
						
							|  |  |  |         fun->setMethodKey(Function::SlotMethod); | 
					
						
							| 
									
										
										
										
											2010-01-19 15:26:08 +10:00
										 |  |  |     else if (isQ_INVOKABLE) | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  |         fun->setMethodKey(Function::InvokableMethod); | 
					
						
							| 
									
										
										
										
											2009-03-25 11:50:17 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     checkFunctionArguments(fun); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = fun; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _scope->enterSymbol(fun); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-30 16:52:20 +02:00
										 |  |  |     if (! semantic()->skipFunctionBodies()) | 
					
						
							|  |  |  |         semantic()->checkFunctionDefinition(ast); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-06 12:53:05 +02:00
										 |  |  | bool CheckDeclaration::visit(MemInitializerAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) semantic()->check(ast->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-11-13 12:36:51 +01:00
										 |  |  |     for (ExpressionListAST *it = ast->expression_list; it; it = it->next) { | 
					
						
							|  |  |  |         FullySpecifiedType ty = semantic()->check(it->value, _scope); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-10-06 12:53:05 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | bool CheckDeclaration::visit(LinkageBodyAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (DeclarationListAST *decl = ast->declaration_list; decl; decl = decl->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 11:23:35 +01:00
										 |  |  |        semantic()->check(decl->value, _scope); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(LinkageSpecificationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-17 16:08:01 +02:00
										 |  |  |     semantic()->check(ast->declaration, _scope); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(NamespaceAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 14:38:42 +01:00
										 |  |  |     const Name *namespaceName = 0; | 
					
						
							|  |  |  |     if (const Identifier *id = identifier(ast->identifier_token)) | 
					
						
							|  |  |  |         namespaceName = control()->nameId(id); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ast->identifier_token) | 
					
						
							|  |  |  |         sourceLocation = ast->identifier_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Namespace *ns = control()->newNamespace(sourceLocation, namespaceName); | 
					
						
							| 
									
										
										
										
											2009-03-31 13:56:28 +02:00
										 |  |  |     ns->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     ns->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = ns; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _scope->enterSymbol(ns); | 
					
						
							|  |  |  |     semantic()->check(ast->linkage_body, ns->members()); // ### we'll do the merge later.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:18:11 +02:00
										 |  |  | bool CheckDeclaration::visit(NamespaceAliasDefinitionAST *ast) | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-05 10:18:11 +02:00
										 |  |  |     const Name *name = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (const Identifier *id = identifier(ast->namespace_name_token)) | 
					
						
							|  |  |  |         name = control()->nameId(id); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ast->namespace_name_token) | 
					
						
							|  |  |  |         sourceLocation = ast->namespace_name_token; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     const Name *namespaceName = semantic()->check(ast->name, _scope); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     NamespaceAlias *namespaceAlias = control()->newNamespaceAlias(sourceLocation, name); | 
					
						
							|  |  |  |     namespaceAlias->setNamespaceName(namespaceName); | 
					
						
							|  |  |  |     namespaceAlias->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     namespaceAlias->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:18:11 +02:00
										 |  |  |     //ast->symbol = namespaceAlias;
 | 
					
						
							|  |  |  |     _scope->enterSymbol(namespaceAlias); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(ParameterDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-25 11:02:02 +02:00
										 |  |  |     unsigned sourceLocation = locationOfDeclaratorId(ast->declarator); | 
					
						
							|  |  |  |     if (! sourceLocation) { | 
					
						
							|  |  |  |         if (ast->declarator) | 
					
						
							|  |  |  |             sourceLocation = ast->declarator->firstToken(); | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |             sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *argName = 0; | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     FullySpecifiedType ty = semantic()->check(ast->type_specifier_list, _scope); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     FullySpecifiedType argTy = semantic()->check(ast->declarator, ty.qualifiedType(), | 
					
						
							|  |  |  |                                                  _scope, &argName); | 
					
						
							|  |  |  |     FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |     Argument *arg = control()->newArgument(sourceLocation, argName); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = arg; | 
					
						
							| 
									
										
										
										
											2009-12-08 11:34:22 +01:00
										 |  |  |     if (ast->expression) { | 
					
						
							|  |  |  |         unsigned startOfExpression = ast->expression->firstToken(); | 
					
						
							|  |  |  |         unsigned endOfExpression = ast->expression->lastToken(); | 
					
						
							|  |  |  |         std::string buffer; | 
					
						
							|  |  |  |         for (unsigned index = startOfExpression; index != endOfExpression; ++index) { | 
					
						
							|  |  |  |             const Token &tk = tokenAt(index); | 
					
						
							|  |  |  |             if (tk.whitespace() || tk.newline()) | 
					
						
							|  |  |  |                 buffer += ' '; | 
					
						
							|  |  |  |             buffer += tk.spell(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         const StringLiteral *initializer = control()->findOrInsertStringLiteral(buffer.c_str(), buffer.size()); | 
					
						
							|  |  |  |         arg->setInitializer(initializer); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     arg->setType(argTy); | 
					
						
							|  |  |  |     _scope->enterSymbol(arg); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(TemplateDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-08-26 11:41:20 +02:00
										 |  |  |     Scope *scope = new Scope(_scope->owner()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (DeclarationListAST *param = ast->template_parameter_list; param; param = param->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 11:23:35 +01:00
										 |  |  |        semantic()->check(param->value, scope); | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-26 11:41:20 +02:00
										 |  |  |     semantic()->check(ast->declaration, _scope, | 
					
						
							|  |  |  |                       new TemplateParameters(_templateParameters, scope)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(TypenameTypeParameterAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |     unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  |     if (ast->name) | 
					
						
							|  |  |  |         sourceLocation = ast->name->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = semantic()->check(ast->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-12-08 12:04:57 +01:00
										 |  |  |     TypenameArgument *arg = control()->newTypenameArgument(sourceLocation, name); | 
					
						
							|  |  |  |     FullySpecifiedType ty = semantic()->check(ast->type_id, _scope); | 
					
						
							|  |  |  |     arg->setType(ty); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = arg; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _scope->enterSymbol(arg); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(TemplateTypeParameterAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  |     unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  |     if (ast->name) | 
					
						
							|  |  |  |         sourceLocation = ast->name->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = semantic()->check(ast->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-12-08 12:04:57 +01:00
										 |  |  |     TypenameArgument *arg = control()->newTypenameArgument(sourceLocation, name); | 
					
						
							|  |  |  |     FullySpecifiedType ty = semantic()->check(ast->type_id, _scope); | 
					
						
							|  |  |  |     arg->setType(ty); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = arg; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _scope->enterSymbol(arg); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(UsingAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = semantic()->check(ast->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  |     if (ast->name) | 
					
						
							|  |  |  |         sourceLocation = ast->name->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UsingDeclaration *u = control()->newUsingDeclaration(sourceLocation, name); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = u; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _scope->enterSymbol(u); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(UsingDirectiveAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *name = semantic()->check(ast->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-03-03 13:46:37 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  |     if (ast->name) | 
					
						
							|  |  |  |         sourceLocation = ast->name->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UsingNamespaceDirective *u = control()->newUsingNamespaceDirective(sourceLocation, name); | 
					
						
							| 
									
										
										
										
											2009-02-09 12:19:17 +01:00
										 |  |  |     ast->symbol = u; | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     _scope->enterSymbol(u); | 
					
						
							| 
									
										
										
										
											2009-02-19 13:52:05 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (! (_scope->isBlockScope() || _scope->isNamespaceScope())) | 
					
						
							|  |  |  |         translationUnit()->error(ast->firstToken(), | 
					
						
							|  |  |  |                                  "using-directive not within namespace or block scope"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-02 12:01:29 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 17:14:08 +02:00
										 |  |  | bool CheckDeclaration::visit(ObjCProtocolForwardDeclarationAST *ast) | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     const unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     List<ObjCForwardProtocolDeclaration *> **symbolIter = &ast->symbols; | 
					
						
							| 
									
										
										
										
											2010-02-06 11:05:43 +01:00
										 |  |  |     for (NameListAST *it = ast->identifier_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         unsigned declarationLocation; | 
					
						
							| 
									
										
										
										
											2009-11-10 12:39:29 +01:00
										 |  |  |         if (it->value) | 
					
						
							|  |  |  |             declarationLocation = it->value->firstToken(); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         else | 
					
						
							|  |  |  |             declarationLocation = sourceLocation; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *protocolName = semantic()->check(it->value, _scope); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         ObjCForwardProtocolDeclaration *fwdProtocol = control()->newObjCForwardProtocolDeclaration(sourceLocation, protocolName); | 
					
						
							|  |  |  |         fwdProtocol->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |         fwdProtocol->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         _scope->enterSymbol(fwdProtocol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         *symbolIter = new (translationUnit()->memoryPool()) List<ObjCForwardProtocolDeclaration *>(); | 
					
						
							|  |  |  |         (*symbolIter)->value = fwdProtocol; | 
					
						
							|  |  |  |         symbolIter = &(*symbolIter)->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 17:14:08 +02:00
										 |  |  | bool CheckDeclaration::visit(ObjCProtocolDeclarationAST *ast) | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned sourceLocation; | 
					
						
							|  |  |  |     if (ast->name) | 
					
						
							|  |  |  |         sourceLocation = ast->name->firstToken(); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *protocolName = semantic()->check(ast->name, _scope); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |     ObjCProtocol *protocol = control()->newObjCProtocol(sourceLocation, protocolName); | 
					
						
							|  |  |  |     protocol->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     protocol->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |     if (ast->protocol_refs && ast->protocol_refs->identifier_list) { | 
					
						
							| 
									
										
										
										
											2010-02-06 11:05:43 +01:00
										 |  |  |         for (NameListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:39:29 +01:00
										 |  |  |             NameAST* name = iter->value; | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |             const Name *protocolName = semantic()->check(name, _scope); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |             ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName); | 
					
						
							|  |  |  |             protocol->addProtocol(baseProtocol); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Public); | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (DeclarationListAST *it = ast->member_declaration_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 11:23:35 +01:00
										 |  |  |         semantic()->check(it->value, protocol->members()); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     (void) semantic()->switchObjCVisibility(previousObjCVisibility); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ast->symbol = protocol; | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |     _scope->enterSymbol(protocol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 17:14:08 +02:00
										 |  |  | bool CheckDeclaration::visit(ObjCClassForwardDeclarationAST *ast) | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     const unsigned sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     List<ObjCForwardClassDeclaration *> **symbolIter = &ast->symbols; | 
					
						
							| 
									
										
										
										
											2010-02-06 11:05:43 +01:00
										 |  |  |     for (NameListAST *it = ast->identifier_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         unsigned declarationLocation; | 
					
						
							| 
									
										
										
										
											2009-11-10 12:39:29 +01:00
										 |  |  |         if (it->value) | 
					
						
							|  |  |  |             declarationLocation = it->value->firstToken(); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         else | 
					
						
							|  |  |  |             declarationLocation = sourceLocation; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *className = semantic()->check(it->value, _scope); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         ObjCForwardClassDeclaration *fwdClass = control()->newObjCForwardClassDeclaration(sourceLocation, className); | 
					
						
							|  |  |  |         fwdClass->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |         fwdClass->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         _scope->enterSymbol(fwdClass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         *symbolIter = new (translationUnit()->memoryPool()) List<ObjCForwardClassDeclaration *>(); | 
					
						
							|  |  |  |         (*symbolIter)->value = fwdClass; | 
					
						
							|  |  |  |         symbolIter = &(*symbolIter)->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 17:14:08 +02:00
										 |  |  | bool CheckDeclaration::visit(ObjCClassDeclarationAST *ast) | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     unsigned sourceLocation; | 
					
						
							|  |  |  |     if (ast->class_name) | 
					
						
							|  |  |  |         sourceLocation = ast->class_name->firstToken(); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         sourceLocation = ast->firstToken(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *className = semantic()->check(ast->class_name, _scope); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |     ObjCClass *klass = control()->newObjCClass(sourceLocation, className); | 
					
						
							|  |  |  |     klass->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     klass->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |     ast->symbol = klass; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 18:30:18 +02:00
										 |  |  |     klass->setInterface(ast->interface_token != 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ast->category_name) { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *categoryName = semantic()->check(ast->category_name, _scope); | 
					
						
							| 
									
										
										
										
											2009-08-05 18:30:18 +02:00
										 |  |  |         klass->setCategoryName(categoryName); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |     if (ast->superclass) { | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |         const Name *superClassName = semantic()->check(ast->superclass, _scope); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |         ObjCBaseClass *superKlass = control()->newObjCBaseClass(ast->superclass->firstToken(), superClassName); | 
					
						
							|  |  |  |         klass->setBaseClass(superKlass); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ast->protocol_refs && ast->protocol_refs->identifier_list) { | 
					
						
							| 
									
										
										
										
											2010-02-06 11:05:43 +01:00
										 |  |  |         for (NameListAST *iter = ast->protocol_refs->identifier_list; iter; iter = iter->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:39:29 +01:00
										 |  |  |             NameAST* name = iter->value; | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |             const Name *protocolName = semantic()->check(name, _scope); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |             ObjCBaseProtocol *baseProtocol = control()->newObjCBaseProtocol(name->firstToken(), protocolName); | 
					
						
							|  |  |  |             klass->addProtocol(baseProtocol); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |     _scope->enterSymbol(klass); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int previousObjCVisibility = semantic()->switchObjCVisibility(Function::Protected); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ast->inst_vars_decl) { | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |         for (DeclarationListAST *it = ast->inst_vars_decl->instance_variable_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 11:23:35 +01:00
										 |  |  |             semantic()->check(it->value, klass->members()); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 17:14:08 +02:00
										 |  |  |     (void) semantic()->switchObjCVisibility(Function::Public); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (DeclarationListAST *it = ast->member_declaration_list; it; it = it->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 11:23:35 +01:00
										 |  |  |         semantic()->check(it->value, klass->members()); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     (void) semantic()->switchObjCVisibility(previousObjCVisibility); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(ObjCMethodDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  |     ObjCMethodPrototypeAST *methodProto = ast->method_prototype; | 
					
						
							|  |  |  |     if (!methodProto) | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     ObjCSelectorAST *selector = methodProto->selector; | 
					
						
							|  |  |  |     if (!selector) | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  |     FullySpecifiedType ty = semantic()->check(methodProto, _scope); | 
					
						
							| 
									
										
										
										
											2009-12-29 18:26:01 +01:00
										 |  |  |     ObjCMethod *methodTy = ty.type()->asObjCMethodType(); | 
					
						
							|  |  |  |     if (!methodTy) | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-08-05 18:30:18 +02:00
										 |  |  |     Symbol *symbol; | 
					
						
							| 
									
										
										
										
											2009-09-21 18:26:37 +02:00
										 |  |  |     if (ast->function_body) { | 
					
						
							| 
									
										
										
										
											2009-12-29 18:26:01 +01:00
										 |  |  |         symbol = methodTy; | 
					
						
							| 
									
										
										
										
											2009-09-21 18:26:37 +02:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  |         Declaration *decl = control()->newDeclaration(selector->firstToken(), methodTy->name()); | 
					
						
							| 
									
										
										
										
											2009-12-29 18:26:01 +01:00
										 |  |  |         decl->setType(methodTy); | 
					
						
							| 
									
										
										
										
											2009-09-21 18:26:37 +02:00
										 |  |  |         symbol = decl; | 
					
						
							| 
									
										
										
										
											2009-12-29 18:26:01 +01:00
										 |  |  |         symbol->setStorage(methodTy->storage()); | 
					
						
							| 
									
										
										
										
											2009-08-05 18:30:18 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-02-10 22:45:28 +01:00
										 |  |  |     symbol->setStartOffset(tokenAt(ast->firstToken()).offset); | 
					
						
							| 
									
										
										
										
											2010-05-28 14:51:43 +02:00
										 |  |  |     symbol->setEndOffset(tokenAt(ast->lastToken() - 1).end()); | 
					
						
							| 
									
										
										
										
											2010-02-08 09:34:51 +01:00
										 |  |  |     symbol->setVisibility(semantic()->currentObjCVisibility()); | 
					
						
							| 
									
										
										
										
											2010-03-23 12:04:44 +01:00
										 |  |  |     if (ty.isDeprecated()) | 
					
						
							|  |  |  |         symbol->setDeprecated(true); | 
					
						
							| 
									
										
										
										
											2010-05-26 13:56:25 +02:00
										 |  |  |     if (ty.isUnavailable()) | 
					
						
							|  |  |  |         symbol->setUnavailable(true); | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _scope->enterSymbol(symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-06-18 09:08:00 +02:00
										 |  |  |     if (ast->function_body && !semantic()->skipFunctionBodies()) { | 
					
						
							|  |  |  |         semantic()->check(ast->function_body, methodTy->members()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-31 16:03:48 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-07-28 16:34:15 +02:00
										 |  |  | bool CheckDeclaration::visit(ObjCVisibilityDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int accessSpecifier = tokenKind(ast->visibility_token); | 
					
						
							|  |  |  |     int visibility = semantic()->visibilityForObjCAccessSpecifier(accessSpecifier); | 
					
						
							|  |  |  |     semantic()->switchObjCVisibility(visibility); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  | bool CheckDeclaration::checkPropertyAttribute(ObjCPropertyAttributeAST *attrAst, | 
					
						
							|  |  |  |                                               int &flags, | 
					
						
							|  |  |  |                                               int attr) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (flags & attr) { | 
					
						
							|  |  |  |         translationUnit()->warning(attrAst->attribute_identifier_token, | 
					
						
							|  |  |  |                                    "duplicate property attribute \"%s\"", | 
					
						
							|  |  |  |                                    spell(attrAst->attribute_identifier_token)); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         flags |= attr; | 
					
						
							|  |  |  |         return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(ObjCPropertyDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |     semantic()->check(ast->simple_declaration, _scope); | 
					
						
							|  |  |  |     SimpleDeclarationAST *simpleDecl = ast->simple_declaration->asSimpleDeclaration(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!simpleDecl) { | 
					
						
							|  |  |  |         translationUnit()->warning(ast->simple_declaration->firstToken(), | 
					
						
							|  |  |  |                                    "invalid type for property declaration"); | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     int propAttrs = ObjCPropertyDeclaration::None; | 
					
						
							| 
									
										
										
										
											2009-12-01 12:46:15 +01:00
										 |  |  |     const Name *getterName = 0, *setterName = 0; | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-10 16:47:16 +01:00
										 |  |  |     for (ObjCPropertyAttributeListAST *iter= ast->property_attribute_list; iter; iter = iter->next) { | 
					
						
							| 
									
										
										
										
											2009-11-10 12:47:08 +01:00
										 |  |  |         ObjCPropertyAttributeAST *attrAst = iter->value; | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |         if (!attrAst) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-12-01 11:33:13 +01:00
										 |  |  |         const Identifier *attrId = identifier(attrAst->attribute_identifier_token); | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         if (attrId == control()->objcGetterId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Getter)) { | 
					
						
							|  |  |  |                 getterName = semantic()->check(attrAst->method_selector, _scope); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcSetterId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             if (checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Setter)) { | 
					
						
							|  |  |  |                 setterName = semantic()->check(attrAst->method_selector, _scope); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcReadwriteId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadWrite); | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcReadonlyId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::ReadOnly); | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcAssignId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Assign); | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcRetainId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Retain); | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcCopyId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::Copy); | 
					
						
							| 
									
										
										
										
											2009-10-20 12:47:54 +02:00
										 |  |  |         } else if (attrId == control()->objcNonatomicId()) { | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             checkPropertyAttribute(attrAst, propAttrs, ObjCPropertyDeclaration::NonAtomic); | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |     if (propAttrs & ObjCPropertyDeclaration::ReadOnly && | 
					
						
							|  |  |  |         propAttrs & ObjCPropertyDeclaration::ReadWrite) | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |         // Should this be an error instead of only a warning?
 | 
					
						
							|  |  |  |         translationUnit()->warning(ast->property_token, | 
					
						
							|  |  |  |                                    "property can have at most one attribute \"readonly\" or \"readwrite\" specified"); | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |     int setterSemAttrs = propAttrs & ObjCPropertyDeclaration::SetterSemanticsMask; | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |     if (setterSemAttrs | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |             && setterSemAttrs != ObjCPropertyDeclaration::Assign | 
					
						
							|  |  |  |             && setterSemAttrs != ObjCPropertyDeclaration::Retain | 
					
						
							|  |  |  |             && setterSemAttrs != ObjCPropertyDeclaration::Copy) { | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |         // Should this be an error instead of only a warning?
 | 
					
						
							|  |  |  |         translationUnit()->warning(ast->property_token, | 
					
						
							|  |  |  |                                    "property can have at most one attribute \"assign\", \"retain\", or \"copy\" specified"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-11 09:32:05 +01:00
										 |  |  |     List<ObjCPropertyDeclaration *> **lastSymbols = &ast->symbols; | 
					
						
							|  |  |  |     for (List<Declaration*> *iter = simpleDecl->symbols; iter; iter = iter->next) { | 
					
						
							|  |  |  |         ObjCPropertyDeclaration *propDecl = control()->newObjCPropertyDeclaration(ast->firstToken(), | 
					
						
							|  |  |  |                                                                                   iter->value->name()); | 
					
						
							|  |  |  |         propDecl->setType(iter->value->type()); | 
					
						
							|  |  |  |         propDecl->setAttributes(propAttrs); | 
					
						
							|  |  |  |         propDecl->setGetterName(getterName); | 
					
						
							|  |  |  |         propDecl->setSetterName(setterName); | 
					
						
							|  |  |  |         _scope->enterSymbol(propDecl); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         *lastSymbols = new (translationUnit()->memoryPool()) List<ObjCPropertyDeclaration *>(); | 
					
						
							|  |  |  |         (*lastSymbols)->value = propDecl; | 
					
						
							|  |  |  |         lastSymbols = &(*lastSymbols)->next; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-05 18:02:01 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-06 14:32:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(QtEnumDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  |     checkQEnumsQFlagsNames(ast->enumerator_list, "Q_ENUMS"); | 
					
						
							| 
									
										
										
										
											2010-02-06 14:32:25 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(QtFlagsDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  |     checkQEnumsQFlagsNames(ast->flag_enums_list, "Q_FLAGS"); | 
					
						
							| 
									
										
										
										
											2010-02-06 14:32:25 +01:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-17 16:25:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool CheckDeclaration::visit(QtPropertyDeclarationAST *ast) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (ast->type_id) | 
					
						
							|  |  |  |         semantic()->check(ast->type_id, _scope); | 
					
						
							|  |  |  |     if (ast->property_name) | 
					
						
							|  |  |  |         semantic()->check(ast->property_name, _scope); | 
					
						
							|  |  |  |     for (QtPropertyDeclarationItemListAST *iter = ast->property_declaration_items; | 
					
						
							|  |  |  |          iter; iter = iter->next) { | 
					
						
							|  |  |  |         if (iter->value) | 
					
						
							|  |  |  |             semantic()->check(iter->value->expression, _scope); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 13:41:54 +02:00
										 |  |  | static bool checkEnumName(const Name *name) | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-07-12 13:41:54 +02:00
										 |  |  |     if (! name) | 
					
						
							|  |  |  |         return false; | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 13:41:54 +02:00
										 |  |  |     else if (name->asNameId() != 0) | 
					
						
							|  |  |  |         return true; | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 13:41:54 +02:00
										 |  |  |     else if (const QualifiedNameId *q = name->asQualifiedNameId()) { | 
					
						
							|  |  |  |         if (! q->base()) | 
					
						
							|  |  |  |             return false; // global qualified name
 | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-07-12 13:41:54 +02:00
										 |  |  |         if (checkEnumName(q->base()) && checkEnumName(q->name())) | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CheckDeclaration::checkQEnumsQFlagsNames(NameListAST *nameListAst, const char *declName) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (NameListAST *iter = nameListAst; iter; iter = iter->next) { | 
					
						
							|  |  |  |         if (const Name *name = semantic()->check(iter->value, _scope)) { | 
					
						
							|  |  |  |             if (! checkEnumName(name)) | 
					
						
							|  |  |  |                 translationUnit()->error(iter->firstToken(), "invalid name in %s", declName); | 
					
						
							| 
									
										
										
										
											2010-03-16 16:38:02 +01:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |