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 
25 namespace Utils { class Link; }
26 
27 namespace CPlusPlus {
28 
29 class CPLUSPLUS_EXPORT Symbol
30 {
31     Symbol(const Symbol &other);
32     void operator =(const Symbol &other);
33 
34 public:
35     /// Storage class specifier
36     enum Storage {
37         NoStorage = 0,
38         Friend,
39         Auto,
40         Register,
41         Static,
42         Extern,
43         Mutable,
44         Typedef
45     };
46 
47     /// Access specifier.
48     enum Visibility {
49         Public,
50         Protected,
51         Private,
52         Package
53     };
54 
55 public:
56     /// Constructs a Symbol with the given source location, name and translation unit.
57     Symbol(TranslationUnit *translationUnit, int sourceLocation, const Name *name);
58     Symbol(Clone *clone, Subst *subst, Symbol *original);
59 
60     /// Destroy this Symbol.
61     virtual ~Symbol();
62 
63     /// Returns this Symbol's source location.
64     int sourceLocation() const;
65 
66     /// \returns this Symbol's line number. The line number is 1-based.
67     int line() const;
68 
69     /// \returns this Symbol's column number. The column number is 1-based.
70     int column() const;
71 
72     /// Returns this Symbol's file name.
73     const StringLiteral *fileId() const;
74 
75     /// Returns this Symbol's file name.
76     const char *fileName() const;
77 
78     /// Returns this Symbol's file name length.
79     int fileNameLength() const;
80 
81     /// Returns this Symbol's name.
82     const Name *name() const;
83 
84     /// Sets this Symbol's name.
85     void setName(const Name *name); // ### dangerous
86 
87     /// Returns this Symbol's (optional) identifier
88     const Identifier *identifier() const;
89 
90     /// Returns this Symbol's storage class specifier.
91     int storage() const;
92 
93     /// Sets this Symbol's storage class specifier.
94     void setStorage(int storage);
95 
96     /// Returns this Symbol's visibility.
97     int visibility() const;
98 
99     /// Sets this Symbol's visibility.
100     void setVisibility(int visibility);
101 
102     /// Returns the next chained Symbol.
103     Symbol *next() const;
104 
105     /// Returns true if this Symbol has friend storage specifier.
106     bool isFriend() const;
107 
108     /// Returns true if this Symbol has register storage specifier.
109     bool isRegister() const;
110 
111     /// Returns true if this Symbol has static storage specifier.
112     bool isStatic() const;
113 
114     /// Returns true if this Symbol has extern storage specifier.
115     bool isExtern() const;
116 
117     /// Returns true if this Symbol has mutable storage specifier.
118     bool isMutable() const;
119 
120     /// Returns true if this Symbol has typedef storage specifier.
121     bool isTypedef() const;
122 
123     /// Returns true if this Symbol's visibility is public.
124     bool isPublic() const;
125 
126     /// Returns true if this Symbol's visibility is protected.
127     bool isProtected() const;
128 
129     /// Returns true if this Symbol's visibility is private.
130     bool isPrivate() const;
131 
132     /// Returns true if this Symbol is a Scope.
133     bool isScope() const;
134 
135     /// Returns true if this Symbol is an Enum.
136     bool isEnum() const;
137 
138     /// Returns true if this Symbol is an Function.
139     bool isFunction() const;
140 
141     /// Returns true if this Symbol is a Namespace.
142     bool isNamespace() const;
143 
144     /// Returns true if this Symbol is a Template.
145     bool isTemplate() const;
146 
147     /// Returns true if this Symbol is a Class.
148     bool isClass() const;
149 
150     /// Returns true if this Symbol is a Block.
151     bool isBlock() const;
152 
153     /// Returns true if this Symbol is a UsingNamespaceDirective.
154     bool isUsingNamespaceDirective() const;
155 
156     /// Returns true if this Symbol is a UsingDeclaration.
157     bool isUsingDeclaration() const;
158 
159     /// Returns true if this Symbol is a Declaration.
160     bool isDeclaration() const;
161 
162     /// Returns true if this Symbol is an Argument.
163     bool isArgument() const;
164 
165     /// Returns true if this Symbol is a Typename argument.
166     bool isTypenameArgument() const;
167 
168     /// Returns true if this Symbol is a BaseClass.
169     bool isBaseClass() const;
170 
171     /// Returns true if this Symbol is a ForwardClassDeclaration.
172     bool isForwardClassDeclaration() const;
173 
174     /// Returns true if this Symbol is a QtPropertyDeclaration.
175     bool isQtPropertyDeclaration() const;
176 
177     /// Returns true if this Symbol is a QtEnum.
178     bool isQtEnum() const;
179 
180     bool isObjCBaseClass() const;
181     bool isObjCBaseProtocol() const;
182 
183     /// Returns true if this Symbol is an Objective-C Class declaration.
184     bool isObjCClass() const;
185 
186     /// Returns true if this Symbol is an Objective-C Class forward declaration.
187     bool isObjCForwardClassDeclaration() const;
188 
189     /// Returns true if this Symbol is an Objective-C Protocol declaration.
190     bool isObjCProtocol() const;
191 
192     /// Returns true if this Symbol is an Objective-C Protocol forward declaration.
193     bool isObjCForwardProtocolDeclaration() const;
194 
195     /// Returns true if this Symbol is an Objective-C method declaration.
196     bool isObjCMethod() const;
197 
198     /// Returns true if this Symbol is an Objective-C @property declaration.
199     bool isObjCPropertyDeclaration() const;
200 
201     Utils::Link toLink() const;
202 
asScope()203     virtual const Scope *asScope() const { return nullptr; }
asEnum()204     virtual const Enum *asEnum() const { return nullptr; }
asFunction()205     virtual const Function *asFunction() const { return nullptr; }
asNamespace()206     virtual const Namespace *asNamespace() const { return nullptr; }
asTemplate()207     virtual const Template *asTemplate() const { return nullptr; }
asNamespaceAlias()208     virtual const NamespaceAlias *asNamespaceAlias() const { return nullptr; }
asClass()209     virtual const Class *asClass() const { return nullptr; }
asBlock()210     virtual const Block *asBlock() const { return nullptr; }
asUsingNamespaceDirective()211     virtual const UsingNamespaceDirective *asUsingNamespaceDirective() const { return nullptr; }
asUsingDeclaration()212     virtual const UsingDeclaration *asUsingDeclaration() const { return nullptr; }
asDeclaration()213     virtual const Declaration *asDeclaration() const { return nullptr; }
asArgument()214     virtual const Argument *asArgument() const { return nullptr; }
asTypenameArgument()215     virtual const TypenameArgument *asTypenameArgument() const { return nullptr; }
asBaseClass()216     virtual const BaseClass *asBaseClass() const { return nullptr; }
asForwardClassDeclaration()217     virtual const ForwardClassDeclaration *asForwardClassDeclaration() const { return nullptr; }
asQtPropertyDeclaration()218     virtual const QtPropertyDeclaration *asQtPropertyDeclaration() const { return nullptr; }
asQtEnum()219     virtual const QtEnum *asQtEnum() const { return nullptr; }
asObjCBaseClass()220     virtual const ObjCBaseClass *asObjCBaseClass() const { return nullptr; }
asObjCBaseProtocol()221     virtual const ObjCBaseProtocol *asObjCBaseProtocol() const { return nullptr; }
asObjCClass()222     virtual const ObjCClass *asObjCClass() const { return nullptr; }
asObjCForwardClassDeclaration()223     virtual const ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() const { return nullptr; }
asObjCProtocol()224     virtual const ObjCProtocol *asObjCProtocol() const { return nullptr; }
asObjCForwardProtocolDeclaration()225     virtual const ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() const { return nullptr; }
asObjCMethod()226     virtual const ObjCMethod *asObjCMethod() const { return nullptr; }
asObjCPropertyDeclaration()227     virtual const ObjCPropertyDeclaration *asObjCPropertyDeclaration() const { return nullptr; }
228 
asScope()229     virtual Scope *asScope() { return nullptr; }
asEnum()230     virtual Enum *asEnum() { return nullptr; }
asFunction()231     virtual Function *asFunction() { return nullptr; }
asNamespace()232     virtual Namespace *asNamespace() { return nullptr; }
asTemplate()233     virtual Template *asTemplate() { return nullptr; }
asNamespaceAlias()234     virtual NamespaceAlias *asNamespaceAlias() { return nullptr; }
asClass()235     virtual Class *asClass() { return nullptr; }
asBlock()236     virtual Block *asBlock() { return nullptr; }
asUsingNamespaceDirective()237     virtual UsingNamespaceDirective *asUsingNamespaceDirective() { return nullptr; }
asUsingDeclaration()238     virtual UsingDeclaration *asUsingDeclaration() { return nullptr; }
asDeclaration()239     virtual Declaration *asDeclaration() { return nullptr; }
asArgument()240     virtual Argument *asArgument() { return nullptr; }
asTypenameArgument()241     virtual TypenameArgument *asTypenameArgument() { return nullptr; }
asBaseClass()242     virtual BaseClass *asBaseClass() { return nullptr; }
asForwardClassDeclaration()243     virtual ForwardClassDeclaration *asForwardClassDeclaration() { return nullptr; }
asQtPropertyDeclaration()244     virtual QtPropertyDeclaration *asQtPropertyDeclaration() { return nullptr; }
asQtEnum()245     virtual QtEnum *asQtEnum() { return nullptr; }
asObjCBaseClass()246     virtual ObjCBaseClass *asObjCBaseClass() { return nullptr; }
asObjCBaseProtocol()247     virtual ObjCBaseProtocol *asObjCBaseProtocol() { return nullptr; }
asObjCClass()248     virtual ObjCClass *asObjCClass() { return nullptr; }
asObjCForwardClassDeclaration()249     virtual ObjCForwardClassDeclaration *asObjCForwardClassDeclaration() { return nullptr; }
asObjCProtocol()250     virtual ObjCProtocol *asObjCProtocol() { return nullptr; }
asObjCForwardProtocolDeclaration()251     virtual ObjCForwardProtocolDeclaration *asObjCForwardProtocolDeclaration() { return nullptr; }
asObjCMethod()252     virtual ObjCMethod *asObjCMethod() { return nullptr; }
asObjCPropertyDeclaration()253     virtual ObjCPropertyDeclaration *asObjCPropertyDeclaration() { return nullptr; }
254 
255     /// Returns this Symbol's type.
256     virtual FullySpecifiedType type() const = 0;
257 
258     /// Returns this Symbol's hash value.
259     unsigned hashCode() const;
260 
261     /// Returns this Symbol's index.
262     unsigned index() const;
263 
264     const Name *unqualifiedName() const;
265 
266     bool isGenerated() const;
267 
268     bool isDeprecated() const;
269     void setDeprecated(bool isDeprecated);
270 
271     bool isUnavailable() const;
272     void setUnavailable(bool isUnavailable);
273 
274     /// Returns this Symbol's eclosing scope.
275     Scope *enclosingScope() const;
276 
277     /// Returns the eclosing namespace scope.
278     Namespace *enclosingNamespace() const;
279 
280     /// Returns the eclosing template scope.
281     Template *enclosingTemplate() const;
282 
283     /// Returns the enclosing class scope.
284     Class *enclosingClass() const;
285 
286     /// Returns the enclosing enum scope.
287     Enum *enclosingEnum() const;
288 
289     /// Returns the enclosing prototype scope.
290     Function *enclosingFunction() const;
291 
292     /// Returns the enclosing Block scope.
293     Block *enclosingBlock() const;
294 
295     void setEnclosingScope(Scope *enclosingScope); // ### make me private
296     void resetEnclosingScope(); // ### make me private
297     void setSourceLocation(int sourceLocation, TranslationUnit *translationUnit); // ### make me private
298 
299     void visitSymbol(SymbolVisitor *visitor);
300     static void visitSymbol(Symbol *symbol, SymbolVisitor *visitor);
301 
302     virtual void copy(Symbol *other);
303 
304 protected:
305     virtual void visitSymbol0(SymbolVisitor *visitor) = 0;
306 
307 private:
308     const Name *_name;
309     Scope *_enclosingScope;
310     Symbol *_next;
311     const StringLiteral *_fileId;
312     int _sourceLocation;
313     unsigned _hashCode;
314     int _storage;
315     int _visibility;
316     int _index;
317     int _line;
318     int _column;
319 
320     bool _isGenerated: 1;
321     bool _isDeprecated: 1;
322     bool _isUnavailable: 1;
323 
324     class HashCode;
325 
326     friend class SymbolTable;
327 };
328 
329 } // namespace CPlusPlus
330