1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/cmsxi/Metadata.hpp>
  7 #include <cmajor/cmsxi/BasicBlock.hpp>
  8 #include <soulng/util/TextUtils.hpp>
  9 
 10 namespace cmsxi {
 11 
 12 MDItem::MDItem(MDItemKind kind_) : kind(kind_)
 13 {
 14 }
 15 
 16 MDItem::~MDItem()
 17 {
 18 }
 19 
 20 MDBool::MDBool(bool value_) : MDItem(MDItemKind::bool_)value(value_)
 21 {
 22 }
 23 
 24 void MDBool::Write(CodeFormatter& formatter)
 25 {
 26     if (value)
 27     {
 28         formatter.Write("true");
 29     }
 30     else
 31     {
 32         formatter.Write("false");
 33     }
 34 }
 35 
 36 MDLong::MDLong(int64_t value_) : MDItem(MDItemKind::long_)value(value_)
 37 {
 38 }
 39 
 40 void MDLong::Write(CodeFormatter& formatter)
 41 {
 42     formatter.Write(std::to_string(value));
 43 }
 44 
 45 MDString::MDString(const std::string& value_) : MDItem(MDItemKind::string)value(value_)
 46 {
 47 }
 48 
 49 void MDString::Write(CodeFormatter& formatter)
 50 {
 51     formatter.Write("\"");
 52     formatter.Write(StringStr(value));
 53     formatter.Write("\"");
 54 }
 55 
 56 MDStructRef::MDStructRef(int id_) : MDItem(MDItemKind::structRef)id(id_)
 57 {
 58 }
 59 
 60 void MDStructRef::Write(CodeFormatter& formatter)
 61 {
 62     formatter.Write("!" + std::to_string(id));
 63 }
 64 
 65 MDStruct::MDStruct(int id_) : MDItem(MDItemKind::struct_)id(id_)
 66 {
 67 }
 68 
 69 void MDStruct::Write(CodeFormatter& formatter)
 70 {
 71     formatter.Write("!" + std::to_string(id));
 72 }
 73 
 74 void MDStruct::WriteDefinition(CodeFormatter& formatter)
 75 {
 76     formatter.Write("!" + std::to_string(id) + " = {");
 77     bool first = true;
 78     for (const auto& item : items)
 79     {
 80         if (first)
 81         {
 82             first = false;
 83         }
 84         else
 85         {
 86             formatter.Write(", ");
 87         }
 88         formatter.Write(item.first);
 89         formatter.Write(": ")
 90         item.second->Write(formatter);
 91     }
 92     formatter.WriteLine("}");
 93 }
 94 
 95 void MDStruct::AddItem(const std::string& fieldNameMDItem* item)
 96 {
 97     items.push_back(std::make_pair(fieldNameitem));
 98 }
 99 
100 MDBasicBlockRef::MDBasicBlockRef(void* bb_) : MDItem(MDItemKind::basicBlockRef)bb(bb_)
101 {
102 }
103 
104 void MDBasicBlockRef::Write(CodeFormatter& formatter)
105 {
106     BasicBlock* basicBlock = static_cast<BasicBlock*>(bb);
107     formatter.Write(std::to_string(basicBlock->Id()));
108 }
109 
110 Metadata::Metadata() : mdTrue(true)mdFalse(false)
111 {
112 }
113 
114 MDBool* Metadata::CreateMDBool(bool value)
115 {
116     if (value)
117     {
118         return &mdTrue;
119     }
120     else
121     {
122         return &mdFalse;
123     }
124 }
125 
126 MDLong* Metadata::CreateMDLong(int64_t value)
127 {
128     MDLong* item = new MDLong(value);
129     AddItem(item);
130     return item;
131 }
132 
133 MDString* Metadata::CreateMDString(const std::string& value)
134 {
135     MDString* item = new MDString(value);
136     AddItem(item);
137     return item;
138 }
139 
140 void Metadata::AddItem(MDItem* item)
141 {
142     items.push_back(std::unique_ptr<MDItem>(item));;
143 }
144 
145 MDStructRef* Metadata::CreateMDStructRef(int id)
146 {
147     MDStructRef* item = new MDStructRef(id);
148     AddItem(item);
149     return item;
150 }
151 
152 MDStruct* Metadata::CreateMDStruct()
153 {
154     MDStruct* item = new MDStruct(structs.size());
155     structs.push_back(std::unique_ptr<MDStruct>(item));
156     return item;
157 }
158 
159 MDBasicBlockRef* Metadata::CreateMDBasicBlockRef(void* bb)
160 {
161     MDBasicBlockRef* item = new MDBasicBlockRef(bb);
162     AddItem(item);
163     return item;
164 }
165 
166 void Metadata::Write(CodeFormatter& formatter)
167 {
168     if (structs.empty()) return;
169     formatter.WriteLine();
170     formatter.WriteLine("metadata");
171     formatter.WriteLine("{");
172     formatter.IncIndent();
173     for (const auto& s : structs)
174     {
175         s->WriteDefinition(formatter);
176     }
177     formatter.DecIndent();
178     formatter.WriteLine("}");
179 }
180 
181 } // namespace cmsxi