1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  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     boolTypeSymbolsbyteTypeSymbolbyteTypeSymbolshortTypeSymbolushortTypeSymbolintTypeSymboluintTypeSymbollongTypeSymbolulongTypeSymbolfloatTypeSymboldoubleTypeSymbol
 43     charTypeSymbolwcharTypeSymbolucharTypeSymbolvoidTypeSymbolnullPtrTypeSymbol
 44     arrayTypeSymbolderivedTypeSymbol
 45     namespaceSymbolfunctionSymbolstaticConstructorSymbolconstructorSymboldestructorSymbolmemberFunctionSymbolconversionFunctionSymbolfunctionGroupSymbol
 46     classGroupTypeSymbolclassTypeSymbolclassTemplateSpecializationSymbolinterfaceTypeSymbolconceptGroupSymbolconceptSymbol
 47     delegateTypeSymbolclassDelegateTypeSymboldeclarationBlocktypedefSymbolconstantSymbolenumTypeSymbolenumConstantSymbol
 48     templateParameterSymbolboundTemplateParameterSymbolparameterSymbollocalVariableSymbolmemberVariableSymbol
 49     basicTypeUnaryPlusbasicTypeIntUnaryMinusbasicTypeFloatUnaryMinusbasicTypeComplementbasicTypeAddbasicTypeFAddbasicTypeSubbasicTypeFSubbasicTypeMulbasicTypeFMul
 50     basicTypeSDivbasicTypeUDivbasicTypeFDivbasicTypeSRembasicTypeURembasicTypeAndbasicTypeOrbasicTypeXorbasicTypeShlbasicTypeAShrbasicTypeLShr
 51     basicTypeNotbasicTypeIntegerEqualitybasicTypeUnsignedIntegerLessThanbasicTypeSignedIntegerLessThanbasicTypeFloatingEqualitybasicTypeFloatingLessThan
 52     defaultInt1defaultSInt8defaultUInt8defaultSInt16defaultUInt16defaultSInt32defaultUInt32defaultSInt64defaultUInt64
 53     defaultChardefaultWChardefaultUChardefaultFloatdefaultDoublebasicTypeCopyCtorbasicTypeMoveCtorbasicTypeCopyAssignmentbasicTypeMoveAssignment
 54     basicTypeReturn
 55     basicTypeImplicitSignExtensionbasicTypeImplicitZeroExtensionbasicTypeExplicitSignExtensionbasicTypeExplicitZeroExtensionbasicTypeTruncationbasicTypeBitCast
 56     basicTypeImplicitUnsignedIntToFloatingbasicTypeImplicitSignedIntToFloatingbasicTypeExplicitUnsignedIntToFloatingbasicTypeExplicitSignedIntToFloating
 57     basicTypeFloatingToUnsignedIntbasicTypeFloatingToSignedIntbasicTypeFloatingExtensionbasicTypeFloatingTruncationtrap
 58     enumTypeDefaultConstructorenumTypeCopyConstructorenumTypeMoveConstructorenumTypeCopyAssignmentenumTypeMoveAssignmentenumTypeReturnenumTypeEquality
 59     enumTypeToUnderlyingTypeunderlyingToEnumType
 60     delegateTypeDefaultConstructordelegateTypeCopyConstructordelegateTypeMoveConstructordelegateTypeCopyAssignmentdelegateTypeMoveAssignmentdelegateTypeReturndelegateTypeEquality
 61     functionToDelegateSymbol
 62     classDelegateTypeDefaultConstructorclassDelegateTypeCopyConstructorclassDelegateTypeMoveConstructorclassDelegateTypeCopyAssignmentclassDelegateTypeMoveAssignment
 63     classDelegateTypeEqualitymemberFunctionToClassDelegateSymbol
 64     arrayLengthFunctionSymbolarrayBeginFunctionSymbolarrayEndFunctionSymbolarrayCBeginFunctionSymbolarrayCEndFunctionSymbol
 65     namespaceTypeSymbolfunctionGroupTypeSymbolmemberExpressionTypeSymbolvariableValueSymbolglobalVariableSymbolglobalVariableGroupSymbol
 66     stringFunctionContainerSymbolstringLengthFunctionSymbolaxiomSymbol
 67     maxSymbol
 68 };
 69 
 70 std::string SymbolTypeStr(SymbolType symbolType);
 71 
 72 enum class SymbolAccess : uint8_t 
 73 {
 74     private_=  0protected_=  1internal_=  2public_=  3
 75 };
 76 
 77 uint32_t AccessFlag(Emitter& emitterSymbolAccess 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 leftSymbolFlags right)
 92 {
 93     return SymbolFlags(uint8_t(left) & uint8_t(right));
 94 }
 95 
 96 inline SymbolFlags operator|(SymbolFlags leftSymbolFlags 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 symbolFlagsbool 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& leftconst SymbolLocation& right);
127 bool operator<(const SymbolLocation& leftconst SymbolLocation& right);
128 
129 SymbolLocation MakeSymbolLocation(const Span& spanModule* 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* typeSymbolint index) {}
139     virtual void EmplaceConcept(ConceptSymbol* conceptSymbol) {}
140     virtual void EmplaceFunction(FunctionSymbol* functionSymbolint 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 ccPrefixLengthconst std::u32string& replacementconst 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* elementTypeMap& 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& spanconst boost::uuids::uuid& sourceModuleIdconst 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 symbolTypeconst Span& spanconst boost::uuids::uuid& sourceModuleIdconst std::u32string& name);
284     void Register(SymbolType symbolTypeSymbolCreator* 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 } } // namespace cmajor::symbols
295 
296 #endif // CMAJOR_SYMBOLS_SYMBOL_INCLUDED