1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_SYMBOLS_ENUM_SYMBOL_INCLUDED
  7 #define CMAJOR_SYMBOLS_ENUM_SYMBOL_INCLUDED
  8 #include <cmajor/symbols/TypeSymbol.hpp>
  9 #include <cmajor/symbols/FunctionSymbol.hpp>
 10 #include <cmajor/symbols/Value.hpp>
 11 
 12 namespace cmajor { namespace symbols {
 13 
 14 class EnumConstantSymbol;
 15 
 16 class EnumTypeSymbol public TypeSymbol
 17 {
 18 public:
 19     EnumTypeSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
 20     void Write(SymbolWriter& writer) override;
 21     void Read(SymbolReader& reader) override;
 22     void EmplaceType(TypeSymbol* typeSymbolint index) override;
 23     std::string TypeString() const override { return "enumerated_type"; }
 24     std::string Syntax() const override;
 25     bool IsEnumeratedType() const override { return true; }
 26     bool IsParentSymbol() const override { return true; }
 27     void Accept(SymbolCollector* collector) override;
 28     void CollectMembers(SymbolCollector* collector);
 29     void Dump(CodeFormatter& formatter) override;
 30     void SetSpecifiers(Specifiers specifiers);
 31     const TypeSymbol* UnderlyingType() const { return underlyingType; }
 32     TypeSymbol* UnderlyingType() { return underlyingType; }
 33     void SetUnderlyingType(TypeSymbol* underlyingType_) { underlyingType = underlyingType_; }
 34     std::vector<EnumConstantSymbol*> GetEnumConstants();
 35     void* IrType(Emitter& emitter) override { return underlyingType->IrType(emitter); }
 36     void* CreateDefaultIrValue(Emitter& emitter) override { return underlyingType->CreateDefaultIrValue(emitter); }
 37     void* CreateDIType(Emitter& emitter) override;
 38     bool IsSwitchConditionType() const override { return true; }
 39     ValueType GetValueType() const override;
 40     Value* MakeValue() const override;
 41     std::u32string Id() const override;
 42     std::u32string Info() const override { return Name(); }
 43     const char* ClassName() const override { return "EnumTypeSymbol"; }
 44     void Check() override;
 45     std::string GetSymbolCategoryStr() const override { return "ET"; }
 46     std::string GetSymbolCategoryDescription() const override { return "enumerated type"; }
 47 private:
 48     TypeSymbol* underlyingType;
 49 };
 50 
 51 class EnumConstantSymbol public Symbol
 52 {
 53 public:
 54     EnumConstantSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
 55     SymbolAccess DeclaredAccess() const override { return SymbolAccess::public_; }
 56     std::string TypeString() const override { return "enumeration_constant"; }
 57     void Accept(SymbolCollector* collector) override;
 58     void Dump(CodeFormatter& formatter) override;
 59     void Write(SymbolWriter& writer) override;
 60     void Read(SymbolReader& reader) override;
 61     bool Evaluating() const { return evaluating; }
 62     void SetEvaluating() { evaluating = true; }
 63     void ResetEvaluating() { evaluating = false; }
 64     const TypeSymbol* GetType() const { return static_cast<const EnumTypeSymbol*>(Parent()); }
 65     TypeSymbol* GetType() { return static_cast<EnumTypeSymbol*>(Parent()); }
 66     void SetValue(Value* value_);
 67     const Value* GetValue() const { return value.get(); }
 68     Value* GetValue() { return value.get(); }
 69     std::u32string Info() const override { return Name(); }
 70     const char* ClassName() const override { return "EnumConstantSymbol"; }
 71     void SetStrValue(const std::u32string& strValue_) { strValue = strValue_; }
 72     const std::u32string& StrValue() const { return strValue; }
 73     std::string GetSymbolCategoryStr() const override { return "EC"; }
 74     std::string GetSymbolCategoryDescription() const override { return "enumeration constant"; }
 75 private:
 76     std::unique_ptr<Value> value;
 77     bool evaluating;
 78     std::u32string strValue;
 79 };
 80 
 81 class EnumTypeDefaultConstructor public FunctionSymbol
 82 {
 83 public:
 84     EnumTypeDefaultConstructor(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
 85     EnumTypeDefaultConstructor(EnumTypeSymbol* enumType_);
 86     void Write(SymbolWriter& writer) override;
 87     void Read(SymbolReader& reader) override;
 88     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
 89     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
 90     bool IsBasicTypeOperation() const override { return true; }
 91     const char* ClassName() const override { return "EnumTypeDefaultConstructor"; }
 92     void Check() override;
 93 private:
 94     FunctionSymbol* underlyingTypeDefaultConstructor;
 95 };
 96 
 97 class EnumTypeCopyConstructor public FunctionSymbol
 98 {
 99 public:
100     EnumTypeCopyConstructor(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
101     EnumTypeCopyConstructor(EnumTypeSymbol* enumType_);
102     void Write(SymbolWriter& writer) override;
103     void Read(SymbolReader& reader) override;
104     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
105     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
106     bool IsBasicTypeOperation() const override { return true; }
107     const char* ClassName() const override { return "EnumTypeCopyConstructor"; }
108     void Check() override;
109 private:
110     FunctionSymbol* underlyingTypeCopyConstructor;
111 };
112 
113 class EnumTypeMoveConstructor public FunctionSymbol
114 {
115 public:
116     EnumTypeMoveConstructor(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
117     EnumTypeMoveConstructor(EnumTypeSymbol* enumType_);
118     void Write(SymbolWriter& writer) override;
119     void Read(SymbolReader& reader) override;
120     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
121     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
122     bool IsBasicTypeOperation() const override { return true; }
123     const char* ClassName() const override { return "EnumTypeMoveConstructor"; }
124     void Check() override;
125 private:
126     FunctionSymbol* underlyingTypeMoveConstructor;
127 };
128 
129 class EnumTypeCopyAssignment public FunctionSymbol
130 {
131 public:
132     EnumTypeCopyAssignment(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
133     EnumTypeCopyAssignment(EnumTypeSymbol* enumType_TypeSymbol* voidType_);
134     void Write(SymbolWriter& writer) override;
135     void Read(SymbolReader& reader) override;
136     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
137     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
138     bool IsBasicTypeOperation() const override { return true; }
139     const char* ClassName() const override { return "EnumTypeCopyAssignment"; }
140     void Check() override;
141 private:
142     FunctionSymbol* underlyingTypeCopyAssignment;
143 };
144 
145 class EnumTypeMoveAssignment public FunctionSymbol
146 {
147 public:
148     EnumTypeMoveAssignment(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
149     EnumTypeMoveAssignment(EnumTypeSymbol* enumType_TypeSymbol* voidType_);
150     void Write(SymbolWriter& writer) override;
151     void Read(SymbolReader& reader) override;
152     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
153     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
154     bool IsBasicTypeOperation() const override { return true; }
155     const char* ClassName() const override { return "EnumTypeMoveAssignment"; }
156     void Check() override;
157 private:
158     FunctionSymbol* underlyingTypeMoveAssignment;
159 };
160 
161 class EnumTypeReturn public FunctionSymbol
162 {
163 public:
164     EnumTypeReturn(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
165     EnumTypeReturn(EnumTypeSymbol* enumType_);
166     void Write(SymbolWriter& writer) override;
167     void Read(SymbolReader& reader) override;
168     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
169     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
170     bool IsBasicTypeOperation() const override { return true; }
171     const char* ClassName() const override { return "EnumTypeReturn"; }
172     void Check() override;
173 private:
174     FunctionSymbol* underlyingTypeReturn;
175 };
176 
177 class EnumTypeEqualityOp public FunctionSymbol
178 {
179 public:
180     EnumTypeEqualityOp(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
181     EnumTypeEqualityOp(EnumTypeSymbol* enumType_TypeSymbol* boolType_);
182     void Write(SymbolWriter& writer) override;
183     void Read(SymbolReader& reader) override;
184     void EmplaceFunction(FunctionSymbol* functionSymbolint index) override;
185     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
186     bool IsBasicTypeOperation() const override { return true; }
187     const char* ClassName() const override { return "EnumTypeEqualityOp"; }
188     void Check() override;
189 private:
190     FunctionSymbol* underlyingTypeEquality;
191 };
192 
193 class EnumTypeToUnderlyingTypeConversion public FunctionSymbol
194 {
195 public:
196     EnumTypeToUnderlyingTypeConversion(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
197     EnumTypeToUnderlyingTypeConversion(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_TypeSymbol* sourceType_TypeSymbol* targetType_);
198     void Write(SymbolWriter& writer) override;
199     void Read(SymbolReader& reader) override;
200     void EmplaceType(TypeSymbol* typeSymbolint index) override;
201     SymbolAccess DeclaredAccess() const override { return SymbolAccess::public_; }
202     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
203     bool IsBasicTypeOperation() const override { return true; }
204     ConversionType GetConversionType() const override { return ConversionType::implicit_; }
205     uint8_t ConversionDistance() const override { return 1; }
206     const char* ClassName() const override { return "EnumTypeToUnderlyingTypeConversion"; }
207     void Check() override;
208 private:
209     TypeSymbol* sourceType;
210     TypeSymbol* targetType;
211 };
212 
213 class UnderlyingTypeToEnumTypeConversion public FunctionSymbol
214 {
215 public:
216     UnderlyingTypeToEnumTypeConversion(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
217     UnderlyingTypeToEnumTypeConversion(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_TypeSymbol* sourceType_TypeSymbol* targetType_);
218     void Write(SymbolWriter& writer) override;
219     void Read(SymbolReader& reader) override;
220     void EmplaceType(TypeSymbol* typeSymbolint index) override;
221     SymbolAccess DeclaredAccess() const override { return SymbolAccess::public_; }
222     void GenerateCall(Emitter& emitterstd::std::vector<GenObject*>&genObjectsOperationFlagsflagsconstSpan&spanconstboost::uuids::uuid& moduleId) override;
223     bool IsBasicTypeOperation() const override { return true; }
224     ConversionType GetConversionType() const override { return ConversionType::explicit_; }
225     uint8_t ConversionDistance() const override { return 255; }
226     const char* ClassName() const override { return "UnderlyingTypeToEnumTypeConversion"; }
227     void Check() override;
228 private:
229     TypeSymbol* sourceType;
230     TypeSymbol* targetType;
231 };
232 
233 } } // namespace cmajor::symbols
234 
235 #endif // CMAJOR_SYMBOLS_ENUM_SYMBOL_INCLUDED