1
2
3
4
5
6 #ifndef CMAJOR_SYMBOLS_SYMBOL_INCLUDED
7 #define CMAJOR_SYMBOLS_SYMBOL_INCLUDED
8 #include <cmajor/symbols/SymbolsApi.hpp>
9 #include <cmajor/symbols/TypeMap.hpp>
10 #include <sngcm/ast/Attribute.hpp>
11 #include <sngcm/ast/Specifier.hpp>
12 #include <sngcm/ast/CompileUnit.hpp>
13 #include <sngxml/dom/Element.hpp>
14 #include <soulng/util/CodeFormatter.hpp>
15 #include <cmajor/ir/Emitter.hpp>
16 #include <unordered_set>
17 #include <stdint.h>
18
19 namespace cmajor { namespace symbols {
20
21 using soulng::lexer::Span;
22 using namespace sngcm::ast;
23 using namespace soulng::util;
24 using namespace cmajor::ir;
25
26 class SymbolWriter;
27 class SymbolReader;
28 class ContainerScope;
29 class ContainerSymbol;
30 class TypeSymbol;
31 class ConceptSymbol;
32 class ClassTypeSymbol;
33 class InterfaceTypeSymbol;
34 class NamespaceSymbol;
35 class FunctionSymbol;
36 class SymbolTable;
37 class Module;
38 class SymbolCollector;
39
40 enum class SymbolType : uint8_t
41 {
42 boolTypeSymbol, sbyteTypeSymbol, byteTypeSymbol, shortTypeSymbol, ushortTypeSymbol, intTypeSymbol, uintTypeSymbol, longTypeSymbol, ulongTypeSymbol, floatTypeSymbol, doubleTypeSymbol,
43 charTypeSymbol, wcharTypeSymbol, ucharTypeSymbol, voidTypeSymbol, nullPtrTypeSymbol,
44 arrayTypeSymbol, derivedTypeSymbol,
45 namespaceSymbol, functionSymbol, staticConstructorSymbol, constructorSymbol, destructorSymbol, memberFunctionSymbol, conversionFunctionSymbol, functionGroupSymbol,
46 classGroupTypeSymbol, classTypeSymbol, classTemplateSpecializationSymbol, interfaceTypeSymbol, conceptGroupSymbol, conceptSymbol,
47 delegateTypeSymbol, classDelegateTypeSymbol, declarationBlock, typedefSymbol, constantSymbol, enumTypeSymbol, enumConstantSymbol,
48 templateParameterSymbol, boundTemplateParameterSymbol, parameterSymbol, localVariableSymbol, memberVariableSymbol,
49 basicTypeUnaryPlus, basicTypeIntUnaryMinus, basicTypeFloatUnaryMinus, basicTypeComplement, basicTypeAdd, basicTypeFAdd, basicTypeSub, basicTypeFSub, basicTypeMul, basicTypeFMul,
50 basicTypeSDiv, basicTypeUDiv, basicTypeFDiv, basicTypeSRem, basicTypeURem, basicTypeAnd, basicTypeOr, basicTypeXor, basicTypeShl, basicTypeAShr, basicTypeLShr,
51 basicTypeNot, basicTypeIntegerEquality, basicTypeUnsignedIntegerLessThan, basicTypeSignedIntegerLessThan, basicTypeFloatingEquality, basicTypeFloatingLessThan,
52 defaultInt1, defaultSInt8, defaultUInt8, defaultSInt16, defaultUInt16, defaultSInt32, defaultUInt32, defaultSInt64, defaultUInt64,
53 defaultChar, defaultWChar, defaultUChar, defaultFloat, defaultDouble, basicTypeCopyCtor, basicTypeMoveCtor, basicTypeCopyAssignment, basicTypeMoveAssignment,
54 basicTypeReturn,
55 basicTypeImplicitSignExtension, basicTypeImplicitZeroExtension, basicTypeExplicitSignExtension, basicTypeExplicitZeroExtension, basicTypeTruncation, basicTypeBitCast,
56 basicTypeImplicitUnsignedIntToFloating, basicTypeImplicitSignedIntToFloating, basicTypeExplicitUnsignedIntToFloating, basicTypeExplicitSignedIntToFloating,
57 basicTypeFloatingToUnsignedInt, basicTypeFloatingToSignedInt, basicTypeFloatingExtension, basicTypeFloatingTruncation, trap,
58 enumTypeDefaultConstructor, enumTypeCopyConstructor, enumTypeMoveConstructor, enumTypeCopyAssignment, enumTypeMoveAssignment, enumTypeReturn, enumTypeEquality,
59 enumTypeToUnderlyingType, underlyingToEnumType,
60 delegateTypeDefaultConstructor, delegateTypeCopyConstructor, delegateTypeMoveConstructor, delegateTypeCopyAssignment, delegateTypeMoveAssignment, delegateTypeReturn, delegateTypeEquality,
61 functionToDelegateSymbol,
62 classDelegateTypeDefaultConstructor, classDelegateTypeCopyConstructor, classDelegateTypeMoveConstructor, classDelegateTypeCopyAssignment, classDelegateTypeMoveAssignment,
63 classDelegateTypeEquality, memberFunctionToClassDelegateSymbol,
64 arrayLengthFunctionSymbol, arrayBeginFunctionSymbol, arrayEndFunctionSymbol, arrayCBeginFunctionSymbol, arrayCEndFunctionSymbol,
65 namespaceTypeSymbol, functionGroupTypeSymbol, memberExpressionTypeSymbol, variableValueSymbol, globalVariableSymbol, globalVariableGroupSymbol,
66 stringFunctionContainerSymbol, stringLengthFunctionSymbol, axiomSymbol,
67 maxSymbol
68 };
69
70 std::string SymbolTypeStr(SymbolType symbolType);
71
72 enum class SymbolAccess : uint8_t
73 {
74 private_= 0, protected_= 1, internal_= 2, public_= 3
75 };
76
77 uint32_t AccessFlag(Emitter& emitter, SymbolAccess access);
78
79 enum class SymbolFlags : uint8_t
80 {
81 none= 0,
82 access= 1 << 0 | 1 << 1,
83 static_= 1 << 2,
84 external= 1 << 3,
85 nothrow_= 1 << 4,
86 project= 1 << 5,
87 bound= 1 << 6,
88 installed= 1 << 7
89 };
90
91 inline SymbolFlags operator&(SymbolFlags left, SymbolFlags right)
92 {
93 return SymbolFlags(uint8_t(left) & uint8_t(right));
94 }
95
96 inline SymbolFlags operator|(SymbolFlags left, SymbolFlags right)
97 {
98 return SymbolFlags(uint8_t(left) | uint8_t(right));
99 }
100
101 inline SymbolFlags operator~(SymbolFlags flags)
102 {
103 return SymbolFlags(~uint8_t(flags));
104 }
105
106 std::string SymbolFlagStr(SymbolFlags symbolFlags);
107 std::string SymbolFlagStr(SymbolFlags symbolFlags, bool noAccess);
108
109 class SymbolLocation
110 {
111 public:
112 SymbolLocation() : moduleId(boost::uuids::nil_uuid()), fileIndex(0), line(0), scol(0), ecol(0)
113 {
114 }
115 SymbolLocation(const boost::uuids::uuid& moduleId_, int32_t fileIndex_, int32_t line_, int32_t scol_, int32_t ecol_) :
116 moduleId(moduleId_), fileIndex(fileIndex_), line(line_), scol(scol_), ecol(ecol_)
117 {
118 }
119 boost::uuids::uuid moduleId;
120 int32_t fileIndex;
121 int32_t line;
122 int32_t scol;
123 int32_t ecol;
124 };
125
126 bool operator==(const SymbolLocation& left, const SymbolLocation& right);
127 bool operator<(const SymbolLocation& left, const SymbolLocation& right);
128
129 SymbolLocation MakeSymbolLocation(const Span& span, Module* module);
130
131 class Symbol
132 {
133 public:
134 Symbol(SymbolType symbolType_, const Span& span_, const boost::uuids::uuid& sourceModuleId_, const std::u32string& name_);
135 virtual ~Symbol();
136 virtual void Write(SymbolWriter& writer);
137 virtual void Read(SymbolReader& reader);
138 virtual void EmplaceType(TypeSymbol* typeSymbol, int index) {}
139 virtual void EmplaceConcept(ConceptSymbol* conceptSymbol) {}
140 virtual void EmplaceFunction(FunctionSymbol* functionSymbol, int index) {}
141 virtual bool IsExportSymbol() const { return IsProject(); }
142 virtual bool IsContainerSymbol() const { return false; }
143 virtual bool IsFunctionSymbol() const { return false; }
144 virtual bool IsTypeSymbol() const { return false; }
145 virtual bool IsClassTypeSymbol() const { return false; }
146 virtual bool IsParentSymbol() const { return false; }
147 virtual bool IsVariableSymbol() const { return false; }
148 virtual bool IsGlobalVariableSymbol() const { return false; }
149 virtual void Accept(SymbolCollector* collector) {}
150 virtual const ContainerScope* GetContainerScope() const;
151 virtual ContainerScope* GetContainerScope();
152 virtual const ContainerScope* GetTypeScope() const;
153 virtual ContainerScope* GetTypeScope();
154 virtual ContainerScope* GetArrowScope();
155 virtual const ContainerScope* GetArrowScope() const;
156 virtual std::u32string FullName() const;
157 virtual std::u32string FullNameWithSpecifiers() const;
158 virtual std::u32string SimpleName() const { return Name(); }
159 virtual std::u32string DocName() const { return Name(); }
160 virtual std::u32string CodeName() const { return Name(); }
161 virtual std::u32string Id() const { return mangledName; }
162 virtual SymbolAccess DeclaredAccess() const { return Access(); }
163 virtual std::string TypeString() const { return "symbol"; }
164 virtual void* IrObject(Emitter& emitter);
165 virtual void ComputeMangledName();
166 virtual void Dump(CodeFormatter& formatter) {}
167 virtual std::string GetSpecifierStr() const;
168 virtual std::string Syntax() const;
169 virtual void CopyFrom(const Symbol* that);
170 virtual void Check();
171 void SetMangledName(const std::u32string& mangledName_);
172 SymbolAccess Access() const { return SymbolAccess(flags & SymbolFlags::access); }
173 void SetAccess(SymbolAccess access_) { flags = flags | SymbolFlags(access_); }
174 void SetAccess(Specifiers accessSpecifiers);
175 bool IsSameParentOrAncestorOf(const Symbol* that) const;
176 SymbolType GetSymbolType() const { return symbolType; }
177 const Span& GetSpan() const { return span; }
178 void SetSpan(const Span& span_) { span = span_; }
179 const std::u32string& Name() const { return name; }
180 void SetName(const std::u32string& name_) { name = name_; }
181 SymbolFlags GetSymbolFlags() const { return flags; }
182 SymbolFlags GetStableSymbolFlags() const { return flags & ~(SymbolFlags::project | SymbolFlags::bound | SymbolFlags::installed); }
183 bool IsStatic() const { return GetFlag(SymbolFlags::static_); }
184 void SetStatic() { SetFlag(SymbolFlags::static_); }
185 bool IsExternal() const { return GetFlag(SymbolFlags::external); }
186 void SetExternal() { SetFlag(SymbolFlags::external); }
187 bool IsNothrow() const { return GetFlag(SymbolFlags::nothrow_); }
188 void SetNothrow() { SetFlag(SymbolFlags::nothrow_); }
189 bool IsProject() const { return GetFlag(SymbolFlags::project); }
190 void SetProject() { SetFlag(SymbolFlags::project); }
191 bool IsBound() const { return GetFlag(SymbolFlags::bound); }
192 void SetBound() { SetFlag(SymbolFlags::bound); }
193 bool GetFlag(SymbolFlags flag) const { return (flags & flag) != SymbolFlags::none; }
194 void SetFlag(SymbolFlags flag) { flags = flags | flag; }
195 void ResetFlag(SymbolFlags flag) { flags = flags & ~flag; }
196 const Symbol* Parent() const { return parent; }
197 Symbol* Parent() { return parent; }
198 void SetParent(Symbol* parent_) { parent = parent_; }
199 const NamespaceSymbol* Ns() const;
200 NamespaceSymbol* Ns();
201 const ClassTypeSymbol* ClassNoThrow() const;
202 ClassTypeSymbol* ClassNoThrow();
203 const ContainerSymbol* ClassOrNsNoThrow() const;
204 ContainerSymbol* ClassOrNsNoThrow();
205 const ContainerSymbol* ClassInterfaceOrNsNoThrow() const;
206 ContainerSymbol* ClassInterfaceOrNsNoThrow();
207 const ContainerSymbol* ClassInterfaceEnumDelegateOrNsNoThrow() const;
208 ContainerSymbol* ClassInterfaceEnumDelegateOrNsNoThrow();
209 const ClassTypeSymbol* Class() const;
210 ClassTypeSymbol* Class();
211 const ClassTypeSymbol* ContainingClassNoThrow() const;
212 ClassTypeSymbol* ContainingClassNoThrow();
213 const InterfaceTypeSymbol* InterfaceNoThrow() const;
214 InterfaceTypeSymbol* InterfaceNoThrow();
215 const InterfaceTypeSymbol* ContainingInterfaceNoThrow() const;
216 InterfaceTypeSymbol* ContainingInterfaceNoThrow();
217 const FunctionSymbol* FunctionNoThrow() const;
218 FunctionSymbol* FunctionNoThrow();
219 const FunctionSymbol* Function() const;
220 FunctionSymbol* Function();
221 const FunctionSymbol* ContainingFunctionNoThrow() const;
222 FunctionSymbol* ContainingFunctionNoThrow();
223 const ContainerScope* ClassOrNsScope() const;
224 ContainerScope* ClassOrNsScope();
225 const ContainerScope* ClassInterfaceOrNsScope() const;
226 ContainerScope* ClassInterfaceOrNsScope();
227 const ContainerScope* ClassInterfaceEnumDelegateOrNsScope() const;
228 ContainerScope* ClassInterfaceEnumDelegateOrNsScope();
229 Module* GetModule() const { return module; }
230 Module* GetModule() { return module; }
231 void SetModule(Module* module_) { module = module_; }
232 const CompileUnitNode* GetCompileUnit() const { return compileUnit; }
233 void SetCompileUnit(CompileUnitNode* compileUnit_) { compileUnit = compileUnit_; }
234 const std::u32string& MangledName() const { return mangledName; }
235 void SetAttributes(std::std::unique_ptr<AttributesNode>&&attributes_);
236 AttributesNode* GetAttributes() const { return attributes.get(); }
237 std::unique_ptr<sngxml::dom::Element> ToDomElement(TypeMap& typeMap);
238 virtual std::unique_ptr<sngxml::dom::Element> CreateDomElement(TypeMap& typeMap);
239 virtual sngxml::dom::Element* ToCCElement(int ccPrefixLength, const std::u32string& replacement, const std::u32string& functionGroup) const;
240 virtual std::string GetSymbolCategoryStr() const { return "SY"; }
241 virtual std::string GetSymbolCategoryDescription() const { return "symbol"; }
242 virtual std::string GetSymbolHelp() const;
243 virtual std::u32string Info() const { return std::u32string(); }
244 virtual void AppendChildElements(sngxml::dom::Element* element, TypeMap& typeMap) const {}
245 virtual bool HasProjectMembers() const { return false; }
246 virtual const char* ClassName() const { return "Symbol"; }
247 bool GetLocation(SymbolLocation& definitionLocation) const;
248 const boost::uuids::uuid& SourceModuleId() const { return sourceModuleId; }
249 int SymbolIndex() const { return symbolIndex; }
250 void SetSymbolIndex(int symbolIndex_) { symbolIndex = symbolIndex_; }
251 virtual std::unique_ptr<Symbol> RemoveMember(int symbolIndex);
252 virtual std::unique_ptr<Symbol> RemoveFromParent();
253 void SetInstalled() { SetFlag(SymbolFlags::installed); }
254 void ResetInstalled() { ResetFlag(SymbolFlags::installed); }
255 bool IsInstalled() const { return GetFlag(SymbolFlags::installed); }
256 private:
257 SymbolType symbolType;
258 Span span;
259 boost::uuids::uuid sourceModuleId;
260 std::u32string name;
261 SymbolFlags flags;
262 std::u32string mangledName;
263 Symbol* parent;
264 Module* module;
265 CompileUnitNode* compileUnit;
266 std::unique_ptr<AttributesNode> attributes;
267 int symbolIndex;
268 };
269
270 class SymbolCreator
271 {
272 public:
273 virtual ~SymbolCreator();
274 virtual Symbol* CreateSymbol(const Span& span, const boost::uuids::uuid& sourceModuleId, const std::u32string& name) = 0;
275 };
276
277 class SymbolFactory
278 {
279 public:
280 static void Init();
281 static void Done();
282 static SymbolFactory& Instance() { Assert(instance, "symbol factory not initialized"); return *instance; }
283 Symbol* CreateSymbol(SymbolType symbolType, const Span& span, const boost::uuids::uuid& sourceModuleId, const std::u32string& name);
284 void Register(SymbolType symbolType, SymbolCreator* creator);
285 private:
286 static std::unique_ptr<SymbolFactory> instance;
287 std::vector<std::std::unique_ptr<SymbolCreator>>symbolCreators;
288 SymbolFactory();
289 };
290
291 void InitSymbol();
292 void DoneSymbol();
293
294 } }
295
296 #endif // CMAJOR_SYMBOLS_SYMBOL_INCLUDED