| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | /**************************************************************************
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** This file is part of Qt Creator | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Contact: Nokia Corporation (qt-info@nokia.com) | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** Commercial Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** 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. | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** GNU Lesser General Public License Usage | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** 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.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | ** If you are unsure which license is appropriate for your use, please | 
					
						
							|  |  |  | ** contact the sales department at http://qt.nokia.com/contact.
 | 
					
						
							|  |  |  | ** | 
					
						
							|  |  |  | **************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "LookupContext.h"
 | 
					
						
							|  |  |  | #include "ResolveExpression.h"
 | 
					
						
							|  |  |  | #include "Overview.h"
 | 
					
						
							| 
									
										
										
										
											2010-05-20 13:44:38 +02:00
										 |  |  | #include "DeprecatedGenTemplateInstance.h"
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <CoreTypes.h>
 | 
					
						
							|  |  |  | #include <Symbols.h>
 | 
					
						
							|  |  |  | #include <Literals.h>
 | 
					
						
							|  |  |  | #include <Names.h>
 | 
					
						
							|  |  |  | #include <Scope.h>
 | 
					
						
							|  |  |  | #include <Control.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <QtDebug>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 14:00:56 +02:00
										 |  |  | namespace { | 
					
						
							|  |  |  |     const bool debug = ! qgetenv("CPLUSPLUS_LOOKUPCONTEXT_DEBUG").isEmpty(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | using namespace CPlusPlus; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | static void fullyQualifiedName_helper(Symbol *symbol, QList<const Name *> *names) | 
					
						
							| 
									
										
										
										
											2010-05-05 16:25:16 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (! symbol) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |     fullyQualifiedName_helper(symbol->enclosingSymbol(), names); | 
					
						
							| 
									
										
										
										
											2010-05-05 16:25:16 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:10:28 +02:00
										 |  |  |     if (symbol->name()) { | 
					
						
							|  |  |  |         if (symbol->isClass() || symbol->isNamespace()) { | 
					
						
							|  |  |  |             if (const QualifiedNameId *q = symbol->name()->asQualifiedNameId()) { | 
					
						
							|  |  |  |                 for (unsigned i = 0; i < q->nameCount(); ++i) | 
					
						
							|  |  |  |                     names->append(q->nameAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             } else if (symbol->name()->isNameId() || symbol->name()->isTemplateNameId()) { | 
					
						
							|  |  |  |                 names->append(symbol->name()); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-05-20 12:13:44 +02:00
										 |  |  |         } else if (symbol->isObjCClass() || symbol->isObjCBaseClass() || symbol->isObjCProtocol() | 
					
						
							|  |  |  |                 || symbol->isObjCForwardClassDeclaration() || symbol->isObjCForwardProtocolDeclaration()) { | 
					
						
							|  |  |  |             if (symbol->name()) | 
					
						
							|  |  |  |                 names->append(symbol->name()); | 
					
						
							| 
									
										
										
										
											2010-05-14 15:10:28 +02:00
										 |  |  |         } else if (symbol->isFunction()) { | 
					
						
							|  |  |  |             if (const QualifiedNameId *q = symbol->name()->asQualifiedNameId()) { | 
					
						
							|  |  |  |                 for (unsigned i = 0; i < q->nameCount() - 1; ++i) | 
					
						
							|  |  |  |                     names->append(q->nameAt(i)); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-05-05 16:25:16 +02:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  | bool ClassOrNamespace::CompareName::operator()(const Name *name, const Name *other) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     Q_ASSERT(name != 0); | 
					
						
							|  |  |  |     Q_ASSERT(other != 0); | 
					
						
							| 
									
										
										
										
											2010-05-10 12:19:13 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     const Identifier *id = name->identifier(); | 
					
						
							|  |  |  |     const Identifier *otherId = other->identifier(); | 
					
						
							| 
									
										
										
										
											2010-05-10 12:19:13 +02:00
										 |  |  |     return strcmp(id->chars(), otherId->chars()) < 0; | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | /////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // LookupContext
 | 
					
						
							|  |  |  | /////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | LookupContext::LookupContext() | 
					
						
							|  |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LookupContext::LookupContext(Document::Ptr thisDocument, | 
					
						
							|  |  |  |                              const Snapshot &snapshot) | 
					
						
							|  |  |  |     : _expressionDocument(Document::create("<LookupContext>")), | 
					
						
							|  |  |  |       _thisDocument(thisDocument), | 
					
						
							|  |  |  |       _snapshot(snapshot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LookupContext::LookupContext(Document::Ptr expressionDocument, | 
					
						
							|  |  |  |                              Document::Ptr thisDocument, | 
					
						
							|  |  |  |                              const Snapshot &snapshot) | 
					
						
							|  |  |  |     : _expressionDocument(expressionDocument), | 
					
						
							|  |  |  |       _thisDocument(thisDocument), | 
					
						
							|  |  |  |       _snapshot(snapshot) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LookupContext::LookupContext(const LookupContext &other) | 
					
						
							| 
									
										
										
										
											2010-05-17 16:56:22 +02:00
										 |  |  |     : _expressionDocument(other._expressionDocument), | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |       _thisDocument(other._thisDocument), | 
					
						
							|  |  |  |       _snapshot(other._snapshot), | 
					
						
							|  |  |  |       _bindings(other._bindings) | 
					
						
							|  |  |  | { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LookupContext &LookupContext::operator = (const LookupContext &other) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _expressionDocument = other._expressionDocument; | 
					
						
							|  |  |  |     _thisDocument = other._thisDocument; | 
					
						
							|  |  |  |     _snapshot = other._snapshot; | 
					
						
							|  |  |  |     _bindings = other._bindings; | 
					
						
							|  |  |  |     return *this; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  | QList<const Name *> LookupContext::fullyQualifiedName(Symbol *symbol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<const Name *> names; | 
					
						
							|  |  |  |     fullyQualifiedName_helper(symbol, &names); | 
					
						
							|  |  |  |     return names; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | QSharedPointer<CreateBindings> LookupContext::bindings() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! _bindings) | 
					
						
							|  |  |  |         _bindings = QSharedPointer<CreateBindings>(new CreateBindings(_thisDocument, _snapshot)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return _bindings; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void LookupContext::setBindings(QSharedPointer<CreateBindings> bindings) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _bindings = bindings; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Control *LookupContext::control() const | 
					
						
							| 
									
										
										
										
											2010-05-17 16:56:22 +02:00
										 |  |  | { return bindings()->control(); } | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | Document::Ptr LookupContext::expressionDocument() const | 
					
						
							|  |  |  | { return _expressionDocument; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Document::Ptr LookupContext::thisDocument() const | 
					
						
							|  |  |  | { return _thisDocument; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Document::Ptr LookupContext::document(const QString &fileName) const | 
					
						
							|  |  |  | { return _snapshot.document(fileName); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Snapshot LookupContext::snapshot() const | 
					
						
							|  |  |  | { return _snapshot; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ClassOrNamespace *LookupContext::globalNamespace() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return bindings()->globalNamespace(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  | ClassOrNamespace *LookupContext::lookupType(const Name *name, Scope *scope) const | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 14:00:56 +02:00
										 |  |  |     if (ClassOrNamespace *b = bindings()->lookupType(scope->owner())) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |         return b->lookupType(name); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  | ClassOrNamespace *LookupContext::lookupType(Symbol *symbol) const | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 14:00:56 +02:00
										 |  |  |     return bindings()->lookupType(symbol); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QList<Symbol *> LookupContext::lookup(const Name *name, Scope *scope) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     QList<Symbol *> candidates; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (! name) | 
					
						
							|  |  |  |         return candidates; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (; scope; scope = scope->enclosingScope()) { | 
					
						
							| 
									
										
										
										
											2010-05-25 15:55:12 +02:00
										 |  |  |         if ((name->isNameId() || name->isTemplateNameId()) && scope->isBlockScope()) { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:01:10 +02:00
										 |  |  |             bindings()->lookupInScope(name, scope, &candidates, /*templateId = */ 0); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (! candidates.isEmpty()) | 
					
						
							|  |  |  |                 break; // it's a local.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (unsigned index = 0; index < scope->symbolCount(); ++index) { | 
					
						
							|  |  |  |                 Symbol *member = scope->symbolAt(index); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) { | 
					
						
							| 
									
										
										
										
											2010-05-05 12:06:38 +02:00
										 |  |  |                     if (Namespace *enclosingNamespace = u->enclosingNamespaceScope()->owner()->asNamespace()) { | 
					
						
							| 
									
										
										
										
											2010-05-14 14:00:56 +02:00
										 |  |  |                         if (ClassOrNamespace *b = bindings()->lookupType(enclosingNamespace)) { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |                             if (ClassOrNamespace *uu = b->lookupType(u->name())) { | 
					
						
							| 
									
										
										
										
											2010-05-05 12:06:38 +02:00
										 |  |  |                                 candidates = uu->lookup(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                 if (! candidates.isEmpty()) | 
					
						
							|  |  |  |                                     return candidates; | 
					
						
							|  |  |  |                             } | 
					
						
							|  |  |  |                         } | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |                     } | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } else if (scope->isFunctionScope()) { | 
					
						
							|  |  |  |             Function *fun = scope->owner()->asFunction(); | 
					
						
							| 
									
										
										
										
											2010-05-11 10:01:10 +02:00
										 |  |  |             bindings()->lookupInScope(name, fun->arguments(), &candidates, /*templateId = */ 0); | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             for (TemplateParameters *it = fun->templateParameters(); it && candidates.isEmpty(); it = it->previous()) | 
					
						
							|  |  |  |                 bindings()->lookupInScope(name, it->scope(), &candidates, /* templateId = */ 0); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             if (! candidates.isEmpty()) | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  |                 break; // it's an argument or a template parameter.
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             if (fun->name() && fun->name()->isQualifiedNameId()) { | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  |                 if (ClassOrNamespace *binding = bindings()->lookupType(fun)) { | 
					
						
							|  |  |  |                     candidates = binding->lookup(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                     if (! candidates.isEmpty()) | 
					
						
							|  |  |  |                         return candidates; | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  |             // contunue, and look at the enclosing scope.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         } else if (scope->isObjCMethodScope()) { | 
					
						
							|  |  |  |             ObjCMethod *method = scope->owner()->asObjCMethod(); | 
					
						
							| 
									
										
										
										
											2010-05-11 10:01:10 +02:00
										 |  |  |             bindings()->lookupInScope(name, method->arguments(), &candidates, /*templateId = */ 0); | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             if (! candidates.isEmpty()) | 
					
						
							|  |  |  |                 break; // it's a formal argument.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  |         } else if (scope->isClassScope()) { | 
					
						
							|  |  |  |             Class *klass = scope->owner()->asClass(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (TemplateParameters *it = klass->templateParameters(); it && candidates.isEmpty(); it = it->previous()) | 
					
						
							|  |  |  |                 bindings()->lookupInScope(name, it->scope(), &candidates, /* templateId = */ 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (! candidates.isEmpty()) | 
					
						
							|  |  |  |                 break; // it's an argument or a template parameter.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if (ClassOrNamespace *binding = bindings()->lookupType(klass)) { | 
					
						
							|  |  |  |                 candidates = binding->lookup(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (! candidates.isEmpty()) | 
					
						
							|  |  |  |                     return candidates; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         } else if (scope->isNamespaceScope() || scope->isObjCClassScope() || scope->isObjCProtocolScope()) { | 
					
						
							| 
									
										
										
										
											2010-05-14 14:00:56 +02:00
										 |  |  |             if (ClassOrNamespace *binding = bindings()->lookupType(scope->owner())) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |                 return binding->lookup(name); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return candidates; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ClassOrNamespace::ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |     : _factory(factory), _parent(parent), _templateId(0) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  | const TemplateNameId *ClassOrNamespace::templateId() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _templateId; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-10 12:19:13 +02:00
										 |  |  | ClassOrNamespace *ClassOrNamespace::parent() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _parent; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | QList<ClassOrNamespace *> ClassOrNamespace::usings() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const_cast<ClassOrNamespace *>(this)->flush(); | 
					
						
							|  |  |  |     return _usings; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QList<Enum *> ClassOrNamespace::enums() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     const_cast<ClassOrNamespace *>(this)->flush(); | 
					
						
							|  |  |  |     return _enums; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QList<Symbol *> ClassOrNamespace::symbols() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-12 14:33:21 +02:00
										 |  |  |     if (_templateId && ! _usings.isEmpty()) | 
					
						
							|  |  |  |         return _usings.first()->symbols(); // ask to the base implementation
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     const_cast<ClassOrNamespace *>(this)->flush(); | 
					
						
							|  |  |  |     return _symbols; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ClassOrNamespace *ClassOrNamespace::globalNamespace() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ClassOrNamespace *e = const_cast<ClassOrNamespace *>(this); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     do { | 
					
						
							|  |  |  |         if (! e->_parent) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         e = e->_parent; | 
					
						
							|  |  |  |     } while (e); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return e; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:20:51 +02:00
										 |  |  | QList<Symbol *> ClassOrNamespace::find(const Name *name) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return lookup_helper(name, false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | QList<Symbol *> ClassOrNamespace::lookup(const Name *name) | 
					
						
							| 
									
										
										
										
											2010-05-11 10:20:51 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     return lookup_helper(name, true); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | QList<Symbol *> ClassOrNamespace::lookup_helper(const Name *name, bool searchInEnclosingScope) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QList<Symbol *> result; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |     if (name) { | 
					
						
							|  |  |  |         if (const QualifiedNameId *q = name->asQualifiedNameId()) { | 
					
						
							|  |  |  |             ClassOrNamespace *binding = this; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |             if (q->isGlobal()) | 
					
						
							|  |  |  |                 binding = globalNamespace(); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |             if (q->nameCount() == 1) | 
					
						
							|  |  |  |                 return binding->find(q->unqualifiedNameId()); | 
					
						
							| 
									
										
										
										
											2010-05-10 10:38:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |             binding = binding->lookupType(q->nameAt(0)); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |             for (unsigned index = 1; binding && index < q->nameCount() - 1; ++index) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |                 binding = binding->findType(q->nameAt(index)); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |             if (binding) | 
					
						
							|  |  |  |                 result = binding->find(q->unqualifiedNameId()); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |             return result; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-12 16:04:43 +02:00
										 |  |  |         QSet<ClassOrNamespace *> processed; | 
					
						
							|  |  |  |         ClassOrNamespace *binding = this; | 
					
						
							|  |  |  |         do { | 
					
						
							|  |  |  |             lookup_helper(name, binding, &result, &processed, /*templateId = */ 0); | 
					
						
							|  |  |  |             binding = binding->_parent; | 
					
						
							|  |  |  |         } while (searchInEnclosingScope && binding); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return result; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassOrNamespace::lookup_helper(const Name *name, ClassOrNamespace *binding, | 
					
						
							|  |  |  |                                      QList<Symbol *> *result, | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |                                      QSet<ClassOrNamespace *> *processed, | 
					
						
							|  |  |  |                                      const TemplateNameId *templateId) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 14:37:17 +02:00
										 |  |  |     if (binding && ! processed->contains(binding)) { | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         processed->insert(binding); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (Symbol *s, binding->symbols()) { | 
					
						
							|  |  |  |             if (ScopedSymbol *scoped = s->asScopedSymbol()) | 
					
						
							| 
									
										
										
										
											2010-05-11 10:01:10 +02:00
										 |  |  |                 _factory->lookupInScope(name, scoped->members(), result, templateId); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (Enum *e, binding->enums()) | 
					
						
							| 
									
										
										
										
											2010-05-11 10:01:10 +02:00
										 |  |  |             _factory->lookupInScope(name, e->members(), result, templateId); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         foreach (ClassOrNamespace *u, binding->usings()) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |             lookup_helper(name, u, result, processed, binding->_templateId); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:01:10 +02:00
										 |  |  | void CreateBindings::lookupInScope(const Name *name, Scope *scope, | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |                                    QList<Symbol *> *result, | 
					
						
							|  |  |  |                                    const TemplateNameId *templateId) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |     Q_UNUSED(templateId); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     if (! name) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (const OperatorNameId *op = name->asOperatorNameId()) { | 
					
						
							|  |  |  |         for (Symbol *s = scope->lookat(op->kind()); s; s = s->next()) { | 
					
						
							|  |  |  |             if (! s->name()) | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |             else if (! s->name()->isEqualTo(op)) | 
					
						
							|  |  |  |                 continue; | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             result->append(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } else if (const Identifier *id = name->identifier()) { | 
					
						
							|  |  |  |         for (Symbol *s = scope->lookat(id); s; s = s->next()) { | 
					
						
							| 
									
										
										
										
											2010-05-12 11:16:54 +02:00
										 |  |  |             if (! id->isEqualTo(s->identifier())) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |                 continue; | 
					
						
							| 
									
										
										
										
											2010-05-12 11:16:54 +02:00
										 |  |  |             else if (s->name()->isQualifiedNameId()) | 
					
						
							|  |  |  |                 continue; // skip qualified ids.
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-17 16:56:22 +02:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2010-05-17 15:08:10 +02:00
										 |  |  |             if (templateId && (s->isDeclaration() || s->isFunction())) { | 
					
						
							| 
									
										
										
										
											2010-05-10 09:44:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-17 15:08:10 +02:00
										 |  |  |                 FullySpecifiedType ty = GenTemplateInstance::instantiate(templateId, s, _control); | 
					
						
							| 
									
										
										
										
											2010-05-10 09:44:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-17 15:08:10 +02:00
										 |  |  |                 if (debug) { | 
					
						
							| 
									
										
										
										
											2010-05-14 15:34:39 +02:00
										 |  |  |                     Overview oo; | 
					
						
							|  |  |  |                     oo.setShowFunctionSignatures(true); | 
					
						
							|  |  |  |                     oo.setShowReturnTypes(true); | 
					
						
							| 
									
										
										
										
											2010-05-17 15:08:10 +02:00
										 |  |  |                     qDebug() << "instantiate:" << oo(s->type(), s->name()) << "using:" << oo(templateId) << oo(ty); | 
					
						
							|  |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-05-10 09:44:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-17 15:08:10 +02:00
										 |  |  |                 if (Declaration *decl = s->asDeclaration()) { | 
					
						
							|  |  |  |                     Declaration *d = _control->newDeclaration(0, 0); | 
					
						
							|  |  |  |                     d->copy(decl); | 
					
						
							|  |  |  |                     d->setType(ty); | 
					
						
							|  |  |  |                     result->append(d); | 
					
						
							|  |  |  |                     continue; | 
					
						
							|  |  |  |                 } else if (Function *fun = s->asFunction()) { | 
					
						
							|  |  |  |                     Function *d = ty->asFunctionType(); | 
					
						
							|  |  |  |                     d->copy(fun); | 
					
						
							|  |  |  |                     result->append(d); | 
					
						
							|  |  |  |                     continue; | 
					
						
							| 
									
										
										
										
											2010-05-14 15:34:39 +02:00
										 |  |  |                 } | 
					
						
							| 
									
										
										
										
											2010-05-10 09:44:18 +02:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2010-05-17 16:56:22 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2010-05-10 09:44:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             result->append(s); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  | ClassOrNamespace *ClassOrNamespace::lookupType(const Name *name) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (! name) | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     QSet<ClassOrNamespace *> processed; | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |     return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ true); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  | ClassOrNamespace *ClassOrNamespace::findType(const Name *name) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     QSet<ClassOrNamespace *> processed; | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |     return lookupType_helper(name, &processed, /*searchInEnclosingScope =*/ false); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  | ClassOrNamespace *ClassOrNamespace::lookupType_helper(const Name *name, | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |                                                       QSet<ClassOrNamespace *> *processed, | 
					
						
							|  |  |  |                                                       bool searchInEnclosingScope) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |     if (const QualifiedNameId *q = name->asQualifiedNameId()) { | 
					
						
							|  |  |  |         ClassOrNamespace *e = this; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |         if (q->isGlobal()) | 
					
						
							|  |  |  |             e = globalNamespace(); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |         e = e->lookupType(q->nameAt(0)); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |         for (unsigned index = 1; e && index < q->nameCount(); ++index) | 
					
						
							|  |  |  |             e = e->findType(q->nameAt(index)); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |         return e; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |     } else if (! processed->contains(this)) { | 
					
						
							|  |  |  |         processed->insert(this); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 15:32:40 +02:00
										 |  |  |         if (name->isNameId() || name->isTemplateNameId()) { | 
					
						
							|  |  |  |             flush(); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  |             if (ClassOrNamespace *e = nestedType(name)) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |                 return e; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-21 15:44:04 +02:00
										 |  |  |             else if (_templateId) { | 
					
						
							|  |  |  |                 Q_ASSERT(_usings.size() == 1); | 
					
						
							|  |  |  |                 ClassOrNamespace *delegate = _usings.first(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (ClassOrNamespace *r = delegate->lookupType_helper(name, processed, /*searchInEnclosingScope = */ true)) | 
					
						
							|  |  |  |                     return r; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             foreach (ClassOrNamespace *u, usings()) { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |                 if (ClassOrNamespace *r = u->lookupType_helper(name, processed, /*searchInEnclosingScope =*/ false)) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |                     return r; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |         if (_parent && searchInEnclosingScope) | 
					
						
							|  |  |  |             return _parent->lookupType_helper(name, processed, searchInEnclosingScope); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  | ClassOrNamespace *ClassOrNamespace::nestedType(const Name *name) const | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     Q_ASSERT(name != 0); | 
					
						
							|  |  |  |     Q_ASSERT(name->isNameId() || name->isTemplateNameId()); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     const_cast<ClassOrNamespace *>(this)->flush(); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     Table::const_iterator it = _classOrNamespaces.find(name); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     if (it == _classOrNamespaces.end()) | 
					
						
							|  |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |     ClassOrNamespace *c = it->second; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (const TemplateNameId *templId = name->asTemplateNameId()) { | 
					
						
							|  |  |  |         foreach (ClassOrNamespace *i, c->_instantiations) { | 
					
						
							| 
									
										
										
										
											2010-05-10 09:44:18 +02:00
										 |  |  |             if (templId->isEqualTo(i->_templateId)) | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |                 return i; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         ClassOrNamespace *i = _factory->allocClassOrNamespace(c); | 
					
						
							|  |  |  |         i->_templateId = templId; | 
					
						
							|  |  |  |         i->_usings.append(c); | 
					
						
							|  |  |  |         c->_instantiations.append(i); | 
					
						
							|  |  |  |         return i; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return c; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassOrNamespace::flush() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-05 14:07:10 +02:00
										 |  |  |     if (! _todo.isEmpty()) { | 
					
						
							|  |  |  |         const QList<Symbol *> todo = _todo; | 
					
						
							|  |  |  |         _todo.clear(); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 14:07:10 +02:00
										 |  |  |         foreach (Symbol *member, todo) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |             _factory->process(member, this); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassOrNamespace::addSymbol(Symbol *symbol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _symbols.append(symbol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassOrNamespace::addTodo(Symbol *symbol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _todo.append(symbol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassOrNamespace::addEnum(Enum *e) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _enums.append(e); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ClassOrNamespace::addUsing(ClassOrNamespace *u) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _usings.append(u); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  | void ClassOrNamespace::addNestedType(const Name *alias, ClassOrNamespace *e) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     _classOrNamespaces[alias] = e; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  | ClassOrNamespace *ClassOrNamespace::findOrCreateType(const Name *name) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     if (! name) | 
					
						
							|  |  |  |         return this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (const QualifiedNameId *q = name->asQualifiedNameId()) { | 
					
						
							|  |  |  |         ClassOrNamespace *e = this; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (unsigned i = 0; e && i < q->nameCount(); ++i) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |             e = e->findOrCreateType(q->nameAt(i)); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         return e; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |     } else if (name->isNameId() || name->isTemplateNameId()) { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  |         ClassOrNamespace *e = nestedType(name); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (! e) { | 
					
						
							|  |  |  |             e = _factory->allocClassOrNamespace(this); | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |             _classOrNamespaces[name] = e; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return e; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CreateBindings::CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot) | 
					
						
							|  |  |  |     : _snapshot(snapshot) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |     _control = new Control(); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     _globalNamespace = allocClassOrNamespace(/*parent = */ 0); | 
					
						
							|  |  |  |     _currentClassOrNamespace = _globalNamespace; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     process(thisDocument); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CreateBindings::~CreateBindings() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qDeleteAll(_entities); | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  |     delete _control; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:03:30 +02:00
										 |  |  | ClassOrNamespace *CreateBindings::switchCurrentClassOrNamespace(ClassOrNamespace *classOrNamespace) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     ClassOrNamespace *previous = _currentClassOrNamespace; | 
					
						
							|  |  |  |     _currentClassOrNamespace = classOrNamespace; | 
					
						
							|  |  |  |     return previous; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ClassOrNamespace *CreateBindings::globalNamespace() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _globalNamespace; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 14:00:56 +02:00
										 |  |  | ClassOrNamespace *CreateBindings::lookupType(Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 12:47:20 +02:00
										 |  |  |     const QList<const Name *> names = LookupContext::fullyQualifiedName(symbol); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 16:25:16 +02:00
										 |  |  |     if (names.isEmpty()) | 
					
						
							|  |  |  |         return _globalNamespace; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |     ClassOrNamespace *b = _globalNamespace->lookupType(names.at(0)); | 
					
						
							| 
									
										
										
										
											2010-05-05 16:25:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (int i = 1; b && i < names.size(); ++i) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |         b = b->findType(names.at(i)); | 
					
						
							| 
									
										
										
										
											2010-05-05 16:25:16 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return b; | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CreateBindings::process(Symbol *s, ClassOrNamespace *classOrNamespace) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:03:30 +02:00
										 |  |  |     ClassOrNamespace *previous = switchCurrentClassOrNamespace(classOrNamespace); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     accept(s); | 
					
						
							| 
									
										
										
										
											2010-05-11 10:03:30 +02:00
										 |  |  |     (void) switchCurrentClassOrNamespace(previous); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CreateBindings::process(Symbol *symbol) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _currentClassOrNamespace->addTodo(symbol); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-06 14:01:38 +02:00
										 |  |  | Control *CreateBindings::control() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return _control; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | ClassOrNamespace *CreateBindings::allocClassOrNamespace(ClassOrNamespace *parent) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ClassOrNamespace *e = new ClassOrNamespace(this, parent); | 
					
						
							|  |  |  |     _entities.append(e); | 
					
						
							|  |  |  |     return e; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CreateBindings::process(Document::Ptr doc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! doc) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     else if (Namespace *globalNamespace = doc->globalNamespace()) { | 
					
						
							|  |  |  |         if (! _processed.contains(globalNamespace)) { | 
					
						
							|  |  |  |             _processed.insert(globalNamespace); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             foreach (const Document::Include &i, doc->includes()) { | 
					
						
							|  |  |  |                 if (Document::Ptr incl = _snapshot.document(i.fileName())) | 
					
						
							|  |  |  |                     process(incl); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             accept(globalNamespace); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  | ClassOrNamespace *CreateBindings::enterClassOrNamespaceBinding(Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |     ClassOrNamespace *entity = _currentClassOrNamespace->findOrCreateType(symbol->name()); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     entity->addSymbol(symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:03:30 +02:00
										 |  |  |     return switchCurrentClassOrNamespace(entity); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  | ClassOrNamespace *CreateBindings::enterGlobalClassOrNamespace(Symbol *symbol) | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |     ClassOrNamespace *entity = _globalNamespace->findOrCreateType(symbol->name()); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     entity->addSymbol(symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-11 10:03:30 +02:00
										 |  |  |     return switchCurrentClassOrNamespace(entity); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(Namespace *ns) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  |     ClassOrNamespace *previous = enterClassOrNamespaceBinding(ns); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < ns->memberCount(); ++i) | 
					
						
							|  |  |  |         process(ns->memberAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(Class *klass) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-10 12:30:42 +02:00
										 |  |  |     ClassOrNamespace *previous = _currentClassOrNamespace; | 
					
						
							|  |  |  |     ClassOrNamespace *binding = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (klass->name() && klass->name()->isQualifiedNameId()) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |         binding = _currentClassOrNamespace->lookupType(klass->name()); | 
					
						
							| 
									
										
										
										
											2010-05-10 12:30:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (! binding) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:54:56 +02:00
										 |  |  |         binding = _currentClassOrNamespace->findOrCreateType(klass->name()); | 
					
						
							| 
									
										
										
										
											2010-05-10 12:30:42 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _currentClassOrNamespace = binding; | 
					
						
							|  |  |  |     _currentClassOrNamespace->addSymbol(klass); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < klass->baseClassCount(); ++i) | 
					
						
							|  |  |  |         process(klass->baseClassAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < klass->memberCount(); ++i) | 
					
						
							|  |  |  |         process(klass->memberAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ForwardClassDeclaration *klass) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-10 09:47:46 +02:00
										 |  |  |     if (! klass->isFriend()) { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  |         ClassOrNamespace *previous = enterClassOrNamespaceBinding(klass); | 
					
						
							| 
									
										
										
										
											2010-05-10 09:47:46 +02:00
										 |  |  |         _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(Enum *e) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     _currentClassOrNamespace->addEnum(e); | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(Declaration *decl) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (decl->isTypedef()) { | 
					
						
							|  |  |  |         const FullySpecifiedType ty = decl->type(); | 
					
						
							|  |  |  |         const Identifier *typedefId = decl->identifier(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (typedefId && ! (ty.isConst() || ty.isVolatile())) { | 
					
						
							|  |  |  |             if (const NamedType *namedTy = ty->asNamedType()) { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |                 if (ClassOrNamespace *e = _currentClassOrNamespace->lookupType(namedTy->name())) { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  |                     _currentClassOrNamespace->addNestedType(decl->name(), e); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |                 } else if (false) { | 
					
						
							|  |  |  |                     Overview oo; | 
					
						
							|  |  |  |                     qDebug() << "found entity not found for" << oo(namedTy->name()); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(Function *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(BaseClass *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |     if (ClassOrNamespace *base = _currentClassOrNamespace->lookupType(b->name())) { | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         _currentClassOrNamespace->addUsing(base); | 
					
						
							|  |  |  |     } else if (false) { | 
					
						
							|  |  |  |         Overview oo; | 
					
						
							|  |  |  |         qDebug() << "no entity for:" << oo(b->name()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(UsingNamespaceDirective *u) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |     if (ClassOrNamespace *e = _currentClassOrNamespace->lookupType(u->name())) { | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         _currentClassOrNamespace->addUsing(e); | 
					
						
							|  |  |  |     } else if (false) { | 
					
						
							|  |  |  |         Overview oo; | 
					
						
							|  |  |  |         qDebug() << "no entity for namespace:" << oo(u->name()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(NamespaceAlias *a) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (! a->identifier()) { | 
					
						
							|  |  |  |         return false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |     } else if (ClassOrNamespace *e = _currentClassOrNamespace->lookupType(a->namespaceName())) { | 
					
						
							| 
									
										
										
										
											2010-05-06 11:26:23 +02:00
										 |  |  |         if (a->name()->isNameId() || a->name()->isTemplateNameId()) | 
					
						
							| 
									
										
										
										
											2010-05-14 13:49:16 +02:00
										 |  |  |             _currentClassOrNamespace->addNestedType(a->name(), e); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     } else if (false) { | 
					
						
							|  |  |  |         Overview oo; | 
					
						
							|  |  |  |         qDebug() << "no entity for namespace:" << oo(a->namespaceName()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCClass *klass) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  |     ClassOrNamespace *previous = enterGlobalClassOrNamespace(klass); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     process(klass->baseClass()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < klass->protocolCount(); ++i) | 
					
						
							|  |  |  |         process(klass->protocolAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < klass->memberCount(); ++i) | 
					
						
							|  |  |  |         process(klass->memberAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCBaseClass *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |     if (ClassOrNamespace *base = _globalNamespace->lookupType(b->name())) { | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         _currentClassOrNamespace->addUsing(base); | 
					
						
							|  |  |  |     } else if (false) { | 
					
						
							|  |  |  |         Overview oo; | 
					
						
							|  |  |  |         qDebug() << "no entity for:" << oo(b->name()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCForwardClassDeclaration *klass) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  |     ClassOrNamespace *previous = enterGlobalClassOrNamespace(klass); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCProtocol *proto) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  |     ClassOrNamespace *previous = enterGlobalClassOrNamespace(proto); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < proto->protocolCount(); ++i) | 
					
						
							|  |  |  |         process(proto->protocolAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (unsigned i = 0; i < proto->memberCount(); ++i) | 
					
						
							|  |  |  |         process(proto->memberAt(i)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCBaseProtocol *b) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-14 13:44:54 +02:00
										 |  |  |     if (ClassOrNamespace *base = _globalNamespace->lookupType(b->name())) { | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |         _currentClassOrNamespace->addUsing(base); | 
					
						
							|  |  |  |     } else if (false) { | 
					
						
							|  |  |  |         Overview oo; | 
					
						
							|  |  |  |         qDebug() << "no entity for:" << oo(b->name()); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCForwardProtocolDeclaration *proto) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2010-05-11 10:12:49 +02:00
										 |  |  |     ClassOrNamespace *previous = enterGlobalClassOrNamespace(proto); | 
					
						
							| 
									
										
										
										
											2010-05-05 10:28:32 +02:00
										 |  |  |     _currentClassOrNamespace = previous; | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool CreateBindings::visit(ObjCMethod *) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } |