blob: 43a0e102d7e1f3fd02c01c08588b89ce3ef82797 [file] [log] [blame]
Nick Kledzikf60a9272012-12-12 20:46:15 +00001//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Rafael Espindola2a826e42014-06-13 17:20:48 +000010#include "llvm/Support/Errc.h"
Nick Kledzikf60a9272012-12-12 20:46:15 +000011#include "llvm/ADT/Twine.h"
12#include "llvm/Support/Casting.h"
13#include "llvm/Support/ErrorHandling.h"
Benjamin Kramercbe05842012-12-12 20:55:44 +000014#include "llvm/Support/Format.h"
Nick Kledzikf60a9272012-12-12 20:46:15 +000015#include "llvm/Support/YAMLParser.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000016#include "llvm/Support/YAMLTraits.h"
Benjamin Kramercbe05842012-12-12 20:55:44 +000017#include "llvm/Support/raw_ostream.h"
Rui Ueyama106eded2013-09-11 04:00:08 +000018#include <cctype>
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000019#include <cstring>
Benjamin Kramer36b0f122012-12-12 22:40:02 +000020using namespace llvm;
21using namespace yaml;
Nick Kledzikf60a9272012-12-12 20:46:15 +000022
23//===----------------------------------------------------------------------===//
24// IO
25//===----------------------------------------------------------------------===//
26
27IO::IO(void *Context) : Ctxt(Context) {
28}
29
30IO::~IO() {
31}
32
33void *IO::getContext() {
34 return Ctxt;
35}
36
37void IO::setContext(void *Context) {
38 Ctxt = Context;
39}
40
Nick Kledzikf60a9272012-12-12 20:46:15 +000041//===----------------------------------------------------------------------===//
42// Input
43//===----------------------------------------------------------------------===//
44
Alexander Kornienko681e37c2013-11-18 15:50:04 +000045Input::Input(StringRef InputContent,
46 void *Ctxt,
47 SourceMgr::DiagHandlerTy DiagHandler,
48 void *DiagHandlerCtxt)
Rui Ueyama38dfffa2013-09-11 00:53:07 +000049 : IO(Ctxt),
Nick Kledzik0dcef842013-01-08 21:04:44 +000050 Strm(new Stream(InputContent, SrcMgr)),
Craig Topperc10719f2014-04-07 04:17:22 +000051 CurrentNode(nullptr) {
Alexander Kornienko681e37c2013-11-18 15:50:04 +000052 if (DiagHandler)
53 SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
Nick Kledzikf60a9272012-12-12 20:46:15 +000054 DocIterator = Strm->begin();
55}
56
Nick Kledzik0dcef842013-01-08 21:04:44 +000057Input::~Input() {
Nick Kledzik0dcef842013-01-08 21:04:44 +000058}
59
Rafael Espindoladb4ed0b2014-06-13 02:24:39 +000060std::error_code Input::error() { return EC; }
Nick Kledzikf60a9272012-12-12 20:46:15 +000061
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000062// Pin the vtables to this file.
63void Input::HNode::anchor() {}
64void Input::EmptyHNode::anchor() {}
65void Input::ScalarHNode::anchor() {}
David Blaikied759fe52014-09-15 18:39:24 +000066void Input::MapHNode::anchor() {}
67void Input::SequenceHNode::anchor() {}
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +000068
Nick Kledzik4761c602013-11-21 00:20:10 +000069bool Input::outputting() {
Nick Kledzikf60a9272012-12-12 20:46:15 +000070 return false;
71}
72
73bool Input::setCurrentDocument() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +000074 if (DocIterator != Strm->end()) {
Nick Kledzikf60a9272012-12-12 20:46:15 +000075 Node *N = DocIterator->getRoot();
Alexander Kornienko681e37c2013-11-18 15:50:04 +000076 if (!N) {
77 assert(Strm->failed() && "Root is NULL iff parsing failed");
Rafael Espindola2a826e42014-06-13 17:20:48 +000078 EC = make_error_code(errc::invalid_argument);
Alexander Kornienko681e37c2013-11-18 15:50:04 +000079 return false;
80 }
81
Benjamin Kramer36b0f122012-12-12 22:40:02 +000082 if (isa<NullNode>(N)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +000083 // Empty files are allowed and ignored
84 ++DocIterator;
85 return setCurrentDocument();
86 }
David Blaikied759fe52014-09-15 18:39:24 +000087 TopNode = this->createHNodes(N);
Nick Kledzik0dcef842013-01-08 21:04:44 +000088 CurrentNode = TopNode.get();
Nick Kledzikf60a9272012-12-12 20:46:15 +000089 return true;
90 }
91 return false;
92}
93
Simon Atanasyanf97af8a2014-05-31 04:51:07 +000094bool Input::nextDocument() {
95 return ++DocIterator != Strm->end();
Nick Kledzikf60a9272012-12-12 20:46:15 +000096}
NAKAMURA Takumi9439c522013-11-14 07:08:49 +000097
Nick Kledzik1e6033c2013-11-14 00:59:59 +000098bool Input::mapTag(StringRef Tag, bool Default) {
NAKAMURA Takumi5b94d282013-11-14 07:08:56 +000099 std::string foundTag = CurrentNode->_node->getVerbatimTag();
Nick Kledzik1e6033c2013-11-14 00:59:59 +0000100 if (foundTag.empty()) {
101 // If no tag found and 'Tag' is the default, say it was found.
102 return Default;
103 }
104 // Return true iff found tag matches supplied tag.
105 return Tag.equals(foundTag);
106}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000107
108void Input::beginMapping() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000109 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000110 return;
Alexander Kornienko681e37c2013-11-18 15:50:04 +0000111 // CurrentNode can be null if the document is empty.
112 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000113 if (MN) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000114 MN->ValidKeys.clear();
115 }
116}
117
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000118bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
119 void *&SaveInfo) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000120 UseDefault = false;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000121 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000122 return false;
Alexander Kornienko681e37c2013-11-18 15:50:04 +0000123
124 // CurrentNode is null for empty documents, which is an error in case required
125 // nodes are present.
126 if (!CurrentNode) {
127 if (Required)
Rafael Espindola2a826e42014-06-13 17:20:48 +0000128 EC = make_error_code(errc::invalid_argument);
Alexander Kornienko681e37c2013-11-18 15:50:04 +0000129 return false;
130 }
131
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000132 MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
133 if (!MN) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000134 setError(CurrentNode, "not a mapping");
135 return false;
136 }
137 MN->ValidKeys.push_back(Key);
David Blaikied759fe52014-09-15 18:39:24 +0000138 HNode *Value = MN->Mapping[Key].get();
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000139 if (!Value) {
140 if (Required)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000141 setError(CurrentNode, Twine("missing required key '") + Key + "'");
142 else
143 UseDefault = true;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000144 return false;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000145 }
146 SaveInfo = CurrentNode;
147 CurrentNode = Value;
148 return true;
149}
150
151void Input::postflightKey(void *saveInfo) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000152 CurrentNode = reinterpret_cast<HNode *>(saveInfo);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000153}
154
155void Input::endMapping() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000156 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000157 return;
Alexander Kornienko681e37c2013-11-18 15:50:04 +0000158 // CurrentNode can be null if the document is empty.
159 MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000160 if (!MN)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000161 return;
Simon Atanasyan878bd8a2014-04-10 06:02:49 +0000162 for (const auto &NN : MN->Mapping) {
163 if (!MN->isValidKey(NN.first())) {
David Blaikied759fe52014-09-15 18:39:24 +0000164 setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
Nick Kledzikf60a9272012-12-12 20:46:15 +0000165 break;
166 }
167 }
168}
169
Nick Kledzikf60a9272012-12-12 20:46:15 +0000170unsigned Input::beginSequence() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000171 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000172 return SQ->Entries.size();
173 }
174 return 0;
175}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000176
Nick Kledzikf60a9272012-12-12 20:46:15 +0000177void Input::endSequence() {
178}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000179
Nick Kledzikf60a9272012-12-12 20:46:15 +0000180bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000181 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000182 return false;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000183 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000184 SaveInfo = CurrentNode;
David Blaikied759fe52014-09-15 18:39:24 +0000185 CurrentNode = SQ->Entries[Index].get();
Nick Kledzikf60a9272012-12-12 20:46:15 +0000186 return true;
187 }
188 return false;
189}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000190
Nick Kledzikf60a9272012-12-12 20:46:15 +0000191void Input::postflightElement(void *SaveInfo) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000192 CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000193}
194
195unsigned Input::beginFlowSequence() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000196 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000197 return SQ->Entries.size();
198 }
199 return 0;
200}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000201
Nick Kledzikf60a9272012-12-12 20:46:15 +0000202bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000203 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000204 return false;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000205 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000206 SaveInfo = CurrentNode;
David Blaikied759fe52014-09-15 18:39:24 +0000207 CurrentNode = SQ->Entries[index].get();
Nick Kledzikf60a9272012-12-12 20:46:15 +0000208 return true;
209 }
210 return false;
211}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000212
Nick Kledzikf60a9272012-12-12 20:46:15 +0000213void Input::postflightFlowElement(void *SaveInfo) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000214 CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000215}
216
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000217void Input::endFlowSequence() {
218}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000219
220void Input::beginEnumScalar() {
221 ScalarMatchFound = false;
222}
223
224bool Input::matchEnumScalar(const char *Str, bool) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000225 if (ScalarMatchFound)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000226 return false;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000227 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
228 if (SN->value().equals(Str)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000229 ScalarMatchFound = true;
230 return true;
231 }
232 }
233 return false;
234}
235
Michael J. Spencer731cae32015-01-23 21:57:50 +0000236bool Input::matchEnumFallback() {
237 if (ScalarMatchFound)
238 return false;
239 ScalarMatchFound = true;
240 return true;
241}
242
Nick Kledzikf60a9272012-12-12 20:46:15 +0000243void Input::endEnumScalar() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000244 if (!ScalarMatchFound) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000245 setError(CurrentNode, "unknown enumerated scalar");
246 }
247}
248
Nick Kledzikf60a9272012-12-12 20:46:15 +0000249bool Input::beginBitSetScalar(bool &DoClear) {
250 BitValuesUsed.clear();
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000251 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000252 BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000253 } else {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000254 setError(CurrentNode, "expected sequence of bit values");
255 }
256 DoClear = true;
257 return true;
258}
259
260bool Input::bitSetMatch(const char *Str, bool) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000261 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000262 return false;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000263 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000264 unsigned Index = 0;
David Blaikied759fe52014-09-15 18:39:24 +0000265 for (auto &N : SQ->Entries) {
266 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000267 if (SN->value().equals(Str)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000268 BitValuesUsed[Index] = true;
269 return true;
270 }
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000271 } else {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000272 setError(CurrentNode, "unexpected scalar in sequence of bit values");
273 }
274 ++Index;
275 }
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000276 } else {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000277 setError(CurrentNode, "expected sequence of bit values");
278 }
279 return false;
280}
281
282void Input::endBitSetScalar() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000283 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000284 return;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000285 if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000286 assert(BitValuesUsed.size() == SQ->Entries.size());
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000287 for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
288 if (!BitValuesUsed[i]) {
David Blaikied759fe52014-09-15 18:39:24 +0000289 setError(SQ->Entries[i].get(), "unknown bit value");
Nick Kledzikf60a9272012-12-12 20:46:15 +0000290 return;
291 }
292 }
293 }
294}
295
David Majnemer77880332014-04-10 07:37:33 +0000296void Input::scalarString(StringRef &S, bool) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000297 if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000298 S = SN->value();
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000299 } else {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000300 setError(CurrentNode, "unexpected scalar");
301 }
302}
303
304void Input::setError(HNode *hnode, const Twine &message) {
Alexander Kornienko681e37c2013-11-18 15:50:04 +0000305 assert(hnode && "HNode must not be NULL");
Nick Kledzikf60a9272012-12-12 20:46:15 +0000306 this->setError(hnode->_node, message);
307}
308
309void Input::setError(Node *node, const Twine &message) {
310 Strm->printError(node, message);
Rafael Espindola2a826e42014-06-13 17:20:48 +0000311 EC = make_error_code(errc::invalid_argument);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000312}
313
David Blaikied759fe52014-09-15 18:39:24 +0000314std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000315 SmallString<128> StringStorage;
316 if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000317 StringRef KeyStr = SN->getValue(StringStorage);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000318 if (!StringStorage.empty()) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000319 // Copy string to permanent storage
320 unsigned Len = StringStorage.size();
Nick Kledzik0dcef842013-01-08 21:04:44 +0000321 char *Buf = StringAllocator.Allocate<char>(Len);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000322 memcpy(Buf, &StringStorage[0], Len);
323 KeyStr = StringRef(Buf, Len);
324 }
David Blaikied759fe52014-09-15 18:39:24 +0000325 return llvm::make_unique<ScalarHNode>(N, KeyStr);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000326 } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
David Blaikied759fe52014-09-15 18:39:24 +0000327 auto SQHNode = llvm::make_unique<SequenceHNode>(N);
Simon Atanasyan878bd8a2014-04-10 06:02:49 +0000328 for (Node &SN : *SQ) {
David Blaikied759fe52014-09-15 18:39:24 +0000329 auto Entry = this->createHNodes(&SN);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000330 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000331 break;
David Blaikied759fe52014-09-15 18:39:24 +0000332 SQHNode->Entries.push_back(std::move(Entry));
Nick Kledzikf60a9272012-12-12 20:46:15 +0000333 }
David Blaikied759fe52014-09-15 18:39:24 +0000334 return std::move(SQHNode);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000335 } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
David Blaikied759fe52014-09-15 18:39:24 +0000336 auto mapHNode = llvm::make_unique<MapHNode>(N);
Simon Atanasyan878bd8a2014-04-10 06:02:49 +0000337 for (KeyValueNode &KVN : *Map) {
Rafael Espindolaa97373f2014-08-08 13:58:00 +0000338 Node *KeyNode = KVN.getKey();
339 ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KeyNode);
340 if (!KeyScalar) {
341 setError(KeyNode, "Map key must be a scalar");
342 break;
343 }
Nick Kledzikf60a9272012-12-12 20:46:15 +0000344 StringStorage.clear();
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000345 StringRef KeyStr = KeyScalar->getValue(StringStorage);
346 if (!StringStorage.empty()) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000347 // Copy string to permanent storage
348 unsigned Len = StringStorage.size();
Nick Kledzik0dcef842013-01-08 21:04:44 +0000349 char *Buf = StringAllocator.Allocate<char>(Len);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000350 memcpy(Buf, &StringStorage[0], Len);
351 KeyStr = StringRef(Buf, Len);
352 }
David Blaikied759fe52014-09-15 18:39:24 +0000353 auto ValueHNode = this->createHNodes(KVN.getValue());
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000354 if (EC)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000355 break;
David Blaikied759fe52014-09-15 18:39:24 +0000356 mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
Nick Kledzikf60a9272012-12-12 20:46:15 +0000357 }
David Blaikied759fe52014-09-15 18:39:24 +0000358 return std::move(mapHNode);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000359 } else if (isa<NullNode>(N)) {
David Blaikied759fe52014-09-15 18:39:24 +0000360 return llvm::make_unique<EmptyHNode>(N);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000361 } else {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000362 setError(N, "unknown node kind");
Craig Topperc10719f2014-04-07 04:17:22 +0000363 return nullptr;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000364 }
365}
366
Nick Kledzikf60a9272012-12-12 20:46:15 +0000367bool Input::MapHNode::isValidKey(StringRef Key) {
Simon Atanasyan878bd8a2014-04-10 06:02:49 +0000368 for (const char *K : ValidKeys) {
369 if (Key.equals(K))
Nick Kledzikf60a9272012-12-12 20:46:15 +0000370 return true;
371 }
372 return false;
373}
374
375void Input::setError(const Twine &Message) {
376 this->setError(CurrentNode, Message);
377}
378
Aaron Ballman0e63e532013-08-15 23:17:53 +0000379bool Input::canElideEmptySequence() {
380 return false;
381}
382
Nick Kledzikf60a9272012-12-12 20:46:15 +0000383//===----------------------------------------------------------------------===//
384// Output
385//===----------------------------------------------------------------------===//
386
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000387Output::Output(raw_ostream &yout, void *context)
388 : IO(context),
389 Out(yout),
390 Column(0),
391 ColumnAtFlowStart(0),
392 NeedBitValueComma(false),
393 NeedFlowSequenceComma(false),
394 EnumerationMatchFound(false),
395 NeedsNewLine(false) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000396}
397
398Output::~Output() {
399}
400
Nick Kledzik4761c602013-11-21 00:20:10 +0000401bool Output::outputting() {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000402 return true;
403}
404
405void Output::beginMapping() {
406 StateStack.push_back(inMapFirstKey);
407 NeedsNewLine = true;
408}
409
Nick Kledzik1e6033c2013-11-14 00:59:59 +0000410bool Output::mapTag(StringRef Tag, bool Use) {
411 if (Use) {
412 this->output(" ");
413 this->output(Tag);
414 }
415 return Use;
416}
417
Nick Kledzikf60a9272012-12-12 20:46:15 +0000418void Output::endMapping() {
419 StateStack.pop_back();
420}
421
Nick Kledzikf60a9272012-12-12 20:46:15 +0000422bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000423 bool &UseDefault, void *&) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000424 UseDefault = false;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000425 if (Required || !SameAsDefault) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000426 this->newLineCheck();
427 this->paddedKey(Key);
428 return true;
429 }
430 return false;
431}
432
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000433void Output::postflightKey(void *) {
434 if (StateStack.back() == inMapFirstKey) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000435 StateStack.pop_back();
436 StateStack.push_back(inMapOtherKey);
437 }
438}
439
440void Output::beginDocuments() {
441 this->outputUpToEndOfLine("---");
442}
443
444bool Output::preflightDocument(unsigned index) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000445 if (index > 0)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000446 this->outputUpToEndOfLine("\n---");
447 return true;
448}
449
450void Output::postflightDocument() {
451}
452
453void Output::endDocuments() {
454 output("\n...\n");
455}
456
457unsigned Output::beginSequence() {
458 StateStack.push_back(inSeq);
459 NeedsNewLine = true;
460 return 0;
461}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000462
Nick Kledzikf60a9272012-12-12 20:46:15 +0000463void Output::endSequence() {
464 StateStack.pop_back();
465}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000466
467bool Output::preflightElement(unsigned, void *&) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000468 return true;
469}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000470
471void Output::postflightElement(void *) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000472}
473
474unsigned Output::beginFlowSequence() {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000475 StateStack.push_back(inFlowSeq);
Nick Kledzik11964f22013-01-04 19:32:00 +0000476 this->newLineCheck();
Nick Kledzikf60a9272012-12-12 20:46:15 +0000477 ColumnAtFlowStart = Column;
478 output("[ ");
479 NeedFlowSequenceComma = false;
480 return 0;
481}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000482
Nick Kledzikf60a9272012-12-12 20:46:15 +0000483void Output::endFlowSequence() {
484 StateStack.pop_back();
485 this->outputUpToEndOfLine(" ]");
486}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000487
488bool Output::preflightFlowElement(unsigned, void *&) {
489 if (NeedFlowSequenceComma)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000490 output(", ");
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000491 if (Column > 70) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000492 output("\n");
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000493 for (int i = 0; i < ColumnAtFlowStart; ++i)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000494 output(" ");
495 Column = ColumnAtFlowStart;
496 output(" ");
497 }
498 return true;
499}
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000500
501void Output::postflightFlowElement(void *) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000502 NeedFlowSequenceComma = true;
503}
504
Nick Kledzikf60a9272012-12-12 20:46:15 +0000505void Output::beginEnumScalar() {
506 EnumerationMatchFound = false;
507}
508
509bool Output::matchEnumScalar(const char *Str, bool Match) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000510 if (Match && !EnumerationMatchFound) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000511 this->newLineCheck();
512 this->outputUpToEndOfLine(Str);
513 EnumerationMatchFound = true;
514 }
515 return false;
516}
517
Michael J. Spencer731cae32015-01-23 21:57:50 +0000518bool Output::matchEnumFallback() {
519 if (EnumerationMatchFound)
520 return false;
521 EnumerationMatchFound = true;
522 return true;
523}
524
Nick Kledzikf60a9272012-12-12 20:46:15 +0000525void Output::endEnumScalar() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000526 if (!EnumerationMatchFound)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000527 llvm_unreachable("bad runtime enum value");
528}
529
Nick Kledzikf60a9272012-12-12 20:46:15 +0000530bool Output::beginBitSetScalar(bool &DoClear) {
531 this->newLineCheck();
532 output("[ ");
533 NeedBitValueComma = false;
534 DoClear = false;
535 return true;
536}
537
538bool Output::bitSetMatch(const char *Str, bool Matches) {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000539 if (Matches) {
540 if (NeedBitValueComma)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000541 output(", ");
542 this->output(Str);
543 NeedBitValueComma = true;
544 }
545 return false;
546}
547
548void Output::endBitSetScalar() {
549 this->outputUpToEndOfLine(" ]");
550}
551
David Majnemer77880332014-04-10 07:37:33 +0000552void Output::scalarString(StringRef &S, bool MustQuote) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000553 this->newLineCheck();
Rui Ueyama106eded2013-09-11 04:00:08 +0000554 if (S.empty()) {
555 // Print '' for the empty string because leaving the field empty is not
556 // allowed.
557 this->outputUpToEndOfLine("''");
558 return;
559 }
David Majnemer77880332014-04-10 07:37:33 +0000560 if (!MustQuote) {
561 // Only quote if we must.
Nick Kledzikf60a9272012-12-12 20:46:15 +0000562 this->outputUpToEndOfLine(S);
563 return;
564 }
565 unsigned i = 0;
566 unsigned j = 0;
567 unsigned End = S.size();
568 output("'"); // Starting single quote.
569 const char *Base = S.data();
570 while (j < End) {
571 // Escape a single quote by doubling it.
572 if (S[j] == '\'') {
573 output(StringRef(&Base[i], j - i + 1));
574 output("'");
575 i = j + 1;
576 }
577 ++j;
578 }
579 output(StringRef(&Base[i], j - i));
580 this->outputUpToEndOfLine("'"); // Ending single quote.
581}
582
583void Output::setError(const Twine &message) {
584}
585
Aaron Ballman0e63e532013-08-15 23:17:53 +0000586bool Output::canElideEmptySequence() {
587 // Normally, with an optional key/value where the value is an empty sequence,
588 // the whole key/value can be not written. But, that produces wrong yaml
589 // if the key/value is the only thing in the map and the map is used in
590 // a sequence. This detects if the this sequence is the first key/value
591 // in map that itself is embedded in a sequnce.
Rui Ueyama38dfffa2013-09-11 00:53:07 +0000592 if (StateStack.size() < 2)
Aaron Ballman0e63e532013-08-15 23:17:53 +0000593 return true;
Rui Ueyama38dfffa2013-09-11 00:53:07 +0000594 if (StateStack.back() != inMapFirstKey)
Aaron Ballman0e63e532013-08-15 23:17:53 +0000595 return true;
596 return (StateStack[StateStack.size()-2] != inSeq);
597}
598
Nick Kledzikf60a9272012-12-12 20:46:15 +0000599void Output::output(StringRef s) {
600 Column += s.size();
601 Out << s;
602}
603
604void Output::outputUpToEndOfLine(StringRef s) {
605 this->output(s);
Richard Smith045e4f12012-12-22 00:15:13 +0000606 if (StateStack.empty() || StateStack.back() != inFlowSeq)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000607 NeedsNewLine = true;
608}
609
610void Output::outputNewLine() {
611 Out << "\n";
612 Column = 0;
613}
614
615// if seq at top, indent as if map, then add "- "
616// if seq in middle, use "- " if firstKey, else use " "
617//
618
619void Output::newLineCheck() {
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000620 if (!NeedsNewLine)
Nick Kledzikf60a9272012-12-12 20:46:15 +0000621 return;
622 NeedsNewLine = false;
623
624 this->outputNewLine();
625
626 assert(StateStack.size() > 0);
627 unsigned Indent = StateStack.size() - 1;
628 bool OutputDash = false;
629
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000630 if (StateStack.back() == inSeq) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000631 OutputDash = true;
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000632 } else if ((StateStack.size() > 1) && (StateStack.back() == inMapFirstKey) &&
633 (StateStack[StateStack.size() - 2] == inSeq)) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000634 --Indent;
635 OutputDash = true;
636 }
637
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000638 for (unsigned i = 0; i < Indent; ++i) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000639 output(" ");
640 }
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000641 if (OutputDash) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000642 output("- ");
643 }
644
645}
646
647void Output::paddedKey(StringRef key) {
648 output(key);
649 output(":");
650 const char *spaces = " ";
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000651 if (key.size() < strlen(spaces))
Nick Kledzikf60a9272012-12-12 20:46:15 +0000652 output(&spaces[key.size()]);
653 else
654 output(" ");
655}
656
657//===----------------------------------------------------------------------===//
658// traits for built-in types
659//===----------------------------------------------------------------------===//
660
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000661void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
662 Out << (Val ? "true" : "false");
663}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000664
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000665StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
666 if (Scalar.equals("true")) {
667 Val = true;
668 return StringRef();
669 } else if (Scalar.equals("false")) {
670 Val = false;
Nick Kledzikf60a9272012-12-12 20:46:15 +0000671 return StringRef();
672 }
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000673 return "invalid boolean";
674}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000675
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000676void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
677 raw_ostream &Out) {
678 Out << Val;
679}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000680
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000681StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
682 StringRef &Val) {
683 Val = Scalar;
684 return StringRef();
685}
Alex Rosenbergf298f162015-01-26 18:02:18 +0000686
John Thompson48e018a2013-11-19 17:28:21 +0000687void ScalarTraits<std::string>::output(const std::string &Val, void *,
688 raw_ostream &Out) {
689 Out << Val;
690}
691
692StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *,
693 std::string &Val) {
694 Val = Scalar.str();
695 return StringRef();
696}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000697
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000698void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
699 raw_ostream &Out) {
700 // use temp uin32_t because ostream thinks uint8_t is a character
701 uint32_t Num = Val;
702 Out << Num;
703}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000704
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000705StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
706 unsigned long long n;
707 if (getAsUnsignedInteger(Scalar, 0, n))
708 return "invalid number";
709 if (n > 0xFF)
710 return "out of range number";
711 Val = n;
712 return StringRef();
713}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000714
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000715void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
716 raw_ostream &Out) {
717 Out << Val;
718}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000719
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000720StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *,
721 uint16_t &Val) {
722 unsigned long long n;
723 if (getAsUnsignedInteger(Scalar, 0, n))
724 return "invalid number";
725 if (n > 0xFFFF)
726 return "out of range number";
727 Val = n;
728 return StringRef();
729}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000730
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000731void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
732 raw_ostream &Out) {
733 Out << Val;
734}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000735
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000736StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *,
737 uint32_t &Val) {
738 unsigned long long n;
739 if (getAsUnsignedInteger(Scalar, 0, n))
740 return "invalid number";
741 if (n > 0xFFFFFFFFUL)
742 return "out of range number";
743 Val = n;
744 return StringRef();
745}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000746
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000747void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
748 raw_ostream &Out) {
749 Out << Val;
750}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000751
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000752StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *,
753 uint64_t &Val) {
754 unsigned long long N;
755 if (getAsUnsignedInteger(Scalar, 0, N))
756 return "invalid number";
757 Val = N;
758 return StringRef();
759}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000760
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000761void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
762 // use temp in32_t because ostream thinks int8_t is a character
763 int32_t Num = Val;
764 Out << Num;
765}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000766
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000767StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
768 long long N;
769 if (getAsSignedInteger(Scalar, 0, N))
770 return "invalid number";
771 if ((N > 127) || (N < -128))
772 return "out of range number";
773 Val = N;
774 return StringRef();
775}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000776
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000777void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
778 raw_ostream &Out) {
779 Out << Val;
780}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000781
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000782StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
783 long long N;
784 if (getAsSignedInteger(Scalar, 0, N))
785 return "invalid number";
786 if ((N > INT16_MAX) || (N < INT16_MIN))
787 return "out of range number";
788 Val = N;
789 return StringRef();
790}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000791
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000792void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
793 raw_ostream &Out) {
794 Out << Val;
795}
796
797StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
798 long long N;
799 if (getAsSignedInteger(Scalar, 0, N))
800 return "invalid number";
801 if ((N > INT32_MAX) || (N < INT32_MIN))
802 return "out of range number";
803 Val = N;
804 return StringRef();
805}
806
807void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
808 raw_ostream &Out) {
809 Out << Val;
810}
811
812StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
813 long long N;
814 if (getAsSignedInteger(Scalar, 0, N))
815 return "invalid number";
816 Val = N;
817 return StringRef();
818}
819
820void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000821 Out << format("%g", Val);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000822}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000823
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000824StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
825 SmallString<32> buff(Scalar.begin(), Scalar.end());
826 char *end;
827 Val = strtod(buff.c_str(), &end);
828 if (*end != '\0')
829 return "invalid floating point number";
830 return StringRef();
831}
832
833void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
Nick Kledzikf60a9272012-12-12 20:46:15 +0000834 Out << format("%g", Val);
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000835}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000836
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000837StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
838 SmallString<32> buff(Scalar.begin(), Scalar.end());
839 char *end;
840 Val = strtod(buff.c_str(), &end);
841 if (*end != '\0')
842 return "invalid floating point number";
843 return StringRef();
844}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000845
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000846void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
847 uint8_t Num = Val;
848 Out << format("0x%02X", Num);
849}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000850
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000851StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
852 unsigned long long n;
853 if (getAsUnsignedInteger(Scalar, 0, n))
854 return "invalid hex8 number";
855 if (n > 0xFF)
856 return "out of range hex8 number";
857 Val = n;
858 return StringRef();
859}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000860
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000861void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
862 uint16_t Num = Val;
863 Out << format("0x%04X", Num);
864}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000865
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000866StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
867 unsigned long long n;
868 if (getAsUnsignedInteger(Scalar, 0, n))
869 return "invalid hex16 number";
870 if (n > 0xFFFF)
871 return "out of range hex16 number";
872 Val = n;
873 return StringRef();
874}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000875
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000876void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
877 uint32_t Num = Val;
878 Out << format("0x%08X", Num);
879}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000880
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000881StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
882 unsigned long long n;
883 if (getAsUnsignedInteger(Scalar, 0, n))
884 return "invalid hex32 number";
885 if (n > 0xFFFFFFFFUL)
886 return "out of range hex32 number";
887 Val = n;
888 return StringRef();
889}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000890
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000891void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
892 uint64_t Num = Val;
893 Out << format("0x%016llX", Num);
894}
Nick Kledzikf60a9272012-12-12 20:46:15 +0000895
Benjamin Kramer36b0f122012-12-12 22:40:02 +0000896StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
897 unsigned long long Num;
898 if (getAsUnsignedInteger(Scalar, 0, Num))
899 return "invalid hex64 number";
900 Val = Num;
901 return StringRef();
902}