1
2
3
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::templateParameterSymbol, span_, 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(reader, this, defaultTypeId, 0);
51 }
52 }
53 }
54
55 void TemplateParameterSymbol::EmplaceType(TypeSymbol* typeSymbol, int index)
56 {
57 Assert(index == 0, "invalid emplace type index");
58 defaultType = typeSymbol;
59 }
60
61 TypeSymbol* TemplateParameterSymbol::Unify(TypeSymbol* type, const Span& span, const boost::uuids::uuid& moduleId)
62 {
63 return type;
64 }
65
66 TypeSymbol* TemplateParameterSymbol::UnifyTemplateArgumentType(SymbolTable& symbolTable, const std::std::unordered_map<TemplateParameterSymbol*, TypeSymbol*>&templateParameterMap, constSpan&span, constboost::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::boundTemplateParameterSymbol, span_, 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(reader, this, typeId, 0);
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 } }