1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/symbols/TemplateSymbol.hpp>
  7 #include <cmajor/symbols/SymbolTable.hpp>
  8 #include <cmajor/symbols/Exception.hpp>
  9 #include <cmajor/symbols/Module.hpp>
 10 #include <cmajor/symbols/SymbolWriter.hpp>
 11 #include <cmajor/symbols/SymbolReader.hpp>
 12 #include <soulng/util/Unicode.hpp>
 13 #include <soulng/util/Sha1.hpp>
 14 #include <boost/uuid/uuid_generators.hpp>
 15 
 16 namespace cmajor { namespace symbols {
 17 
 18 using namespace soulng::unicode;
 19 
 20 TemplateParameterSymbol::TemplateParameterSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_) :
 21     TypeSymbol(SymbolType::templateParameterSymbolspan_sourceModuleId_name_)hasDefault(false)defaultType(nullptr)
 22 {
 23 }
 24 
 25 void TemplateParameterSymbol::Write(SymbolWriter& writer)
 26 {
 27     TypeSymbol::Write(writer);
 28     writer.GetBinaryWriter().Write(hasDefault);
 29     if (hasDefault)
 30     {
 31         boost::uuids::uuid defaultTypeId = boost::uuids::nil_uuid();
 32         if (defaultType != nullptr)
 33         {
 34             defaultTypeId = defaultType->TypeId();
 35         }
 36         writer.GetBinaryWriter().Write(defaultTypeId);
 37     }
 38 }
 39 
 40 void TemplateParameterSymbol::Read(SymbolReader& reader)
 41 {
 42     TypeSymbol::Read(reader);
 43     hasDefault = reader.GetBinaryReader().ReadBool();
 44     if (hasDefault)
 45     {
 46         boost::uuids::uuid defaultTypeId;
 47         reader.GetBinaryReader().ReadUuid(defaultTypeId);
 48         if (!defaultTypeId.is_nil())
 49         {
 50             reader.GetSymbolTable()->EmplaceTypeRequest(readerthisdefaultTypeId0);
 51         }
 52     }
 53 }
 54 
 55 void TemplateParameterSymbol::EmplaceType(TypeSymbol* typeSymbolint index)
 56 {
 57     Assert(index == 0"invalid emplace type index");
 58     defaultType = typeSymbol;
 59 }
 60 
 61 TypeSymbol* TemplateParameterSymbol::Unify(TypeSymbol* typeconst Span& spanconst boost::uuids::uuid& moduleId)
 62 {
 63     return type;
 64 }
 65 
 66 TypeSymbol* TemplateParameterSymbol::UnifyTemplateArgumentType(SymbolTable& symbolTableconst std::std::unordered_map<TemplateParameterSymbol*TypeSymbol*>&templateParameterMapconstSpan&spanconstboost::uuids::uuid&moduleId)
 67 {
 68     auto it = templateParameterMap.find(this);
 69     if (it != templateParameterMap.cend())
 70     {
 71         return it->second;
 72     }
 73     else
 74     {
 75         return nullptr;
 76     }
 77 }
 78 
 79 BoundTemplateParameterSymbol::BoundTemplateParameterSymbol(const Span& span_const boost::uuids::uuid& sourceModuleId_const std::u32string& name_) :
 80     Symbol(SymbolType::boundTemplateParameterSymbolspan_sourceModuleId_name_)type(nullptr)
 81 {
 82 }
 83 
 84 void BoundTemplateParameterSymbol::Write(SymbolWriter& writer)
 85 {
 86     Symbol::Write(writer);
 87     writer.GetBinaryWriter().Write(type->TypeId());
 88 }
 89 
 90 void BoundTemplateParameterSymbol::Read(SymbolReader& reader)
 91 {
 92     Symbol::Read(reader);
 93     boost::uuids::uuid typeId;
 94     reader.GetBinaryReader().ReadUuid(typeId);
 95     reader.GetSymbolTable()->EmplaceTypeRequest(readerthistypeId0);
 96 }
 97 
 98 std::std::unique_ptr<sngxml::dom::Element>BoundTemplateParameterSymbol::CreateDomElement(TypeMap&typeMap)
 99 {
100     std::unique_ptr<sngxml::dom::Element> element(new sngxml::dom::Element(U"BoundTemplateParameterSymbol"));
101     if (type)
102     {
103         std::unique_ptr<sngxml::dom::Element> typeElement(new sngxml::dom::Element(U"type"));
104         int typeId = typeMap.GetOrInsertType(type);
105         typeElement->SetAttribute(U"ref"U"type_" + ToUtf32(std::to_string(typeId)));
106         element->AppendChild(std::unique_ptr<sngxml::dom::Node>(typeElement.release()));
107     }
108     return element;
109 }
110 
111 void BoundTemplateParameterSymbol::Check()
112 {
113     Symbol::Check();
114     if (!type)
115     {
116         throw SymbolCheckException("bound template parameter symbol contains null type pointer"GetSpan()SourceModuleId());
117     }
118 }
119 
120 } } // namespace cmajor::symbols