1 // Copyright (c) 2008 Roberto Raggi <roberto.raggi@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included in
11 // all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 // THE SOFTWARE.
20 
21 #pragma once
22 
23 #include "CPlusPlusForwardDeclarations.h"
24 #include "Symbol.h"
25 #include "Type.h"
26 #include "FullySpecifiedType.h"
27 #include "Scope.h"
28 #include <vector>
29 
30 namespace CPlusPlus {
31 
32 class StringLiteral;
33 
34 class CPLUSPLUS_EXPORT UsingNamespaceDirective: public Symbol
35 {
36 public:
37     UsingNamespaceDirective(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
38     UsingNamespaceDirective(Clone *clone, Subst *subst, UsingNamespaceDirective *original);
39     virtual ~UsingNamespaceDirective();
40 
41     // Symbol's interface
42     FullySpecifiedType type() const override;
43 
asUsingNamespaceDirective()44     const UsingNamespaceDirective *asUsingNamespaceDirective() const override
45     { return this; }
46 
asUsingNamespaceDirective()47     UsingNamespaceDirective *asUsingNamespaceDirective() override
48     { return this; }
49 
50 protected:
51     void visitSymbol0(SymbolVisitor *visitor) override;
52 };
53 
54 class CPLUSPLUS_EXPORT UsingDeclaration: public Symbol
55 {
56 public:
57     UsingDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
58     UsingDeclaration(Clone *clone, Subst *subst, UsingDeclaration *original);
59     virtual ~UsingDeclaration();
60 
61     // Symbol's interface
62     FullySpecifiedType type() const override;
63 
asUsingDeclaration()64     const UsingDeclaration *asUsingDeclaration() const override
65     { return this; }
66 
asUsingDeclaration()67     UsingDeclaration *asUsingDeclaration() override
68     { return this; }
69 
70 protected:
71     void visitSymbol0(SymbolVisitor *visitor) override;
72 };
73 
74 class CPLUSPLUS_EXPORT NamespaceAlias: public Symbol
75 {
76 public:
77     NamespaceAlias(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
78     NamespaceAlias(Clone *clone, Subst *subst, NamespaceAlias *original);
79     virtual ~NamespaceAlias();
80 
81     const Name *namespaceName() const;
82     void setNamespaceName(const Name *namespaceName);
83 
84     // Symbol's interface
85     FullySpecifiedType type() const override;
86 
asNamespaceAlias()87     const NamespaceAlias *asNamespaceAlias() const override
88     { return this; }
89 
asNamespaceAlias()90     NamespaceAlias *asNamespaceAlias() override
91     { return this; }
92 
93 protected:
94     void visitSymbol0(SymbolVisitor *visitor) override;
95 
96 private:
97     const Name *_namespaceName;
98 };
99 
100 class CPLUSPLUS_EXPORT Declaration: public Symbol
101 {
102 public:
103     Declaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
104     Declaration(Clone *clone, Subst *subst, Declaration *original);
105     virtual ~Declaration();
106 
107     void setType(const FullySpecifiedType &type);
108     void setInitializer(StringLiteral const* initializer);
109 
110     // Symbol's interface
111     FullySpecifiedType type() const override;
112     const StringLiteral *getInitializer() const;
113 
asDeclaration()114     const Declaration *asDeclaration() const override
115     { return this; }
116 
asDeclaration()117     Declaration *asDeclaration() override
118     { return this; }
119 
asEnumeratorDeclarator()120     virtual EnumeratorDeclaration *asEnumeratorDeclarator()
121     { return nullptr; }
122 
asEnumeratorDeclarator()123     virtual const EnumeratorDeclaration *asEnumeratorDeclarator() const
124     { return nullptr; }
125 
126 protected:
127     void visitSymbol0(SymbolVisitor *visitor) override;
128 
129 private:
130     FullySpecifiedType _type;
131     const StringLiteral *_initializer;
132 };
133 
134 class CPLUSPLUS_EXPORT EnumeratorDeclaration: public Declaration
135 {
136 public:
137     EnumeratorDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
138     virtual ~EnumeratorDeclaration();
139 
140     const StringLiteral *constantValue() const;
141     void setConstantValue(const StringLiteral *constantValue);
142 
asEnumeratorDeclarator()143     EnumeratorDeclaration *asEnumeratorDeclarator() override
144     { return this; }
145 
asEnumeratorDeclarator()146     const EnumeratorDeclaration *asEnumeratorDeclarator() const override
147     { return this; }
148 
149 private:
150     const StringLiteral *_constantValue;
151 };
152 
153 class CPLUSPLUS_EXPORT Argument: public Symbol
154 {
155 public:
156     Argument(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
157     Argument(Clone *clone, Subst *subst, Argument *original);
158     virtual ~Argument();
159 
160     void setType(const FullySpecifiedType &type);
161 
162     bool hasInitializer() const;
163 
164     const StringLiteral *initializer() const;
165     void setInitializer(const StringLiteral *initializer);
166 
167     // Symbol's interface
168     FullySpecifiedType type() const override;
169 
asArgument()170     const Argument *asArgument() const override
171     { return this; }
172 
asArgument()173     Argument *asArgument() override
174     { return this; }
175 
176 protected:
177     void visitSymbol0(SymbolVisitor *visitor) override;
178 
179 private:
180     const StringLiteral *_initializer;
181     FullySpecifiedType _type;
182 };
183 
184 class CPLUSPLUS_EXPORT TypenameArgument: public Symbol
185 {
186 public:
187     TypenameArgument(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
188     TypenameArgument(Clone *clone, Subst *subst, TypenameArgument *original);
189     virtual ~TypenameArgument();
190 
191     void setType(const FullySpecifiedType &type);
setClassDeclarator(bool isClassDecl)192     void setClassDeclarator(bool isClassDecl) { _isClassDeclarator = isClassDecl; }
isClassDeclarator()193     bool isClassDeclarator() const { return _isClassDeclarator; }
194 
195     // Symbol's interface
196     FullySpecifiedType type() const override;
197 
asTypenameArgument()198     const TypenameArgument *asTypenameArgument() const override
199     { return this; }
200 
asTypenameArgument()201     TypenameArgument *asTypenameArgument() override
202     { return this; }
203 
204 protected:
205     void visitSymbol0(SymbolVisitor *visitor) override;
206 
207 private:
208     FullySpecifiedType _type;
209     bool _isClassDeclarator;
210 };
211 
212 class CPLUSPLUS_EXPORT Block: public Scope
213 {
214 public:
215     Block(TranslationUnit *translationUnit, int sourceLocation);
216     Block(Clone *clone, Subst *subst, Block *original);
217     virtual ~Block();
218 
219     // Symbol's interface
220     FullySpecifiedType type() const override;
221 
asBlock()222     const Block *asBlock() const override
223     { return this; }
224 
asBlock()225     Block *asBlock() override
226     { return this; }
227 
228 protected:
229     void visitSymbol0(SymbolVisitor *visitor) override;
230 };
231 
232 class CPLUSPLUS_EXPORT ForwardClassDeclaration: public Symbol, public Type
233 {
234 public:
235     ForwardClassDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
236     ForwardClassDeclaration(Clone *clone, Subst *subst, ForwardClassDeclaration *original);
237     virtual ~ForwardClassDeclaration();
238 
239     // Symbol's interface
240     FullySpecifiedType type() const override;
241 
asForwardClassDeclaration()242     const ForwardClassDeclaration *asForwardClassDeclaration() const override
243     { return this; }
244 
asForwardClassDeclaration()245     ForwardClassDeclaration *asForwardClassDeclaration() override
246     { return this; }
247 
248     // Type's interface
asForwardClassDeclarationType()249     const ForwardClassDeclaration *asForwardClassDeclarationType() const override
250     { return this; }
251 
asForwardClassDeclarationType()252     ForwardClassDeclaration *asForwardClassDeclarationType() override
253     { return this; }
254 
255 protected:
256     void visitSymbol0(SymbolVisitor *visitor) override;
257     void accept0(TypeVisitor *visitor) override;
258     bool match0(const Type *otherType, Matcher *matcher) const override;
259 };
260 
261 class CPLUSPLUS_EXPORT Enum: public Scope, public Type
262 {
263 public:
264     Enum(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
265     Enum(Clone *clone, Subst *subst, Enum *original);
266     virtual ~Enum();
267 
268     bool isScoped() const;
269     void setScoped(bool scoped);
270 
271     // Symbol's interface
272     FullySpecifiedType type() const override;
273 
asEnum()274     const Enum *asEnum() const override
275     { return this; }
276 
asEnum()277     Enum *asEnum() override
278     { return this; }
279 
280     // Type's interface
asEnumType()281     const Enum *asEnumType() const override
282     { return this; }
283 
asEnumType()284     Enum *asEnumType() override
285     { return this; }
286 
287 protected:
288     void visitSymbol0(SymbolVisitor *visitor) override;
289     void accept0(TypeVisitor *visitor) override;
290     bool match0(const Type *otherType, Matcher *matcher) const override;
291 
292 private:
293     bool _isScoped;
294 };
295 
296 class CPLUSPLUS_EXPORT Function: public Scope, public Type
297 {
298 public:
299     enum MethodKey {
300         NormalMethod,
301         SlotMethod,
302         SignalMethod,
303         InvokableMethod
304     };
305 
306     enum RefQualifier {
307         NoRefQualifier, // a function declared w/o & and && => *this may be lvalue or rvalue
308         LvalueRefQualifier, // a function declared with & => *this is lvalue
309         RvalueRefQualifier // a function declared with && => *this is rvalue
310     };
311 
312 public:
313     Function(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
314     Function(Clone *clone, Subst *subst, Function *original);
315     virtual ~Function();
316 
317     bool isNormal() const;
318     bool isSignal() const;
319     bool isSlot() const;
320     bool isInvokable() const;
321     int methodKey() const;
322     void setMethodKey(int key);
323 
324     FullySpecifiedType returnType() const;
325     void setReturnType(const FullySpecifiedType &returnType);
326 
327     /** Convenience function that returns whether the function returns something (including void). */
328     bool hasReturnType() const;
329 
330     int argumentCount() const;
331     Symbol *argumentAt(int index) const;
332 
333     /** Convenience function that returns whether the function receives any arguments. */
334     bool hasArguments() const;
335     int minimumArgumentCount() const;
336 
337     bool isVirtual() const;
338     void setVirtual(bool isVirtual);
339 
340     bool isOverride() const;
341     void setOverride(bool isOverride);
342 
343     bool isFinal() const;
344     void setFinal(bool isFinal);
345 
346     bool isVariadic() const;
347     void setVariadic(bool isVariadic);
348 
349     bool isVariadicTemplate() const;
350     void setVariadicTemplate(bool isVariadicTemplate);
351 
352     bool isConst() const;
353     void setConst(bool isConst);
354 
isStatic()355     bool isStatic() const { return f._isStatic; }
setStatic(bool isStatic)356     void setStatic(bool isStatic) { f._isStatic = isStatic; }
357 
358     bool isVolatile() const;
359     void setVolatile(bool isVolatile);
360 
361     bool isPureVirtual() const;
362     void setPureVirtual(bool isPureVirtual);
363 
364     RefQualifier refQualifier() const;
365     void setRefQualifier(RefQualifier refQualifier);
366 
367     bool isSignatureEqualTo(const Function *other, Matcher *matcher = nullptr) const;
368 
369     bool isAmbiguous() const; // internal
370     void setAmbiguous(bool isAmbiguous); // internal
371 
372     bool maybeValidPrototype(int actualArgumentCount) const;
373 
374     const StringLiteral *exceptionSpecification();
375     void setExceptionSpecification(const StringLiteral *spec);
376 
377     // Symbol's interface
378     FullySpecifiedType type() const override;
379 
asFunction()380     const Function *asFunction() const override
381     { return this; }
382 
asFunction()383     Function *asFunction() override
384     { return this; }
385 
386     // Type's interface
asFunctionType()387     const Function *asFunctionType() const override
388     { return this; }
389 
asFunctionType()390     Function *asFunctionType() override
391     { return this; }
392 
393 protected:
394     void visitSymbol0(SymbolVisitor *visitor) override;
395     void accept0(TypeVisitor *visitor) override;
396     bool match0(const Type *otherType, Matcher *matcher) const override;
397 
398 private:
399     FullySpecifiedType _returnType;
400     const StringLiteral *_exceptionSpecification = nullptr;
401     struct Flags {
402         unsigned _isVirtual: 1;
403         unsigned _isOverride: 1;
404         unsigned _isFinal: 1;
405         unsigned _isStatic: 1;
406         unsigned _isVariadic: 1;
407         unsigned _isVariadicTemplate: 1;
408         unsigned _isPureVirtual: 1;
409         unsigned _isConst: 1;
410         unsigned _isVolatile: 1;
411         unsigned _isAmbiguous: 1;
412         unsigned _methodKey: 3;
413         unsigned _refQualifier: 2;
414     };
415     union {
416         unsigned _flags;
417         Flags f;
418     };
419 };
420 
421 class CPLUSPLUS_EXPORT Template: public Scope, public Type
422 {
423 public:
424     Template(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
425     Template(Clone *clone, Subst *subst, Template *original);
426     virtual ~Template();
427 
428     int templateParameterCount() const;
429     Symbol *templateParameterAt(int index) const;
430     Symbol *declaration() const;
431 
432     // Symbol's interface
433     FullySpecifiedType type() const override;
434 
asTemplate()435     const Template *asTemplate() const override
436     { return this; }
437 
asTemplate()438     Template *asTemplate() override
439     { return this; }
440 
441     // Type's interface
asTemplateType()442     const Template *asTemplateType() const override
443     { return this; }
444 
asTemplateType()445     Template *asTemplateType() override
446     { return this; }
447 
448 protected:
449     void visitSymbol0(SymbolVisitor *visitor) override;
450     void accept0(TypeVisitor *visitor) override;
451     bool match0(const Type *otherType, Matcher *matcher) const override;
452 };
453 
454 
455 class CPLUSPLUS_EXPORT Namespace: public Scope, public Type
456 {
457 public:
458     Namespace(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
459     Namespace(Clone *clone, Subst *subst, Namespace *original);
460     virtual ~Namespace();
461 
462     // Symbol's interface
463     FullySpecifiedType type() const override;
464 
asNamespace()465     const Namespace *asNamespace() const override
466     { return this; }
467 
asNamespace()468     Namespace *asNamespace() override
469     { return this; }
470 
471     // Type's interface
asNamespaceType()472     const Namespace *asNamespaceType() const override
473     { return this; }
474 
asNamespaceType()475     Namespace *asNamespaceType() override
476     { return this; }
477 
isInline()478     bool isInline() const
479     { return _isInline; }
480 
setInline(bool onoff)481     void setInline(bool onoff)
482     { _isInline = onoff; }
483 
484 protected:
485     void visitSymbol0(SymbolVisitor *visitor) override;
486     void accept0(TypeVisitor *visitor) override;
487     bool match0(const Type *otherType, Matcher *matcher) const override;
488 
489 private:
490     bool _isInline;
491 };
492 
493 class CPLUSPLUS_EXPORT BaseClass: public Symbol
494 {
495 public:
496     BaseClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
497     BaseClass(Clone *clone, Subst *subst, BaseClass *original);
498     virtual ~BaseClass();
499 
500     bool isVirtual() const;
501     void setVirtual(bool isVirtual);
502 
503     bool isVariadic() const;
504     void setVariadic(bool isVariadic);
505 
506     // Symbol's interface
507     FullySpecifiedType type() const override;
508     void setType(const FullySpecifiedType &type);
509 
asBaseClass()510     const BaseClass *asBaseClass() const override
511     { return this; }
512 
asBaseClass()513     BaseClass *asBaseClass() override
514     { return this; }
515 
516 protected:
517     void visitSymbol0(SymbolVisitor *visitor) override;
518 
519 private:
520     bool _isVariadic = false;
521     bool _isVirtual;
522     FullySpecifiedType _type;
523 };
524 
525 class CPLUSPLUS_EXPORT Class: public Scope, public Type
526 {
527 public:
528     Class(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
529     Class(Clone *clone, Subst *subst, Class *original);
530     virtual ~Class();
531 
532     enum Key {
533         ClassKey,
534         StructKey,
535         UnionKey
536     };
537 
538     bool isClass() const;
539     bool isStruct() const;
540     bool isUnion() const;
541     Key classKey() const;
542     void setClassKey(Key key);
543 
544     int baseClassCount() const;
545     BaseClass *baseClassAt(int index) const;
546     void addBaseClass(BaseClass *baseClass);
baseClasses()547     const std::vector<BaseClass *> &baseClasses() const { return _baseClasses; }
548 
549     // Symbol's interface
550     FullySpecifiedType type() const override;
551 
asClass()552     const Class *asClass() const override
553     { return this; }
554 
asClass()555     Class *asClass() override
556     { return this; }
557 
558     // Type's interface
asClassType()559     const Class *asClassType() const override
560     { return this; }
561 
asClassType()562     Class *asClassType() override
563     { return this; }
564 
565 protected:
566     void visitSymbol0(SymbolVisitor *visitor) override;
567     void accept0(TypeVisitor *visitor) override;
568     bool match0(const Type *otherType, Matcher *matcher) const override;
569 
570 private:
571     Key _key;
572     std::vector<BaseClass *> _baseClasses;
573 };
574 
575 class CPLUSPLUS_EXPORT QtPropertyDeclaration: public Symbol
576 {
577 public:
578     enum Flag {
579         NoFlags = 0,
580         ReadFunction = 1 << 0,
581         WriteFunction = 1 << 1,
582         MemberVariable = 1 << 2,
583         ResetFunction = 1 << 3,
584         NotifyFunction = 1 << 4,
585         DesignableFlag = 1 << 5,
586         DesignableFunction = 1 << 6,
587         ScriptableFlag = 1 << 7,
588         ScriptableFunction = 1 << 8,
589         StoredFlag = 1 << 9,
590         StoredFunction = 1 << 10,
591         UserFlag = 1 << 11,
592         UserFunction = 1 << 12,
593         ConstantFlag = 1 << 13,
594         FinalFlag = 1 << 14
595     };
596 
597 public:
598     QtPropertyDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
599     QtPropertyDeclaration(Clone *clone, Subst *subst, QtPropertyDeclaration *original);
600     virtual ~QtPropertyDeclaration();
601 
602     void setType(const FullySpecifiedType &type);
603 
604     void setFlags(int flags);
605     int flags() const;
606 
607     // Symbol's interface
608     FullySpecifiedType type() const override;
609 
asQtPropertyDeclaration()610     const QtPropertyDeclaration *asQtPropertyDeclaration() const override
611     { return this; }
612 
asQtPropertyDeclaration()613     QtPropertyDeclaration *asQtPropertyDeclaration() override
614     { return this; }
615 
616 protected:
617     void visitSymbol0(SymbolVisitor *visitor) override;
618 
619 private:
620     FullySpecifiedType _type;
621     int _flags;
622 };
623 
624 class CPLUSPLUS_EXPORT QtEnum: public Symbol
625 {
626 public:
627     QtEnum(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
628     QtEnum(Clone *clone, Subst *subst, QtEnum *original);
629     virtual ~QtEnum();
630 
631     // Symbol's interface
632     FullySpecifiedType type() const override;
633 
asQtEnum()634     const QtEnum *asQtEnum() const override
635     { return this; }
636 
asQtEnum()637     QtEnum *asQtEnum() override
638     { return this; }
639 
640 protected:
641     void visitSymbol0(SymbolVisitor *visitor) override;
642 };
643 
644 class CPLUSPLUS_EXPORT ObjCBaseClass: public Symbol
645 {
646 public:
647     ObjCBaseClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
648     ObjCBaseClass(Clone *clone, Subst *subst, ObjCBaseClass *original);
649     virtual ~ObjCBaseClass();
650 
651     // Symbol's interface
652     FullySpecifiedType type() const override;
653 
asObjCBaseClass()654     const ObjCBaseClass *asObjCBaseClass() const override
655     { return this; }
656 
asObjCBaseClass()657     ObjCBaseClass *asObjCBaseClass() override
658     { return this; }
659 
660 protected:
661     void visitSymbol0(SymbolVisitor *visitor) override;
662 };
663 
664 class CPLUSPLUS_EXPORT ObjCBaseProtocol: public Symbol
665 {
666 public:
667     ObjCBaseProtocol(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
668     ObjCBaseProtocol(Clone *clone, Subst *subst, ObjCBaseProtocol *original);
669     virtual ~ObjCBaseProtocol();
670 
671     // Symbol's interface
672     FullySpecifiedType type() const override;
673 
asObjCBaseProtocol()674     const ObjCBaseProtocol *asObjCBaseProtocol() const override
675     { return this; }
676 
asObjCBaseProtocol()677     ObjCBaseProtocol *asObjCBaseProtocol() override
678     { return this; }
679 
680 protected:
681     void visitSymbol0(SymbolVisitor *visitor) override;
682 };
683 
684 class CPLUSPLUS_EXPORT ObjCForwardProtocolDeclaration: public Symbol, public Type
685 {
686 public:
687     ObjCForwardProtocolDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
688     ObjCForwardProtocolDeclaration(Clone *clone, Subst *subst, ObjCForwardProtocolDeclaration *original);
689     virtual ~ObjCForwardProtocolDeclaration();
690 
691     // Symbol's interface
692     FullySpecifiedType type() const override;
693 
asObjCForwardProtocolDeclaration()694     const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const override
695     { return this; }
696 
asObjCForwardProtocolDeclaration()697     ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() override
698     { return this; }
699 
700     // Type's interface
asObjCForwardProtocolDeclarationType()701     const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() const override
702     { return this; }
703 
asObjCForwardProtocolDeclarationType()704     ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclarationType() override
705     { return this; }
706 
707 protected:
708     void visitSymbol0(SymbolVisitor *visitor) override;
709     void accept0(TypeVisitor *visitor) override;
710     bool match0(const Type *otherType, Matcher *matcher) const override;
711 };
712 
713 class CPLUSPLUS_EXPORT ObjCProtocol: public Scope, public Type
714 {
715 public:
716     ObjCProtocol(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
717     ObjCProtocol(Clone *clone, Subst *subst, ObjCProtocol *original);
718     virtual ~ObjCProtocol();
719 
720     int protocolCount() const;
721     ObjCBaseProtocol *protocolAt(int index) const;
722     void addProtocol(ObjCBaseProtocol *protocol);
723 
724     // Symbol's interface
725     FullySpecifiedType type() const override;
726 
asObjCProtocol()727     const ObjCProtocol *asObjCProtocol() const override
728     { return this; }
729 
asObjCProtocol()730     ObjCProtocol *asObjCProtocol() override
731     { return this; }
732 
733     // Type's interface
asObjCProtocolType()734     const ObjCProtocol *asObjCProtocolType() const override
735     { return this; }
736 
asObjCProtocolType()737     ObjCProtocol *asObjCProtocolType() override
738     { return this; }
739 
740 protected:
741     void visitSymbol0(SymbolVisitor *visitor) override;
742     void accept0(TypeVisitor *visitor) override;
743     bool match0(const Type *otherType, Matcher *matcher) const override;
744 
745 private:
746     std::vector<ObjCBaseProtocol *> _protocols;
747 };
748 
749 class CPLUSPLUS_EXPORT ObjCForwardClassDeclaration: public Symbol, public Type
750 {
751 public:
752     ObjCForwardClassDeclaration(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
753     ObjCForwardClassDeclaration(Clone *clone, Subst *subst, ObjCForwardClassDeclaration *original);
754     virtual ~ObjCForwardClassDeclaration();
755 
756     // Symbol's interface
757     FullySpecifiedType type() const override;
758 
asObjCForwardClassDeclaration()759     const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const override
760     { return this; }
761 
asObjCForwardClassDeclaration()762     ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() override
763     { return this; }
764 
765     // Type's interface
asObjCForwardClassDeclarationType()766     const ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() const override
767     { return this; }
768 
asObjCForwardClassDeclarationType()769     ObjCForwardClassDeclaration *asObjCForwardClassDeclarationType() override
770     { return this; }
771 
772 protected:
773     void visitSymbol0(SymbolVisitor *visitor) override;
774     void accept0(TypeVisitor *visitor) override;
775     bool match0(const Type *otherType, Matcher *matcher) const override;
776 };
777 
778 class CPLUSPLUS_EXPORT ObjCClass: public Scope, public Type
779 {
780 public:
781     ObjCClass(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
782     ObjCClass(Clone *clone, Subst *subst, ObjCClass *original);
783     virtual ~ObjCClass();
784 
785     bool isInterface() const;
786     void setInterface(bool isInterface);
787 
788     bool isCategory() const;
789     const Name *categoryName() const;
790     void setCategoryName(const Name *categoryName);
791 
792     ObjCBaseClass *baseClass() const;
793     void setBaseClass(ObjCBaseClass *baseClass);
794 
795     int protocolCount() const;
796     ObjCBaseProtocol *protocolAt(int index) const;
797     void addProtocol(ObjCBaseProtocol *protocol);
798 
799     // Symbol's interface
800     FullySpecifiedType type() const override;
801 
asObjCClass()802     const ObjCClass *asObjCClass() const override
803     { return this; }
804 
asObjCClass()805     ObjCClass *asObjCClass() override
806     { return this; }
807 
808     // Type's interface
asObjCClassType()809     const ObjCClass *asObjCClassType() const override
810     { return this; }
811 
asObjCClassType()812     ObjCClass *asObjCClassType() override
813     { return this; }
814 
815 protected:
816     void visitSymbol0(SymbolVisitor *visitor) override;
817     void accept0(TypeVisitor *visitor) override;
818     bool match0(const Type *otherType, Matcher *matcher) const override;
819 
820 private:
821     const Name *_categoryName;
822     ObjCBaseClass * _baseClass;
823     std::vector<ObjCBaseProtocol *> _protocols;
824     bool _isInterface;
825 };
826 
827 class CPLUSPLUS_EXPORT ObjCMethod: public Scope, public Type
828 {
829 public:
830     ObjCMethod(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
831     ObjCMethod(Clone *clone, Subst *subst, ObjCMethod *original);
832     virtual ~ObjCMethod();
833 
834     FullySpecifiedType returnType() const;
835     void setReturnType(const FullySpecifiedType &returnType);
836 
837     /** Convenience function that returns whether the function returns something (including void). */
838     bool hasReturnType() const;
839 
840     int argumentCount() const;
841     Symbol *argumentAt(int index) const;
842 
843     /** Convenience function that returns whether the function receives any arguments. */
844     bool hasArguments() const;
845 
846     bool isVariadic() const;
847     void setVariadic(bool isVariadic);
848 
849     // Symbol's interface
850     FullySpecifiedType type() const override;
851 
asObjCMethod()852     const ObjCMethod *asObjCMethod() const override
853     { return this; }
854 
asObjCMethod()855     ObjCMethod *asObjCMethod() override
856     { return this; }
857 
858     // Type's interface
asObjCMethodType()859     const ObjCMethod *asObjCMethodType() const override
860     { return this; }
861 
asObjCMethodType()862     ObjCMethod *asObjCMethodType() override
863     { return this; }
864 
865 protected:
866     void visitSymbol0(SymbolVisitor *visitor) override;
867     void accept0(TypeVisitor *visitor) override;
868     bool match0(const Type *otherType, Matcher *matcher) const override;
869 
870 private:
871     FullySpecifiedType _returnType;
872     struct Flags {
873         unsigned _isVariadic: 1;
874     };
875     union {
876         unsigned _flags;
877         Flags f;
878     };
879 };
880 
881 class CPLUSPLUS_EXPORT ObjCPropertyDeclaration: public Symbol
882 {
883 public:
884     enum PropertyAttributes {
885         None = 0,
886         Assign = 1 << 0,
887         Retain = 1 << 1,
888         Copy = 1 << 2,
889         ReadOnly = 1 << 3,
890         ReadWrite = 1 << 4,
891         Getter = 1 << 5,
892         Setter = 1 << 6,
893         NonAtomic = 1 << 7,
894 
895         WritabilityMask = ReadOnly | ReadWrite,
896         SetterSemanticsMask = Assign | Retain | Copy
897     };
898 
899 public:
900     ObjCPropertyDeclaration(TranslationUnit *translationUnit,
901                             int sourceLocation,
902                             const Name *name);
903     ObjCPropertyDeclaration(Clone *clone, Subst *subst, ObjCPropertyDeclaration *original);
904     virtual ~ObjCPropertyDeclaration();
905 
906     bool hasAttribute(int attribute) const;
907     void setAttributes(int attributes);
908 
909     bool hasGetter() const;
910     bool hasSetter() const;
911 
912     const Name *getterName() const;
913 
914     void setGetterName(const Name *getterName);
915 
916     const Name *setterName() const;
917     void setSetterName(const Name *setterName);
918 
919     void setType(const FullySpecifiedType &type);
920 
921     // Symbol's interface
922     FullySpecifiedType type() const override;
923 
asObjCPropertyDeclaration()924     const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const override
925     { return this; }
926 
asObjCPropertyDeclaration()927     ObjCPropertyDeclaration *asObjCPropertyDeclaration() override
928     { return this; }
929 
930 protected:
931     void visitSymbol0(SymbolVisitor *visitor) override;
932 
933 private:
934     const Name *_getterName;
935     const Name *_setterName;
936     FullySpecifiedType _type;
937     int _propertyAttributes;
938 };
939 
940 } // namespace CPlusPlus
941