1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #ifndef CMAJOR_BINDER_BOUND_COMPILE_UNIT_INCLUDED
  7 #define CMAJOR_BINDER_BOUND_COMPILE_UNIT_INCLUDED
  8 #include <cmajor/binder/BoundNode.hpp>
  9 #include <cmajor/binder/OperationRepository.hpp>
 10 #include <cmajor/binder/FunctionTemplateRepository.hpp>
 11 #include <cmajor/binder/ClassTemplateRepository.hpp>
 12 #include <cmajor/binder/InlineFunctionRepository.hpp>
 13 #include <cmajor/binder/ConstExprFunctionRepository.hpp>
 14 #include <cmajor/binder/StringRepository.hpp>
 15 #include <cmajor/binder/UuidRepository.hpp>
 16 #include <cmajor/binder/ConstantArrayRepository.hpp>
 17 #include <cmajor/binder/ConstantStructureRepository.hpp>
 18 #include <cmajor/binder/ConceptRepository.hpp>
 19 #include <cmajor/symbols/Module.hpp>
 20 #include <cmajor/symbols/ConversionTable.hpp>
 21 #include <sngcm/ast/CompileUnit.hpp>
 22 
 23 namespace cmajor { namespace binder {
 24 
 25 using namespace cmajor::symbols;
 26 
 27 class BoundExpression;
 28 struct ArgumentMatch;
 29 class AttributeBinder;
 30 class BoundNamespace;
 31 
 32 class BoundCompileUnit public BoundNode
 33 {
 34 public:
 35     BoundCompileUnit(Module& module_CompileUnitNode* compileUnitNode_AttributeBinder* attributeBinder_);
 36     BoundCompileUnit(const BoundCompileUnit&) = delete;
 37     BoundCompileUnit& operator=(const BoundCompileUnit&) = delete;
 38     void Load(Emitter& emitterOperationFlags flags) override;
 39     void Store(Emitter& emitterOperationFlags flags) override;
 40     void Accept(BoundNodeVisitor& visitor) override;
 41     Module& GetModule() { return module; }
 42     SymbolTable& GetSymbolTable() { return symbolTable; }
 43     CompileUnitNode* GetCompileUnitNode() const { return compileUnitNode; }
 44     void AddFileScope(FileScope* fileScope);
 45     void RemoveLastFileScope();
 46     FileScope* ReleaseLastFileScope();
 47     FileScope* FirstFileScope() const { Assert(!fileScopes.empty()"file scopes empty");  return fileScopes.front().get(); }
 48     const std::std::vector<std::std::unique_ptr<FileScope>>&FileScopes() const{returnfileScopes;}
 49     void AddBoundNode(std::std::unique_ptr<BoundNode>&&boundNode);
 50     const std::std::vector<std::std::unique_ptr<BoundNode>>&BoundNodes() const{returnboundNodes;}
 51     FunctionSymbol* GetConversion(TypeSymbol* sourceTypeTypeSymbol* targetTypeContainerScope* containerScopeBoundFunction* currentFunctionconst Span& spanconst boost::uuids::uuid& moduleId
 52         ArgumentMatch& argumentMatch);
 53     void CollectViableFunctions(const std::u32string& groupNameContainerScope* containerScopestd::std::vector<std::std::unique_ptr<BoundExpression>>&argumentsBoundFunction*currentFunction
 54         ViableFunctionSet& viableFunctionsstd::std::unique_ptr<Exception>&exceptionconstSpan&spanconstboost::uuids::uuid&moduleIdCollectFlags flags);
 55     FunctionSymbol* InstantiateFunctionTemplate(FunctionSymbol* functionTemplateconst std::std::unordered_map<TemplateParameterSymbol*TypeSymbol*>&templateParameterMappingconstSpan&spanconstboost::uuids::uuid&moduleId);
 56     bool InstantiateClassTemplateMemberFunction(FunctionSymbol* memberFunctionContainerScope* containerScopeBoundFunction* currentFunctionconst Span& spanconst boost::uuids::uuid& moduleId);
 57     FunctionSymbol* InstantiateInlineFunction(FunctionSymbol* inlineFunctionContainerScope* containerScopeconst Span& spanconst boost::uuids::uuid& moduleId);
 58     FunctionNode* GetFunctionNodeFor(FunctionSymbol* constExprFunctionSymbol);
 59     void GenerateCopyConstructorFor(ClassTypeSymbol* classTypeSymbolContainerScope* containerScopeBoundFunction* currentFunctionconst Span& spanconst boost::uuids::uuid& moduleId);
 60     void GenerateCopyConstructorFor(InterfaceTypeSymbol* interfaceTypeSymbolContainerScope* containerScopeBoundFunction* currentFunctionconst Span& spanconst boost::uuids::uuid& moduleId);
 61     int Install(const std::string& str);
 62     int Install(const std::u16string& str);
 63     int Install(const std::u32string& str);
 64     int Install(const boost::uuids::uuid& uuid);
 65     const std::string& GetUtf8String(int stringId) const;
 66     const std::u16string& GetUtf16String(int stringId) const;
 67     const std::u32string& GetUtf32String(int stringId) const;
 68     const unsigned char* GetUtf8CharPtr(int stringId) const;
 69     const char16_t* GetUtf16CharPtr(int stringId) const;
 70     const char32_t* GetUtf32CharPtr(int stringId) const;
 71     const boost::uuids::uuid& GetUuid(int uuidId) const;
 72     void AddConstantArray(ConstantSymbol* constantArraySymbol);
 73     ConstantArrayRepository& GetConstantArrayRepository() { return constantArrayRepository; }
 74     void AddConstantStructure(ConstantSymbol* constantStructureSymbol);
 75     ConstantStructureRepository& GetConstantStructureRepository() { return constantStructureRepository; }
 76     const std::string& SourceFilePath() const { return compileUnitNode->FilePath(); }
 77     const std::string& LLFilePath() const { return llFilePath; }
 78     const std::string& CppFilePath() const { return cppFilePath; }
 79     const std::string& BCFilePath() const { return bcFilePath; }
 80     const std::string& OptLLFilePath() const { return optLLFilePath; }
 81     const std::string& OptBCFilePath() const { return optBCFilePath; }
 82     const std::string& ObjectFilePath() const { return objectFilePath; }
 83     const std::string& Id() const { return compileUnitNode->Id(); }
 84     void SetHasGotos() { hasGotos = true; }
 85     bool HasGotos() const { return hasGotos; }
 86     ClassTemplateRepository& GetClassTemplateRepository() { return classTemplateRepository; }
 87     ConceptRepository& GetConceptRepository() { return conceptRepository; }
 88     void PushBindingTypes();
 89     void PopBindingTypes();
 90     bool BindingTypes() const { return bindingTypes; }
 91     void FinalizeBinding(ClassTemplateSpecializationSymbol* classTemplateSpecialization);
 92     AttributeBinder* GetAttributeBinder() const { return attributeBinder; }
 93     void PushNamespace(BoundNamespace* ns);
 94     void PopNamespace();
 95     bool HasCopyConstructorFor(const boost::uuids::uuid& typeId) const;
 96     FunctionSymbol* GetCopyConstructorFor(const boost::uuids::uuid& typeId) const;
 97     void AddCopyConstructorFor(const boost::uuids::uuid& typeIdstd::std::unique_ptr<FunctionSymbol>&&copyConstructor);
 98     void AddCopyConstructorToMap(const boost::uuids::uuid& typeIdFunctionSymbol* copyConstructor);
 99     bool Immutable() const { return immutable; }
100     void SetImmutable() { immutable = true; }
101     void AddGlobalNs(std::std::unique_ptr<NamespaceNode>&&globalNs);
102     int GetNextExitEntryIndex() { return nextExitEntryIndex++; }
103     bool IsGeneratedDestructorInstantiated(DestructorSymbol* generatedDestructorSymbol) const;
104     void SetGeneratedDestructorInstantiated(DestructorSymbol* generatedDestructorSymbol);
105     void SetSystemRuntimeUnwindInfoSymbol(TypeSymbol* systemRuntimeUnwindInfoSymbol_);
106     TypeSymbol* GetSystemRuntimeUnwindInfoSymbol() const { return systemRuntimeUnwindInfoSymbol; }
107     void GenerateInitUnwindInfoFunctionSymbol();
108     FunctionSymbol* GetInitUnwindInfoFunctionSymbol() const { return initUnwindInfoFunctionSymbol.get(); }
109     void GenerateCompileUnitInitialization();
110     FunctionSymbol* GetInitCompileUnitFunctionSymbol() const { return initCompileUnitFunctionSymbol.get(); }
111     FunctionSymbol* GetPushCompileUnitUnwindInfoInitFunctionSymbol() const { return pushCompileUnitUnwindInfoInitFunctionSymbol; }
112     GlobalVariableSymbol* GetCompileUnitUnwindInfoVarSymbol() const { return compileUnitUnwindInfoVarSymbol.get(); }
113     TypeSymbol* GetInitUnwindInfoDelegateType() const { return initUnwindInfoDelegateType; }
114     FunctionSymbol* GetSystemRuntimeAddCompileUnitFunctionSymbol() const { return systemRuntimeAddCompileUnitFunctionSymbol; }
115     void SetSystemRuntimeAddCompileUnitFunctionSymbol(FunctionSymbol* systemRuntimeAddCompileUnitFunctionSymbol_) { systemRuntimeAddCompileUnitFunctionSymbol = systemRuntimeAddCompileUnitFunctionSymbol_; }
116     void GenerateGlobalInitializationFunction();
117     FunctionSymbol* GetGlobalInitializationFunctionSymbol() const { return globalInitFunctionSymbol; }
118     const std::std::vector<std::std::unique_ptr<FunctionSymbol>>&AllCompileUnitInitFunctionSymbols() const{returnallCompileUnitInitFunctionSymbols;}
119     bool CodeGenerated(FunctionSymbol* functionSymbol) const;
120     void SetCodeGenerated(FunctionSymbol* functionSymbol);
121     bool CanReuse(FunctionSymbol* functionSymbol) const;
122     void SetCanReuse(FunctionSymbol* functionSymbol);
123     void SetLatestIdentifier(IdentifierNode* latestIdentifierNode_) { latestIdentifierNode = latestIdentifierNode_; }
124     IdentifierNode* GetLatestIdentifier() { return latestIdentifierNode; }
125 private:
126     Module& module;
127     SymbolTable& symbolTable;
128     IdentifierNode* latestIdentifierNode;
129     CompileUnitNode* compileUnitNode;
130     AttributeBinder* attributeBinder;
131     std::stack<BoundNamespace*> namespaceStack;
132     BoundNamespace* currentNamespace;
133     std::string llFilePath;
134     std::string bcFilePath;
135     std::string optBCFilePath;
136     std::string optLLFilePath;
137     std::string objectFilePath;
138     std::string cppFilePath;
139     std::vector<std::std::unique_ptr<FileScope>>fileScopes;
140     std::vector<std::std::unique_ptr<BoundNode>>boundNodes;
141     std::vector<std::std::unique_ptr<NamespaceNode>>globalNamespaceNodes;
142     bool hasGotos;
143     OperationRepository operationRepository;
144     FunctionTemplateRepository functionTemplateRepository;
145     ClassTemplateRepository classTemplateRepository;
146     InlineFunctionRepository inlineFunctionRepository;
147     ConstExprFunctionRepository constExprFunctionRepository;
148     StringRepository<std::stringconst unsigned char*> utf8StringRepository;
149     StringRepository<std::u16stringconst char16_t*> utf16StringRepository;
150     StringRepository<std::u32stringconst char32_t*> utf32StringRepository;
151     UuidRepository uuidRepository;
152     ConstantArrayRepository constantArrayRepository;
153     ConstantStructureRepository constantStructureRepository;
154     ConceptRepository conceptRepository;
155     ConversionTable conversionTable;
156     bool bindingTypes;
157     std::stack<bool> bindingTypesStack;
158     int32_t compileUnitIndex;
159     bool immutable;
160     std::unordered_map<boost::uuids::uuidFunctionSymbol*boost::boost::hash<boost::uuids::uuid>>copyConstructorMap;
161     std::vector<std::std::unique_ptr<FunctionSymbol>>copyConstructors;
162     int nextExitEntryIndex;
163     std::set<DestructorSymbol*> instantiatedGeneratedDestructors;
164     std::set<FunctionSymbol*> codeGenerated;
165     std::set<FunctionSymbol*> canReuse;
166     TypeSymbol* systemRuntimeUnwindInfoSymbol;
167     std::unique_ptr<FunctionSymbol> initUnwindInfoFunctionSymbol;
168     std::unique_ptr<FunctionSymbol> initCompileUnitFunctionSymbol;
169     FunctionSymbol* systemRuntimeAddCompileUnitFunctionSymbol;
170     FunctionSymbol* pushCompileUnitUnwindInfoInitFunctionSymbol;
171     TypeSymbol* initUnwindInfoDelegateType;
172     std::unique_ptr<GlobalVariableSymbol> compileUnitUnwindInfoVarSymbol;
173     FunctionSymbol* globalInitFunctionSymbol;
174     std::vector<std::std::unique_ptr<FunctionSymbol>>allCompileUnitInitFunctionSymbols;
175 };
176 
177 } } // namespace cmajor::binder
178 
179 #endif // CMAJOR_BINDER_BOUND_COMPILE_UNIT_INCLUDED