OSDN Git Service

9161a0e39dfd7eb78cf6c8aa3a91c27ec030e8ba
[qt-creator-jp/qt-creator-jp.git] / src / shared / cplusplus / Symbols.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33 // Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
34 //
35 // Permission is hereby granted, free of charge, to any person obtaining a copy
36 // of this software and associated documentation files (the "Software"), to deal
37 // in the Software without restriction, including without limitation the rights
38 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39 // copies of the Software, and to permit persons to whom the Software is
40 // furnished to do so, subject to the following conditions:
41 //
42 // The above copyright notice and this permission notice shall be included in
43 // all copies or substantial portions of the Software.
44 //
45 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51 // THE SOFTWARE.
52
53 #include "Symbols.h"
54 #include "Names.h"
55 #include "TypeVisitor.h"
56 #include "SymbolVisitor.h"
57 #include "TypeMatcher.h"
58 #include "Scope.h"
59
60 using namespace CPlusPlus;
61
62 UsingNamespaceDirective::UsingNamespaceDirective(TranslationUnit *translationUnit,
63                                                  unsigned sourceLocation, const Name *name)
64     : Symbol(translationUnit, sourceLocation, name)
65 { }
66
67 UsingNamespaceDirective::~UsingNamespaceDirective()
68 { }
69
70 FullySpecifiedType UsingNamespaceDirective::type() const
71 { return FullySpecifiedType(); }
72
73 void UsingNamespaceDirective::visitSymbol0(SymbolVisitor *visitor)
74 { visitor->visit(this); }
75
76 NamespaceAlias::NamespaceAlias(TranslationUnit *translationUnit,
77                                unsigned sourceLocation, const Name *name)
78     : Symbol(translationUnit, sourceLocation, name), _namespaceName(0)
79 { }
80
81 NamespaceAlias::~NamespaceAlias()
82 { }
83
84 const Name *NamespaceAlias::namespaceName() const
85 { return _namespaceName; }
86
87 void NamespaceAlias::setNamespaceName(const Name *namespaceName)
88 { _namespaceName = namespaceName; }
89
90 FullySpecifiedType NamespaceAlias::type() const
91 { return FullySpecifiedType(); }
92
93 void NamespaceAlias::visitSymbol0(SymbolVisitor *visitor)
94 { visitor->visit(this); }
95
96
97 UsingDeclaration::UsingDeclaration(TranslationUnit *translationUnit,
98                                    unsigned sourceLocation, const Name *name)
99     : Symbol(translationUnit, sourceLocation, name)
100 { }
101
102 UsingDeclaration::~UsingDeclaration()
103 { }
104
105 FullySpecifiedType UsingDeclaration::type() const
106 { return FullySpecifiedType(); }
107
108 void UsingDeclaration::visitSymbol0(SymbolVisitor *visitor)
109 { visitor->visit(this); }
110
111 Declaration::Declaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
112     : Symbol(translationUnit, sourceLocation, name)
113 { }
114
115 Declaration::~Declaration()
116 { }
117
118 void Declaration::setType(const FullySpecifiedType &type)
119 { _type = type; }
120
121 FullySpecifiedType Declaration::type() const
122 { return _type; }
123
124 void Declaration::visitSymbol0(SymbolVisitor *visitor)
125 { visitor->visit(this); }
126
127 Argument::Argument(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
128     : Symbol(translationUnit, sourceLocation, name),
129       _initializer(0)
130 { }
131
132 Argument::~Argument()
133 { }
134
135 bool Argument::hasInitializer() const
136 { return _initializer != 0; }
137
138 const StringLiteral *Argument::initializer() const
139 { return _initializer; }
140
141 void Argument::setInitializer(const StringLiteral *initializer)
142 { _initializer = initializer; }
143
144 void Argument::setType(const FullySpecifiedType &type)
145 { _type = type; }
146
147 FullySpecifiedType Argument::type() const
148 { return _type; }
149
150 void Argument::visitSymbol0(SymbolVisitor *visitor)
151 { visitor->visit(this); }
152
153 TypenameArgument::TypenameArgument(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
154     : Symbol(translationUnit, sourceLocation, name)
155 { }
156
157 TypenameArgument::~TypenameArgument()
158 { }
159
160 void TypenameArgument::setType(const FullySpecifiedType &type)
161 { _type = type; }
162
163 FullySpecifiedType TypenameArgument::type() const
164 { return _type; }
165
166 void TypenameArgument::visitSymbol0(SymbolVisitor *visitor)
167 { visitor->visit(this); }
168
169 Function::Function(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
170     : Scope(translationUnit, sourceLocation, name),
171       _flags(0)
172 { }
173
174 Function::~Function()
175 { }
176
177 bool Function::isNormal() const
178 { return f._methodKey == NormalMethod; }
179
180 bool Function::isSignal() const
181 { return f._methodKey == SignalMethod; }
182
183 bool Function::isSlot() const
184 { return f._methodKey == SlotMethod; }
185
186 bool Function::isInvokable() const
187 { return f._methodKey == InvokableMethod; }
188
189 int Function::methodKey() const
190 { return f._methodKey; }
191
192 void Function::setMethodKey(int key)
193 { f._methodKey = key; }
194
195 bool Function::isEqualTo(const Type *other) const
196 {
197     const Function *o = other->asFunctionType();
198     if (! o)
199         return false;
200     else if (isConst() != o->isConst())
201         return false;
202     else if (isVolatile() != o->isVolatile())
203         return false;
204 #ifdef ICHECK_BUILD
205     else if (isInvokable() != o->isInvokable())
206         return false;
207     else if (isSignal() != o->isSignal())
208         return false;
209 #endif
210
211     const Name *l = unqualifiedName();
212     const Name *r = o->unqualifiedName();
213     if (l == r || (l && l->isEqualTo(r))) {
214         if (argumentCount() != o->argumentCount())
215             return false;
216         else if (! _returnType.isEqualTo(o->_returnType))
217             return false;
218         for (unsigned i = 0; i < argumentCount(); ++i) {
219             Symbol *l = argumentAt(i);
220             Symbol *r = o->argumentAt(i);
221             if (! l->type().isEqualTo(r->type()))
222                 return false;
223         }
224         return true;
225     }
226     return false;
227 }
228
229 #ifdef ICHECK_BUILD
230 bool Function::isEqualTo(const Function* fct, bool ignoreName/* = false*/) const
231 {
232     if(!ignoreName)
233         return isEqualTo((Type*)fct);
234
235     if (! fct)
236         return false;
237     else if (isConst() != fct->isConst())
238         return false;
239     else if (isVolatile() != fct->isVolatile())
240         return false;
241     else if (isInvokable() != fct->isInvokable())
242         return false;
243     else if (isSignal() != fct->isSignal())
244         return false;
245
246     if (_arguments->symbolCount() != fct->_arguments->symbolCount())
247         return false;
248     else if (! _returnType.isEqualTo(fct->_returnType))
249         return false;
250     for (unsigned i = 0; i < _arguments->symbolCount(); ++i) {
251         Symbol *l = _arguments->symbolAt(i);
252         Symbol *r = fct->_arguments->symbolAt(i);
253         if (! l->type().isEqualTo(r->type()))
254             return false;
255     }
256     return true;
257 }
258 #endif
259
260 void Function::accept0(TypeVisitor *visitor)
261 { visitor->visit(this); }
262
263 bool Function::matchType0(const Type *otherType, TypeMatcher *matcher) const
264 {
265     if (const Function *otherTy = otherType->asFunctionType())
266         return matcher->match(this, otherTy);
267
268     return false;
269 }
270
271 FullySpecifiedType Function::type() const
272 {
273     FullySpecifiedType ty(const_cast<Function *>(this));
274     ty.setConst(isConst());
275     ty.setVolatile(isVolatile());
276     return ty;
277 }
278
279 FullySpecifiedType Function::returnType() const
280 { return _returnType; }
281
282 void Function::setReturnType(const FullySpecifiedType &returnType)
283 { _returnType = returnType; }
284
285 bool Function::hasReturnType() const
286 {
287     const FullySpecifiedType ty = returnType();
288     return ty.isValid() || ty.isSigned() || ty.isUnsigned();
289 }
290
291 unsigned Function::argumentCount() const
292 {
293     const unsigned c = memberCount();
294     if (c > 0 && memberAt(0)->type()->isVoidType())
295         return 0;
296     if (c > 0 && memberAt(c - 1)->isBlock())
297         return c - 1;
298     return c;
299 }
300
301 Symbol *Function::argumentAt(unsigned index) const
302 { return memberAt(index); }
303
304 bool Function::hasArguments() const
305 {
306     return ! (argumentCount() == 0 ||
307               (argumentCount() == 1 && argumentAt(0)->type()->isVoidType()));
308 }
309
310 unsigned Function::minimumArgumentCount() const
311 {
312     unsigned index = 0;
313
314     for (; index < argumentCount(); ++index) {
315         if (Argument *arg = argumentAt(index)->asArgument()) {
316             if (arg->hasInitializer())
317                 break;
318         }
319     }
320
321     return index;
322 }
323
324 bool Function::isVirtual() const
325 { return f._isVirtual; }
326
327 void Function::setVirtual(bool isVirtual)
328 { f._isVirtual = isVirtual; }
329
330 bool Function::isVariadic() const
331 { return f._isVariadic; }
332
333 void Function::setVariadic(bool isVariadic)
334 { f._isVariadic = isVariadic; }
335
336 bool Function::isConst() const
337 { return f._isConst; }
338
339 void Function::setConst(bool isConst)
340 { f._isConst = isConst; }
341
342 bool Function::isVolatile() const
343 { return f._isVolatile; }
344
345 void Function::setVolatile(bool isVolatile)
346 { f._isVolatile = isVolatile; }
347
348 bool Function::isPureVirtual() const
349 { return f._isPureVirtual; }
350
351 void Function::setPureVirtual(bool isPureVirtual)
352 { f._isPureVirtual = isPureVirtual; }
353
354 bool Function::isAmbiguous() const
355 { return f._isAmbiguous; }
356
357 void Function::setAmbiguous(bool isAmbiguous)
358 { f._isAmbiguous = isAmbiguous; }
359
360 void Function::visitSymbol0(SymbolVisitor *visitor)
361 {
362     if (visitor->visit(this)) {
363         for (unsigned i = 0; i < memberCount(); ++i) {
364             visitSymbol(memberAt(i), visitor);
365         }
366     }
367 }
368
369 bool Function::maybeValidPrototype(unsigned actualArgumentCount) const
370 {
371     unsigned minNumberArguments = 0;
372
373     for (; minNumberArguments < this->argumentCount(); ++minNumberArguments) {
374         Argument *arg = this->argumentAt(minNumberArguments)->asArgument();
375
376         if (arg->hasInitializer())
377             break;
378     }
379
380     if (actualArgumentCount < minNumberArguments) {
381         // not enough arguments.
382         return false;
383
384     } else if (! this->isVariadic() && actualArgumentCount > this->argumentCount()) {
385         // too many arguments.
386         return false;
387     }
388
389     return true;
390 }
391
392
393 Block::Block(TranslationUnit *translationUnit, unsigned sourceLocation)
394     : Scope(translationUnit, sourceLocation, /*name = */ 0)
395 { }
396
397 Block::~Block()
398 { }
399
400 FullySpecifiedType Block::type() const
401 { return FullySpecifiedType(); }
402
403 void Block::visitSymbol0(SymbolVisitor *visitor)
404 {
405     if (visitor->visit(this)) {
406         for (unsigned i = 0; i < memberCount(); ++i) {
407             visitSymbol(memberAt(i), visitor);
408         }
409     }
410 }
411
412 Enum::Enum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
413     : Scope(translationUnit, sourceLocation, name)
414 { }
415
416 Enum::~Enum()
417 { }
418
419 FullySpecifiedType Enum::type() const
420 { return FullySpecifiedType(const_cast<Enum *>(this)); }
421
422 bool Enum::isEqualTo(const Type *other) const
423 {
424     const Enum *o = other->asEnumType();
425     if (! o)
426         return false;
427     const Name *l = unqualifiedName();
428     const Name *r = o->unqualifiedName();
429     if (l == r)
430         return true;
431     else if (! l)
432         return false;
433     return l->isEqualTo(r);
434 }
435
436 void Enum::accept0(TypeVisitor *visitor)
437 { visitor->visit(this); }
438
439 bool Enum::matchType0(const Type *otherType, TypeMatcher *matcher) const
440 {
441     if (const Enum *otherTy = otherType->asEnumType())
442         return matcher->match(this, otherTy);
443
444     return false;
445 }
446
447 void Enum::visitSymbol0(SymbolVisitor *visitor)
448 {
449     if (visitor->visit(this)) {
450         for (unsigned i = 0; i < memberCount(); ++i) {
451             visitSymbol(memberAt(i), visitor);
452         }
453     }
454 }
455
456 Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
457     : Scope(translationUnit, sourceLocation, name)
458 { }
459
460 Template::~Template()
461 { }
462
463 unsigned Template::templateParameterCount() const
464 {
465     if (declaration() != 0)
466         return memberCount() - 1;
467
468     return 0;
469 }
470
471 Symbol *Template::templateParameterAt(unsigned index) const
472 { return memberAt(index); }
473
474 Symbol *Template::declaration() const
475 {
476     if (isEmpty())
477         return 0;
478
479     if (Symbol *s = memberAt(memberCount() - 1)) {
480         if (s->isClass() || s->isForwardClassDeclaration() ||
481             s->isTemplate() || s->isFunction() || s->isDeclaration())
482             return s;
483     }
484
485     return 0;
486 }
487
488 FullySpecifiedType Template::type() const
489 { return FullySpecifiedType(const_cast<Template *>(this)); }
490
491 bool Template::isEqualTo(const Type *other) const
492 { return other == this; }
493
494 void Template::visitSymbol0(SymbolVisitor *visitor)
495 {
496     if (visitor->visit(this)) {
497         for (unsigned i = 0; i < memberCount(); ++i) {
498             visitSymbol(memberAt(i), visitor);
499         }
500     }
501 }
502
503 void Template::accept0(TypeVisitor *visitor)
504 { visitor->visit(this); }
505
506 bool Template::matchType0(const Type *otherType, TypeMatcher *matcher) const
507 {
508     if (const Template *otherTy = otherType->asTemplateType())
509         return matcher->match(this, otherTy);
510     return false;
511 }
512
513 Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
514     : Scope(translationUnit, sourceLocation, name)
515 { }
516
517 Namespace::~Namespace()
518 { }
519
520 bool Namespace::isEqualTo(const Type *other) const
521 {
522     const Namespace *o = other->asNamespaceType();
523     if (! o)
524         return false;
525     const Name *l = unqualifiedName();
526     const Name *r = o->unqualifiedName();
527     if (l == r || (l && l->isEqualTo(r)))
528         return true;
529     return false;
530 }
531
532 void Namespace::accept0(TypeVisitor *visitor)
533 { visitor->visit(this); }
534
535 bool Namespace::matchType0(const Type *otherType, TypeMatcher *matcher) const
536 {
537     if (const Namespace *otherTy = otherType->asNamespaceType())
538         return matcher->match(this, otherTy);
539
540     return false;
541 }
542
543 void Namespace::visitSymbol0(SymbolVisitor *visitor)
544 {
545     if (visitor->visit(this)) {
546         for (unsigned i = 0; i < memberCount(); ++i) {
547             visitSymbol(memberAt(i), visitor);
548         }
549     }
550 }
551
552 FullySpecifiedType Namespace::type() const
553 { return FullySpecifiedType(const_cast<Namespace *>(this)); }
554
555 BaseClass::BaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
556     : Symbol(translationUnit, sourceLocation, name),
557       _isVirtual(false)
558 { }
559
560 BaseClass::~BaseClass()
561 { }
562
563 FullySpecifiedType BaseClass::type() const
564 { return _type; }
565
566 void BaseClass::setType(const FullySpecifiedType &type)
567 { _type = type; }
568
569 bool BaseClass::isVirtual() const
570 { return _isVirtual; }
571
572 void BaseClass::setVirtual(bool isVirtual)
573 { _isVirtual = isVirtual; }
574
575 void BaseClass::visitSymbol0(SymbolVisitor *visitor)
576 { visitor->visit(this); }
577
578 ForwardClassDeclaration::ForwardClassDeclaration(TranslationUnit *translationUnit,
579                                                  unsigned sourceLocation, const Name *name)
580     : Symbol(translationUnit, sourceLocation, name)
581 { }
582
583 ForwardClassDeclaration::~ForwardClassDeclaration()
584 { }
585
586 FullySpecifiedType ForwardClassDeclaration::type() const
587 { return FullySpecifiedType(const_cast<ForwardClassDeclaration *>(this)); }
588
589 bool ForwardClassDeclaration::isEqualTo(const Type *other) const
590 {
591     if (const ForwardClassDeclaration *otherClassFwdTy = other->asForwardClassDeclarationType()) {
592         if (name() == otherClassFwdTy->name())
593             return true;
594         else if (name() && otherClassFwdTy->name())
595             return name()->isEqualTo(otherClassFwdTy->name());
596
597         return false;
598     }
599     return false;
600 }
601
602 void ForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor)
603 { visitor->visit(this); }
604
605 void ForwardClassDeclaration::accept0(TypeVisitor *visitor)
606 { visitor->visit(this); }
607
608 bool ForwardClassDeclaration::matchType0(const Type *otherType, TypeMatcher *matcher) const
609 {
610     if (const ForwardClassDeclaration *otherTy = otherType->asForwardClassDeclarationType())
611         return matcher->match(this, otherTy);
612
613     return false;
614 }
615
616 Class::Class(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
617     : Scope(translationUnit, sourceLocation, name),
618       _key(ClassKey)
619 { }
620
621 Class::~Class()
622 { }
623
624 bool Class::isClass() const
625 { return _key == ClassKey; }
626
627 bool Class::isStruct() const
628 { return _key == StructKey; }
629
630 bool Class::isUnion() const
631 { return _key == UnionKey; }
632
633 Class::Key Class::classKey() const
634 { return _key; }
635
636 void Class::setClassKey(Key key)
637 { _key = key; }
638
639 void Class::accept0(TypeVisitor *visitor)
640 { visitor->visit(this); }
641
642 bool Class::matchType0(const Type *otherType, TypeMatcher *matcher) const
643 {
644     if (const Class *otherTy = otherType->asClassType())
645         return matcher->match(this, otherTy);
646
647     return false;
648 }
649
650 unsigned Class::baseClassCount() const
651 { return _baseClasses.size(); }
652
653 BaseClass *Class::baseClassAt(unsigned index) const
654 { return _baseClasses.at(index); }
655
656 void Class::addBaseClass(BaseClass *baseClass)
657 { _baseClasses.push_back(baseClass); }
658
659 FullySpecifiedType Class::type() const
660 { return FullySpecifiedType(const_cast<Class *>(this)); }
661
662 bool Class::isEqualTo(const Type *other) const
663 {
664     const Class *o = other->asClassType();
665     if (! o)
666         return false;
667     const Name *l = unqualifiedName();
668     const Name *r = o->unqualifiedName();
669     if (l == r || (l && l->isEqualTo(r)))
670         return true;
671     else
672         return false;
673 }
674
675 void Class::visitSymbol0(SymbolVisitor *visitor)
676 {
677     if (visitor->visit(this)) {
678         for (unsigned i = 0; i < _baseClasses.size(); ++i) {
679             visitSymbol(_baseClasses.at(i), visitor);
680         }
681         for (unsigned i = 0; i < memberCount(); ++i) {
682             visitSymbol(memberAt(i), visitor);
683         }
684     }
685 }
686
687
688 QtPropertyDeclaration::QtPropertyDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
689     : Symbol(translationUnit, sourceLocation, name)
690     , _flags(NoFlags)
691 { }
692
693 QtPropertyDeclaration::~QtPropertyDeclaration()
694 { }
695
696 void QtPropertyDeclaration::setType(const FullySpecifiedType &type)
697 { _type = type; }
698
699 void QtPropertyDeclaration::setFlags(int flags)
700 { _flags = flags; }
701
702 int QtPropertyDeclaration::flags() const
703 { return _flags; }
704
705 FullySpecifiedType QtPropertyDeclaration::type() const
706 { return _type; }
707
708 void QtPropertyDeclaration::visitSymbol0(SymbolVisitor *visitor)
709 { visitor->visit(this); }
710
711
712 QtEnum::QtEnum(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
713     : Symbol(translationUnit, sourceLocation, name)
714 { }
715
716 QtEnum::~QtEnum()
717 { }
718
719 FullySpecifiedType QtEnum::type() const
720 { return FullySpecifiedType(); }
721
722 void QtEnum::visitSymbol0(SymbolVisitor *visitor)
723 { visitor->visit(this); }
724
725
726 ObjCBaseClass::ObjCBaseClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
727     : Symbol(translationUnit, sourceLocation, name)
728 { }
729
730 ObjCBaseClass::~ObjCBaseClass()
731 { }
732
733 FullySpecifiedType ObjCBaseClass::type() const
734 { return FullySpecifiedType(); }
735
736 void ObjCBaseClass::visitSymbol0(SymbolVisitor *visitor)
737 { visitor->visit(this); }
738
739 ObjCBaseProtocol::ObjCBaseProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
740     : Symbol(translationUnit, sourceLocation, name)
741 { }
742
743 ObjCBaseProtocol::~ObjCBaseProtocol()
744 { }
745
746 FullySpecifiedType ObjCBaseProtocol::type() const
747 { return FullySpecifiedType(); }
748
749 void ObjCBaseProtocol::visitSymbol0(SymbolVisitor *visitor)
750 { visitor->visit(this); }
751
752 ObjCClass::ObjCClass(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name):
753     Scope(translationUnit, sourceLocation, name),
754     _categoryName(0),
755     _baseClass(0),
756     _isInterface(false)
757 {
758 }
759
760 ObjCClass::~ObjCClass()
761 {}
762
763 bool ObjCClass::isInterface() const
764 { return _isInterface; }
765
766 void ObjCClass::setInterface(bool isInterface)
767 { _isInterface = isInterface; }
768
769 bool ObjCClass::isCategory() const
770 { return _categoryName != 0; }
771
772 const Name *ObjCClass::categoryName() const
773 { return _categoryName; }
774
775 void ObjCClass::setCategoryName(const Name *categoryName)
776 { _categoryName = categoryName; }
777
778 ObjCBaseClass *ObjCClass::baseClass() const
779 { return _baseClass; }
780
781 void ObjCClass::setBaseClass(ObjCBaseClass *baseClass)
782 { _baseClass = baseClass; }
783
784 unsigned ObjCClass::protocolCount() const
785 { return _protocols.size(); }
786
787 ObjCBaseProtocol *ObjCClass::protocolAt(unsigned index) const
788 { return _protocols.at(index); }
789
790 void ObjCClass::addProtocol(ObjCBaseProtocol *protocol)
791 { _protocols.push_back(protocol); }
792
793 FullySpecifiedType ObjCClass::type() const
794 { return FullySpecifiedType(const_cast<ObjCClass *>(this)); }
795
796 bool ObjCClass::isEqualTo(const Type *other) const
797 {
798     const ObjCClass *o = other->asObjCClassType();
799     if (!o)
800         return false;
801
802     const Name *l = unqualifiedName();
803     const Name *r = o->unqualifiedName();
804     if (l == r || (l && l->isEqualTo(r)))
805         return true;
806     else
807         return false;
808 }
809
810 void ObjCClass::visitSymbol0(SymbolVisitor *visitor)
811 {
812     if (visitor->visit(this)) {
813         if (_baseClass)
814             visitSymbol(_baseClass, visitor);
815
816         for (unsigned i = 0; i < _protocols.size(); ++i)
817             visitSymbol(_protocols.at(i), visitor);
818
819         for (unsigned i = 0; i < memberCount(); ++i)
820             visitSymbol(memberAt(i), visitor);
821     }
822 }
823
824 void ObjCClass::accept0(TypeVisitor *visitor)
825 { visitor->visit(this); }
826
827 bool ObjCClass::matchType0(const Type *otherType, TypeMatcher *matcher) const
828 {
829     if (const ObjCClass *otherTy = otherType->asObjCClassType())
830         return matcher->match(this, otherTy);
831
832     return false;
833 }
834
835 ObjCProtocol::ObjCProtocol(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name):
836         Scope(translationUnit, sourceLocation, name)
837 {
838 }
839
840 ObjCProtocol::~ObjCProtocol()
841 {}
842
843 unsigned ObjCProtocol::protocolCount() const
844 { return _protocols.size(); }
845
846 ObjCBaseProtocol *ObjCProtocol::protocolAt(unsigned index) const
847 { return _protocols.at(index); }
848
849 void ObjCProtocol::addProtocol(ObjCBaseProtocol *protocol)
850 { _protocols.push_back(protocol); }
851
852 FullySpecifiedType ObjCProtocol::type() const
853 { return FullySpecifiedType(const_cast<ObjCProtocol *>(this)); }
854
855 bool ObjCProtocol::isEqualTo(const Type *other) const
856 {
857     const ObjCProtocol *o = other->asObjCProtocolType();
858     if (!o)
859         return false;
860
861     const Name *l = unqualifiedName();
862     const Name *r = o->unqualifiedName();
863     if (l == r || (l && l->isEqualTo(r)))
864         return true;
865     else
866         return false;
867 }
868
869 void ObjCProtocol::visitSymbol0(SymbolVisitor *visitor)
870 {
871     if (visitor->visit(this)) {
872         for (unsigned i = 0; i < _protocols.size(); ++i)
873             visitSymbol(_protocols.at(i), visitor);
874     }
875 }
876
877 void ObjCProtocol::accept0(TypeVisitor *visitor)
878 { visitor->visit(this); }
879
880 bool ObjCProtocol::matchType0(const Type *otherType, TypeMatcher *matcher) const
881 {
882     if (const ObjCProtocol *otherTy = otherType->asObjCProtocolType())
883         return matcher->match(this, otherTy);
884
885     return false;
886 }
887
888 ObjCForwardClassDeclaration::ObjCForwardClassDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation,
889                                                          const Name *name):
890         Symbol(translationUnit, sourceLocation, name)
891 {
892 }
893
894 ObjCForwardClassDeclaration::~ObjCForwardClassDeclaration()
895 {}
896
897 FullySpecifiedType ObjCForwardClassDeclaration::type() const
898 { return FullySpecifiedType(); }
899
900 bool ObjCForwardClassDeclaration::isEqualTo(const Type *other) const
901 {
902     if (const ObjCForwardClassDeclaration *otherFwdClass = other->asObjCForwardClassDeclarationType()) {
903         if (name() == otherFwdClass->name())
904             return true;
905         else if (name() && otherFwdClass->name())
906             return name()->isEqualTo(otherFwdClass->name());
907         else
908             return false;
909     }
910
911     return false;
912 }
913
914 void ObjCForwardClassDeclaration::visitSymbol0(SymbolVisitor *visitor)
915 { visitor->visit(this); }
916
917 void ObjCForwardClassDeclaration::accept0(TypeVisitor *visitor)
918 { visitor->visit(this); }
919
920 bool ObjCForwardClassDeclaration::matchType0(const Type *otherType, TypeMatcher *matcher) const
921 {
922     if (const ObjCForwardClassDeclaration *otherTy = otherType->asObjCForwardClassDeclarationType())
923         return matcher->match(this, otherTy);
924
925     return false;
926 }
927
928 ObjCForwardProtocolDeclaration::ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, unsigned sourceLocation,
929                                                                const Name *name):
930         Symbol(translationUnit, sourceLocation, name)
931 {
932 }
933
934 ObjCForwardProtocolDeclaration::~ObjCForwardProtocolDeclaration()
935 {}
936
937 FullySpecifiedType ObjCForwardProtocolDeclaration::type() const
938 { return FullySpecifiedType(); }
939
940 bool ObjCForwardProtocolDeclaration::isEqualTo(const Type *other) const
941 {
942     if (const ObjCForwardProtocolDeclaration *otherFwdProtocol = other->asObjCForwardProtocolDeclarationType()) {
943         if (name() == otherFwdProtocol->name())
944             return true;
945         else if (name() && otherFwdProtocol->name())
946             return name()->isEqualTo(otherFwdProtocol->name());
947         else
948             return false;
949     }
950
951     return false;
952 }
953
954 void ObjCForwardProtocolDeclaration::visitSymbol0(SymbolVisitor *visitor)
955 { visitor->visit(this); }
956
957 void ObjCForwardProtocolDeclaration::accept0(TypeVisitor *visitor)
958 { visitor->visit(this); }
959
960 bool ObjCForwardProtocolDeclaration::matchType0(const Type *otherType, TypeMatcher *matcher) const
961 {
962     if (const ObjCForwardProtocolDeclaration *otherTy = otherType->asObjCForwardProtocolDeclarationType())
963         return matcher->match(this, otherTy);
964
965     return false;
966 }
967
968 ObjCMethod::ObjCMethod(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
969     : Scope(translationUnit, sourceLocation, name),
970      _flags(0)
971 { }
972
973 ObjCMethod::~ObjCMethod()
974 { }
975
976 bool ObjCMethod::isEqualTo(const Type *other) const
977 {
978     const ObjCMethod *o = other->asObjCMethodType();
979     if (! o)
980         return false;
981
982     const Name *l = unqualifiedName();
983     const Name *r = o->unqualifiedName();
984     if (l == r || (l && l->isEqualTo(r))) {
985         if (argumentCount() != o->argumentCount())
986             return false;
987         else if (! _returnType.isEqualTo(o->_returnType))
988             return false;
989         for (unsigned i = 0; i < argumentCount(); ++i) {
990             Symbol *l = argumentAt(i);
991             Symbol *r = o->argumentAt(i);
992             if (! l->type().isEqualTo(r->type()))
993                 return false;
994         }
995         return true;
996     }
997     return false;
998 }
999
1000 void ObjCMethod::accept0(TypeVisitor *visitor)
1001 { visitor->visit(this); }
1002
1003 bool ObjCMethod::matchType0(const Type *otherType, TypeMatcher *matcher) const
1004 {
1005     if (const ObjCMethod *otherTy = otherType->asObjCMethodType())
1006         return matcher->match(this, otherTy);
1007
1008     return false;
1009 }
1010
1011 FullySpecifiedType ObjCMethod::type() const
1012 { return FullySpecifiedType(const_cast<ObjCMethod *>(this)); }
1013
1014 FullySpecifiedType ObjCMethod::returnType() const
1015 { return _returnType; }
1016
1017 void ObjCMethod::setReturnType(const FullySpecifiedType &returnType)
1018 { _returnType = returnType; }
1019
1020 bool ObjCMethod::hasReturnType() const
1021 {
1022     const FullySpecifiedType ty = returnType();
1023     return ty.isValid() || ty.isSigned() || ty.isUnsigned();
1024 }
1025
1026 unsigned ObjCMethod::argumentCount() const
1027 {
1028     const unsigned c = memberCount();
1029     if (c > 0 && memberAt(c - 1)->isBlock())
1030         return c - 1;
1031     return c;
1032 }
1033
1034 Symbol *ObjCMethod::argumentAt(unsigned index) const
1035 {
1036     return memberAt(index);
1037 }
1038
1039 bool ObjCMethod::hasArguments() const
1040 {
1041     return ! (argumentCount() == 0 ||
1042               (argumentCount() == 1 && argumentAt(0)->type()->isVoidType()));
1043 }
1044
1045 bool ObjCMethod::isVariadic() const
1046 { return f._isVariadic; }
1047
1048 void ObjCMethod::setVariadic(bool isVariadic)
1049 { f._isVariadic = isVariadic; }
1050
1051 void ObjCMethod::visitSymbol0(SymbolVisitor *visitor)
1052 {
1053     if (visitor->visit(this)) {
1054         for (unsigned i = 0; i < memberCount(); ++i) {
1055             visitSymbol(memberAt(i), visitor);
1056         }
1057     }
1058 }
1059
1060 ObjCPropertyDeclaration::ObjCPropertyDeclaration(TranslationUnit *translationUnit,
1061                                                  unsigned sourceLocation,
1062                                                  const Name *name):
1063     Symbol(translationUnit, sourceLocation, name),
1064     _getterName(0),
1065     _setterName(0),
1066     _propertyAttributes(None)
1067 {}
1068
1069 ObjCPropertyDeclaration::~ObjCPropertyDeclaration()
1070 {}
1071
1072 bool ObjCPropertyDeclaration::hasAttribute(int attribute) const
1073 { return _propertyAttributes & attribute; }
1074
1075 void ObjCPropertyDeclaration::setAttributes(int attributes)
1076 { _propertyAttributes = attributes; }
1077
1078 bool ObjCPropertyDeclaration::hasGetter() const
1079 { return hasAttribute(Getter); }
1080
1081 bool ObjCPropertyDeclaration::hasSetter() const
1082 { return hasAttribute(Setter); }
1083
1084 const Name *ObjCPropertyDeclaration::getterName() const
1085 { return _getterName; }
1086
1087 void ObjCPropertyDeclaration::setGetterName(const Name *getterName)
1088 { _getterName = getterName; }
1089
1090 const Name *ObjCPropertyDeclaration::setterName() const
1091 { return _setterName; }
1092
1093 void ObjCPropertyDeclaration::setSetterName(const Name *setterName)
1094 { _setterName = setterName; }
1095
1096 void ObjCPropertyDeclaration::setType(const FullySpecifiedType &type)
1097 { _type = type; }
1098
1099 FullySpecifiedType ObjCPropertyDeclaration::type() const
1100 { return _type; }
1101
1102 void ObjCPropertyDeclaration::visitSymbol0(SymbolVisitor *visitor)
1103 {
1104     if (visitor->visit(this)) {
1105     }
1106 }