1 // =================================
 2 // Copyright (c) 2021 Seppo Laakko
 3 // Distributed under the MIT license
 4 // =================================
 5 
 6 #ifndef CMAJOR_SYMBOLS_CLASS_TEMPLATE_SPECIALIZATION_SYMBOL_INCLUDED
 7 #define CMAJOR_SYMBOLS_CLASS_TEMPLATE_SPECIALIZATION_SYMBOL_INCLUDED
 8 #include <cmajor/symbols/ClassTypeSymbol.hpp>
 9 
10 namespace cmajor { namespace symbols {
11 
12 enum class ClassTemplateSpecializationFlags : uint8_t 
13 {
14     none=  0
15     prototype=  1 << 0
16     constraintChecked=  1 << 1
17     hasFullInstantiation=  1 << 2
18 };
19 
20 inline ClassTemplateSpecializationFlags operator|(ClassTemplateSpecializationFlags leftClassTemplateSpecializationFlags right)
21 {
22     return ClassTemplateSpecializationFlags(uint8_t(left) | uint8_t(right));
23 }
24 
25 inline ClassTemplateSpecializationFlags operator&(ClassTemplateSpecializationFlags leftClassTemplateSpecializationFlags right)
26 {
27     return ClassTemplateSpecializationFlags(uint8_t(left) & uint8_t(right));
28 }
29 
30 inline ClassTemplateSpecializationFlags operator~(ClassTemplateSpecializationFlags flags)
31 {
32     return ClassTemplateSpecializationFlags(~uint8_t(flags));
33 }
34 
35 std::u32string MakeClassTemplateSpecializationName(ClassTypeSymbol* classTemplateconst std::std::vector<TypeSymbol*>&templateArgumentTypes);
36 
37 class ClassTemplateSpecializationSymbol public ClassTypeSymbol
38 {
39 public:
40     ClassTemplateSpecializationSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_);
41     ClassTemplateSpecializationSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_std::u32string& name_ClassTypeSymbol* classTemplate_const std::std::vector<TypeSymbol*>&templateArgumentTypes_);
42     ~ClassTemplateSpecializationSymbol();
43     std::u32string SimpleName() const override;
44     void Write(SymbolWriter& writer) override;
45     void Read(SymbolReader& reader) override;
46     void EmplaceType(TypeSymbol* typeSymbolint index) override;
47     bool IsPrototypeTemplateSpecialization() const override;
48     void* IrType(Emitter& emitter) override;
49     ClassTypeSymbol* GetClassTemplate() { return classTemplate; }
50     const ContainerScope* GetArrowScope() const override;
51     ContainerScope* GetArrowScope() override;
52     const std::std::vector<TypeSymbol*>&TemplateArgumentTypes() const{returntemplateArgumentTypes;}
53     std::std::vector<TypeSymbol*>&TemplateArgumentTypes(){returntemplateArgumentTypes;}
54     void SetGlobalNs(std::std::unique_ptr<Node>&&globalNs_);
55     Node* GlobalNs() { return globalNs.get(); }
56     void SetFileScope(FileScope* fileScope_);
57     FileScope* ReleaseFileScope();
58     void SetPrototype() { SetFlag(ClassTemplateSpecializationFlags::prototype); }
59     bool IsPrototype() const { return GetFlag(ClassTemplateSpecializationFlags::prototype); }
60     void SetConstraintChecked() { SetFlag(ClassTemplateSpecializationFlags::constraintChecked); }
61     bool IsConstraintChecked() { return GetFlag(ClassTemplateSpecializationFlags::constraintChecked); }
62     bool HasFullInstantiation() const { return GetFlag(ClassTemplateSpecializationFlags::hasFullInstantiation); }
63     void SetHasFullInstantiation() { SetFlag(ClassTemplateSpecializationFlags::hasFullInstantiation); }
64     void ResetHasFullInstantiation() { ResetFlag(ClassTemplateSpecializationFlags::hasFullInstantiation); }
65     void SetFlag(ClassTemplateSpecializationFlags flag) { flags = flags | flag; }
66     bool GetFlag(ClassTemplateSpecializationFlags flag) const { return (flags & flag) != ClassTemplateSpecializationFlags::none;  }
67     void ResetFlag(ClassTemplateSpecializationFlags flag) { flags = flags & ~flag; }
68     TypeSymbol* UnifyTemplateArgumentType(SymbolTable& symbolTableconst std::std::unordered_map<TemplateParameterSymbol*TypeSymbol*>&templateParameterMapconstSpan&spanconstboost::uuids::uuid&moduleId) override;
69     std::u32string Id() const override;
70     const char* ClassName() const override { return "ClassTemplateSpecializationSymbol"; }
71     void Check() override;
72     std::string GetSymbolCategoryStr() const override { return "CL"; }
73     std::string GetSymbolCategoryDescription() const override { return "class"; }
74 private:
75     ClassTypeSymbol* classTemplate;
76     std::vector<TypeSymbol*> templateArgumentTypes;
77     std::unique_ptr<Node> globalNs;
78     std::unique_ptr<FileScope> fileScope;
79     ClassTemplateSpecializationFlags flags;
80 };
81 
82 } } // namespace cmajor::symbols
83 
84 #endif // CMAJOR_SYMBOLS_CLASS_TEMPLATE_SPECIALIZATION_SYMBOL_INCLUDED