LLVM  3.7.0
YAMLTraits.cpp
Go to the documentation of this file.
1 //===- 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 
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Support/Casting.h"
14 #include "llvm/Support/Errc.h"
16 #include "llvm/Support/Format.h"
20 #include <cctype>
21 #include <cstring>
22 using namespace llvm;
23 using namespace yaml;
24 
25 //===----------------------------------------------------------------------===//
26 // IO
27 //===----------------------------------------------------------------------===//
28 
29 IO::IO(void *Context) : Ctxt(Context) {
30 }
31 
33 }
34 
35 void *IO::getContext() {
36  return Ctxt;
37 }
38 
39 void IO::setContext(void *Context) {
40  Ctxt = Context;
41 }
42 
43 //===----------------------------------------------------------------------===//
44 // Input
45 //===----------------------------------------------------------------------===//
46 
47 Input::Input(StringRef InputContent,
48  void *Ctxt,
49  SourceMgr::DiagHandlerTy DiagHandler,
50  void *DiagHandlerCtxt)
51  : IO(Ctxt),
52  Strm(new Stream(InputContent, SrcMgr)),
53  CurrentNode(nullptr) {
54  if (DiagHandler)
55  SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
56  DocIterator = Strm->begin();
57 }
58 
60 }
61 
62 std::error_code Input::error() { return EC; }
63 
64 // Pin the vtables to this file.
65 void Input::HNode::anchor() {}
66 void Input::EmptyHNode::anchor() {}
67 void Input::ScalarHNode::anchor() {}
68 void Input::MapHNode::anchor() {}
69 void Input::SequenceHNode::anchor() {}
70 
71 bool Input::outputting() {
72  return false;
73 }
74 
76  if (DocIterator != Strm->end()) {
77  Node *N = DocIterator->getRoot();
78  if (!N) {
79  assert(Strm->failed() && "Root is NULL iff parsing failed");
81  return false;
82  }
83 
84  if (isa<NullNode>(N)) {
85  // Empty files are allowed and ignored
86  ++DocIterator;
87  return setCurrentDocument();
88  }
89  TopNode = this->createHNodes(N);
90  CurrentNode = TopNode.get();
91  return true;
92  }
93  return false;
94 }
95 
97  return ++DocIterator != Strm->end();
98 }
99 
100 const Node *Input::getCurrentNode() const {
101  return CurrentNode ? CurrentNode->_node : nullptr;
102 }
103 
104 bool Input::mapTag(StringRef Tag, bool Default) {
105  std::string foundTag = CurrentNode->_node->getVerbatimTag();
106  if (foundTag.empty()) {
107  // If no tag found and 'Tag' is the default, say it was found.
108  return Default;
109  }
110  // Return true iff found tag matches supplied tag.
111  return Tag.equals(foundTag);
112 }
113 
114 void Input::beginMapping() {
115  if (EC)
116  return;
117  // CurrentNode can be null if the document is empty.
118  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
119  if (MN) {
120  MN->ValidKeys.clear();
121  }
122 }
123 
124 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
125  void *&SaveInfo) {
126  UseDefault = false;
127  if (EC)
128  return false;
129 
130  // CurrentNode is null for empty documents, which is an error in case required
131  // nodes are present.
132  if (!CurrentNode) {
133  if (Required)
135  return false;
136  }
137 
138  MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
139  if (!MN) {
140  setError(CurrentNode, "not a mapping");
141  return false;
142  }
143  MN->ValidKeys.push_back(Key);
144  HNode *Value = MN->Mapping[Key].get();
145  if (!Value) {
146  if (Required)
147  setError(CurrentNode, Twine("missing required key '") + Key + "'");
148  else
149  UseDefault = true;
150  return false;
151  }
152  SaveInfo = CurrentNode;
153  CurrentNode = Value;
154  return true;
155 }
156 
157 void Input::postflightKey(void *saveInfo) {
158  CurrentNode = reinterpret_cast<HNode *>(saveInfo);
159 }
160 
161 void Input::endMapping() {
162  if (EC)
163  return;
164  // CurrentNode can be null if the document is empty.
165  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
166  if (!MN)
167  return;
168  for (const auto &NN : MN->Mapping) {
169  if (!MN->isValidKey(NN.first())) {
170  setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'");
171  break;
172  }
173  }
174 }
175 
176 void Input::beginFlowMapping() { beginMapping(); }
177 
178 void Input::endFlowMapping() { endMapping(); }
179 
180 unsigned Input::beginSequence() {
181  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
182  return SQ->Entries.size();
183  if (isa<EmptyHNode>(CurrentNode))
184  return 0;
185  // Treat case where there's a scalar "null" value as an empty sequence.
186  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
187  if (isNull(SN->value()))
188  return 0;
189  }
190  // Any other type of HNode is an error.
191  setError(CurrentNode, "not a sequence");
192  return 0;
193 }
194 
195 void Input::endSequence() {
196 }
197 
198 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
199  if (EC)
200  return false;
201  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
202  SaveInfo = CurrentNode;
203  CurrentNode = SQ->Entries[Index].get();
204  return true;
205  }
206  return false;
207 }
208 
209 void Input::postflightElement(void *SaveInfo) {
210  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
211 }
212 
213 unsigned Input::beginFlowSequence() { return beginSequence(); }
214 
215 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
216  if (EC)
217  return false;
218  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
219  SaveInfo = CurrentNode;
220  CurrentNode = SQ->Entries[index].get();
221  return true;
222  }
223  return false;
224 }
225 
226 void Input::postflightFlowElement(void *SaveInfo) {
227  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
228 }
229 
230 void Input::endFlowSequence() {
231 }
232 
233 void Input::beginEnumScalar() {
234  ScalarMatchFound = false;
235 }
236 
237 bool Input::matchEnumScalar(const char *Str, bool) {
238  if (ScalarMatchFound)
239  return false;
240  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
241  if (SN->value().equals(Str)) {
242  ScalarMatchFound = true;
243  return true;
244  }
245  }
246  return false;
247 }
248 
249 bool Input::matchEnumFallback() {
250  if (ScalarMatchFound)
251  return false;
252  ScalarMatchFound = true;
253  return true;
254 }
255 
256 void Input::endEnumScalar() {
257  if (!ScalarMatchFound) {
258  setError(CurrentNode, "unknown enumerated scalar");
259  }
260 }
261 
262 bool Input::beginBitSetScalar(bool &DoClear) {
263  BitValuesUsed.clear();
264  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
265  BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
266  } else {
267  setError(CurrentNode, "expected sequence of bit values");
268  }
269  DoClear = true;
270  return true;
271 }
272 
273 bool Input::bitSetMatch(const char *Str, bool) {
274  if (EC)
275  return false;
276  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
277  unsigned Index = 0;
278  for (auto &N : SQ->Entries) {
279  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
280  if (SN->value().equals(Str)) {
281  BitValuesUsed[Index] = true;
282  return true;
283  }
284  } else {
285  setError(CurrentNode, "unexpected scalar in sequence of bit values");
286  }
287  ++Index;
288  }
289  } else {
290  setError(CurrentNode, "expected sequence of bit values");
291  }
292  return false;
293 }
294 
295 void Input::endBitSetScalar() {
296  if (EC)
297  return;
298  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
299  assert(BitValuesUsed.size() == SQ->Entries.size());
300  for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
301  if (!BitValuesUsed[i]) {
302  setError(SQ->Entries[i].get(), "unknown bit value");
303  return;
304  }
305  }
306  }
307 }
308 
309 void Input::scalarString(StringRef &S, bool) {
310  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
311  S = SN->value();
312  } else {
313  setError(CurrentNode, "unexpected scalar");
314  }
315 }
316 
317 void Input::blockScalarString(StringRef &S) { scalarString(S, false); }
318 
319 void Input::setError(HNode *hnode, const Twine &message) {
320  assert(hnode && "HNode must not be NULL");
321  this->setError(hnode->_node, message);
322 }
323 
324 void Input::setError(Node *node, const Twine &message) {
325  Strm->printError(node, message);
327 }
328 
329 std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
330  SmallString<128> StringStorage;
331  if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
332  StringRef KeyStr = SN->getValue(StringStorage);
333  if (!StringStorage.empty()) {
334  // Copy string to permanent storage
335  unsigned Len = StringStorage.size();
336  char *Buf = StringAllocator.Allocate<char>(Len);
337  memcpy(Buf, &StringStorage[0], Len);
338  KeyStr = StringRef(Buf, Len);
339  }
340  return llvm::make_unique<ScalarHNode>(N, KeyStr);
341  } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
342  StringRef Value = BSN->getValue();
343  char *Buf = StringAllocator.Allocate<char>(Value.size());
344  memcpy(Buf, Value.data(), Value.size());
345  return llvm::make_unique<ScalarHNode>(N, StringRef(Buf, Value.size()));
346  } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
347  auto SQHNode = llvm::make_unique<SequenceHNode>(N);
348  for (Node &SN : *SQ) {
349  auto Entry = this->createHNodes(&SN);
350  if (EC)
351  break;
352  SQHNode->Entries.push_back(std::move(Entry));
353  }
354  return std::move(SQHNode);
355  } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
356  auto mapHNode = llvm::make_unique<MapHNode>(N);
357  for (KeyValueNode &KVN : *Map) {
358  Node *KeyNode = KVN.getKey();
359  ScalarNode *KeyScalar = dyn_cast<ScalarNode>(KeyNode);
360  if (!KeyScalar) {
361  setError(KeyNode, "Map key must be a scalar");
362  break;
363  }
364  StringStorage.clear();
365  StringRef KeyStr = KeyScalar->getValue(StringStorage);
366  if (!StringStorage.empty()) {
367  // Copy string to permanent storage
368  unsigned Len = StringStorage.size();
369  char *Buf = StringAllocator.Allocate<char>(Len);
370  memcpy(Buf, &StringStorage[0], Len);
371  KeyStr = StringRef(Buf, Len);
372  }
373  auto ValueHNode = this->createHNodes(KVN.getValue());
374  if (EC)
375  break;
376  mapHNode->Mapping[KeyStr] = std::move(ValueHNode);
377  }
378  return std::move(mapHNode);
379  } else if (isa<NullNode>(N)) {
380  return llvm::make_unique<EmptyHNode>(N);
381  } else {
382  setError(N, "unknown node kind");
383  return nullptr;
384  }
385 }
386 
387 bool Input::MapHNode::isValidKey(StringRef Key) {
388  for (const char *K : ValidKeys) {
389  if (Key.equals(K))
390  return true;
391  }
392  return false;
393 }
394 
395 void Input::setError(const Twine &Message) {
396  this->setError(CurrentNode, Message);
397 }
398 
399 bool Input::canElideEmptySequence() {
400  return false;
401 }
402 
403 //===----------------------------------------------------------------------===//
404 // Output
405 //===----------------------------------------------------------------------===//
406 
407 Output::Output(raw_ostream &yout, void *context, int WrapColumn)
408  : IO(context),
409  Out(yout),
410  WrapColumn(WrapColumn),
411  Column(0),
412  ColumnAtFlowStart(0),
413  ColumnAtMapFlowStart(0),
414  NeedBitValueComma(false),
415  NeedFlowSequenceComma(false),
416  EnumerationMatchFound(false),
417  NeedsNewLine(false) {
418 }
419 
421 }
422 
424  return true;
425 }
426 
428  StateStack.push_back(inMapFirstKey);
429  NeedsNewLine = true;
430 }
431 
432 bool Output::mapTag(StringRef Tag, bool Use) {
433  if (Use) {
434  this->output(" ");
435  this->output(Tag);
436  }
437  return Use;
438 }
439 
441  StateStack.pop_back();
442 }
443 
444 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
445  bool &UseDefault, void *&) {
446  UseDefault = false;
447  if (Required || !SameAsDefault) {
448  auto State = StateStack.back();
449  if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
450  flowKey(Key);
451  } else {
452  this->newLineCheck();
453  this->paddedKey(Key);
454  }
455  return true;
456  }
457  return false;
458 }
459 
460 void Output::postflightKey(void *) {
461  if (StateStack.back() == inMapFirstKey) {
462  StateStack.pop_back();
463  StateStack.push_back(inMapOtherKey);
464  } else if (StateStack.back() == inFlowMapFirstKey) {
465  StateStack.pop_back();
466  StateStack.push_back(inFlowMapOtherKey);
467  }
468 }
469 
471  StateStack.push_back(inFlowMapFirstKey);
472  this->newLineCheck();
473  ColumnAtMapFlowStart = Column;
474  output("{ ");
475 }
476 
478  StateStack.pop_back();
479  this->outputUpToEndOfLine(" }");
480 }
481 
483  this->outputUpToEndOfLine("---");
484 }
485 
486 bool Output::preflightDocument(unsigned index) {
487  if (index > 0)
488  this->outputUpToEndOfLine("\n---");
489  return true;
490 }
491 
493 }
494 
496  output("\n...\n");
497 }
498 
500  StateStack.push_back(inSeq);
501  NeedsNewLine = true;
502  return 0;
503 }
504 
506  StateStack.pop_back();
507 }
508 
509 bool Output::preflightElement(unsigned, void *&) {
510  return true;
511 }
512 
514 }
515 
517  StateStack.push_back(inFlowSeq);
518  this->newLineCheck();
519  ColumnAtFlowStart = Column;
520  output("[ ");
521  NeedFlowSequenceComma = false;
522  return 0;
523 }
524 
526  StateStack.pop_back();
527  this->outputUpToEndOfLine(" ]");
528 }
529 
530 bool Output::preflightFlowElement(unsigned, void *&) {
531  if (NeedFlowSequenceComma)
532  output(", ");
533  if (WrapColumn && Column > WrapColumn) {
534  output("\n");
535  for (int i = 0; i < ColumnAtFlowStart; ++i)
536  output(" ");
537  Column = ColumnAtFlowStart;
538  output(" ");
539  }
540  return true;
541 }
542 
544  NeedFlowSequenceComma = true;
545 }
546 
548  EnumerationMatchFound = false;
549 }
550 
551 bool Output::matchEnumScalar(const char *Str, bool Match) {
552  if (Match && !EnumerationMatchFound) {
553  this->newLineCheck();
554  this->outputUpToEndOfLine(Str);
555  EnumerationMatchFound = true;
556  }
557  return false;
558 }
559 
561  if (EnumerationMatchFound)
562  return false;
563  EnumerationMatchFound = true;
564  return true;
565 }
566 
568  if (!EnumerationMatchFound)
569  llvm_unreachable("bad runtime enum value");
570 }
571 
572 bool Output::beginBitSetScalar(bool &DoClear) {
573  this->newLineCheck();
574  output("[ ");
575  NeedBitValueComma = false;
576  DoClear = false;
577  return true;
578 }
579 
580 bool Output::bitSetMatch(const char *Str, bool Matches) {
581  if (Matches) {
582  if (NeedBitValueComma)
583  output(", ");
584  this->output(Str);
585  NeedBitValueComma = true;
586  }
587  return false;
588 }
589 
591  this->outputUpToEndOfLine(" ]");
592 }
593 
594 void Output::scalarString(StringRef &S, bool MustQuote) {
595  this->newLineCheck();
596  if (S.empty()) {
597  // Print '' for the empty string because leaving the field empty is not
598  // allowed.
599  this->outputUpToEndOfLine("''");
600  return;
601  }
602  if (!MustQuote) {
603  // Only quote if we must.
604  this->outputUpToEndOfLine(S);
605  return;
606  }
607  unsigned i = 0;
608  unsigned j = 0;
609  unsigned End = S.size();
610  output("'"); // Starting single quote.
611  const char *Base = S.data();
612  while (j < End) {
613  // Escape a single quote by doubling it.
614  if (S[j] == '\'') {
615  output(StringRef(&Base[i], j - i + 1));
616  output("'");
617  i = j + 1;
618  }
619  ++j;
620  }
621  output(StringRef(&Base[i], j - i));
622  this->outputUpToEndOfLine("'"); // Ending single quote.
623 }
624 
626  if (!StateStack.empty())
627  newLineCheck();
628  output(" |");
629  outputNewLine();
630 
631  unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
632 
633  auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
634  for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
635  for (unsigned I = 0; I < Indent; ++I) {
636  output(" ");
637  }
638  output(*Lines);
639  outputNewLine();
640  }
641 }
642 
643 void Output::setError(const Twine &message) {
644 }
645 
647  // Normally, with an optional key/value where the value is an empty sequence,
648  // the whole key/value can be not written. But, that produces wrong yaml
649  // if the key/value is the only thing in the map and the map is used in
650  // a sequence. This detects if the this sequence is the first key/value
651  // in map that itself is embedded in a sequnce.
652  if (StateStack.size() < 2)
653  return true;
654  if (StateStack.back() != inMapFirstKey)
655  return true;
656  return (StateStack[StateStack.size()-2] != inSeq);
657 }
658 
659 void Output::output(StringRef s) {
660  Column += s.size();
661  Out << s;
662 }
663 
664 void Output::outputUpToEndOfLine(StringRef s) {
665  this->output(s);
666  if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
667  StateStack.back() != inFlowMapFirstKey &&
668  StateStack.back() != inFlowMapOtherKey))
669  NeedsNewLine = true;
670 }
671 
672 void Output::outputNewLine() {
673  Out << "\n";
674  Column = 0;
675 }
676 
677 // if seq at top, indent as if map, then add "- "
678 // if seq in middle, use "- " if firstKey, else use " "
679 //
680 
681 void Output::newLineCheck() {
682  if (!NeedsNewLine)
683  return;
684  NeedsNewLine = false;
685 
686  this->outputNewLine();
687 
688  assert(StateStack.size() > 0);
689  unsigned Indent = StateStack.size() - 1;
690  bool OutputDash = false;
691 
692  if (StateStack.back() == inSeq) {
693  OutputDash = true;
694  } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
695  (StateStack.back() == inFlowSeq) ||
696  (StateStack.back() == inFlowMapFirstKey)) &&
697  (StateStack[StateStack.size() - 2] == inSeq)) {
698  --Indent;
699  OutputDash = true;
700  }
701 
702  for (unsigned i = 0; i < Indent; ++i) {
703  output(" ");
704  }
705  if (OutputDash) {
706  output("- ");
707  }
708 
709 }
710 
711 void Output::paddedKey(StringRef key) {
712  output(key);
713  output(":");
714  const char *spaces = " ";
715  if (key.size() < strlen(spaces))
716  output(&spaces[key.size()]);
717  else
718  output(" ");
719 }
720 
721 void Output::flowKey(StringRef Key) {
722  if (StateStack.back() == inFlowMapOtherKey)
723  output(", ");
724  if (WrapColumn && Column > WrapColumn) {
725  output("\n");
726  for (int I = 0; I < ColumnAtMapFlowStart; ++I)
727  output(" ");
728  Column = ColumnAtMapFlowStart;
729  output(" ");
730  }
731  output(Key);
732  output(": ");
733 }
734 
735 //===----------------------------------------------------------------------===//
736 // traits for built-in types
737 //===----------------------------------------------------------------------===//
738 
739 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
740  Out << (Val ? "true" : "false");
741 }
742 
744  if (Scalar.equals("true")) {
745  Val = true;
746  return StringRef();
747  } else if (Scalar.equals("false")) {
748  Val = false;
749  return StringRef();
750  }
751  return "invalid boolean";
752 }
753 
754 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
755  raw_ostream &Out) {
756  Out << Val;
757 }
758 
760  StringRef &Val) {
761  Val = Scalar;
762  return StringRef();
763 }
764 
765 void ScalarTraits<std::string>::output(const std::string &Val, void *,
766  raw_ostream &Out) {
767  Out << Val;
768 }
769 
771  std::string &Val) {
772  Val = Scalar.str();
773  return StringRef();
774 }
775 
776 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
777  raw_ostream &Out) {
778  // use temp uin32_t because ostream thinks uint8_t is a character
779  uint32_t Num = Val;
780  Out << Num;
781 }
782 
783 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
784  unsigned long long n;
785  if (getAsUnsignedInteger(Scalar, 0, n))
786  return "invalid number";
787  if (n > 0xFF)
788  return "out of range number";
789  Val = n;
790  return StringRef();
791 }
792 
793 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
794  raw_ostream &Out) {
795  Out << Val;
796 }
797 
799  uint16_t &Val) {
800  unsigned long long n;
801  if (getAsUnsignedInteger(Scalar, 0, n))
802  return "invalid number";
803  if (n > 0xFFFF)
804  return "out of range number";
805  Val = n;
806  return StringRef();
807 }
808 
809 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
810  raw_ostream &Out) {
811  Out << Val;
812 }
813 
815  uint32_t &Val) {
816  unsigned long long n;
817  if (getAsUnsignedInteger(Scalar, 0, n))
818  return "invalid number";
819  if (n > 0xFFFFFFFFUL)
820  return "out of range number";
821  Val = n;
822  return StringRef();
823 }
824 
825 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
826  raw_ostream &Out) {
827  Out << Val;
828 }
829 
831  uint64_t &Val) {
832  unsigned long long N;
833  if (getAsUnsignedInteger(Scalar, 0, N))
834  return "invalid number";
835  Val = N;
836  return StringRef();
837 }
838 
839 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
840  // use temp in32_t because ostream thinks int8_t is a character
841  int32_t Num = Val;
842  Out << Num;
843 }
844 
845 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
846  long long N;
847  if (getAsSignedInteger(Scalar, 0, N))
848  return "invalid number";
849  if ((N > 127) || (N < -128))
850  return "out of range number";
851  Val = N;
852  return StringRef();
853 }
854 
855 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
856  raw_ostream &Out) {
857  Out << Val;
858 }
859 
860 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
861  long long N;
862  if (getAsSignedInteger(Scalar, 0, N))
863  return "invalid number";
864  if ((N > INT16_MAX) || (N < INT16_MIN))
865  return "out of range number";
866  Val = N;
867  return StringRef();
868 }
869 
870 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
871  raw_ostream &Out) {
872  Out << Val;
873 }
874 
875 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
876  long long N;
877  if (getAsSignedInteger(Scalar, 0, N))
878  return "invalid number";
879  if ((N > INT32_MAX) || (N < INT32_MIN))
880  return "out of range number";
881  Val = N;
882  return StringRef();
883 }
884 
885 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
886  raw_ostream &Out) {
887  Out << Val;
888 }
889 
890 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
891  long long N;
892  if (getAsSignedInteger(Scalar, 0, N))
893  return "invalid number";
894  Val = N;
895  return StringRef();
896 }
897 
898 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
899  Out << format("%g", Val);
900 }
901 
902 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
903  SmallString<32> buff(Scalar.begin(), Scalar.end());
904  char *end;
905  Val = strtod(buff.c_str(), &end);
906  if (*end != '\0')
907  return "invalid floating point number";
908  return StringRef();
909 }
910 
911 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
912  Out << format("%g", Val);
913 }
914 
915 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
916  SmallString<32> buff(Scalar.begin(), Scalar.end());
917  char *end;
918  Val = strtod(buff.c_str(), &end);
919  if (*end != '\0')
920  return "invalid floating point number";
921  return StringRef();
922 }
923 
924 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
925  uint8_t Num = Val;
926  Out << format("0x%02X", Num);
927 }
928 
929 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
930  unsigned long long n;
931  if (getAsUnsignedInteger(Scalar, 0, n))
932  return "invalid hex8 number";
933  if (n > 0xFF)
934  return "out of range hex8 number";
935  Val = n;
936  return StringRef();
937 }
938 
939 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
940  uint16_t Num = Val;
941  Out << format("0x%04X", Num);
942 }
943 
944 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
945  unsigned long long n;
946  if (getAsUnsignedInteger(Scalar, 0, n))
947  return "invalid hex16 number";
948  if (n > 0xFFFF)
949  return "out of range hex16 number";
950  Val = n;
951  return StringRef();
952 }
953 
954 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
955  uint32_t Num = Val;
956  Out << format("0x%08X", Num);
957 }
958 
959 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
960  unsigned long long n;
961  if (getAsUnsignedInteger(Scalar, 0, n))
962  return "invalid hex32 number";
963  if (n > 0xFFFFFFFFUL)
964  return "out of range hex32 number";
965  Val = n;
966  return StringRef();
967 }
968 
969 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
970  uint64_t Num = Val;
971  Out << format("0x%016llX", Num);
972 }
973 
974 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
975  unsigned long long Num;
976  if (getAsUnsignedInteger(Scalar, 0, Num))
977  return "invalid hex64 number";
978  Val = Num;
979  return StringRef();
980 }
void setError(const Twine &message) override
Definition: YAMLTraits.cpp:643
void push_back(const T &Elt)
Definition: SmallVector.h:222
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:240
std::error_code error()
Definition: YAMLTraits.cpp:62
bool preflightElement(unsigned, void *&) override
Definition: YAMLTraits.cpp:509
bool preflightDocument(unsigned)
Definition: YAMLTraits.cpp:486
~Output() override
Definition: YAMLTraits.cpp:420
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
void beginMapping() override
Definition: YAMLTraits.cpp:427
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Definition: StringRef.cpp:339
SourceMgr SrcMgr
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
void endFlowMapping() override
Definition: YAMLTraits.cpp:477
StringRef getValue(SmallVectorImpl< char > &Storage) const
Gets the value of this node as a StringRef.
Represents a YAML sequence created from either a block sequence for a flow sequence.
Definition: YAMLParser.h:421
void * getContext()
Definition: YAMLTraits.cpp:35
void endSequence() override
Definition: YAMLTraits.cpp:505
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:188
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:32
void beginFlowMapping() override
Definition: YAMLTraits.cpp:470
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:79
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:98
A Use represents the edge between a Value definition and its users.
Definition: Use.h:69
void postflightElement(void *) override
Definition: YAMLTraits.cpp:513
bool matchEnumScalar(const char *, bool) override
Definition: YAMLTraits.cpp:551
std::error_code make_error_code(BitcodeError E)
Definition: ReaderWriter.h:150
Output(llvm::raw_ostream &, void *Ctxt=nullptr, int WrapColumn=70)
Definition: YAMLTraits.cpp:407
#define false
Definition: ConvertUTF.c:65
void scalarString(StringRef &, bool) override
Definition: YAMLTraits.cpp:594
bool matchEnumFallback() override
Definition: YAMLTraits.cpp:560
bool beginBitSetScalar(bool &) override
Definition: YAMLTraits.cpp:572
A key and value pair.
Definition: YAMLParser.h:263
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
Definition: SmallVector.h:57
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:107
bool outputting() override
Definition: YAMLTraits.cpp:423
bool mapTag(StringRef, bool) override
Definition: YAMLTraits.cpp:432
iterator begin() const
Definition: StringRef.h:90
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:111
void endMapping() override
Definition: YAMLTraits.cpp:440
const Node * getCurrentNode() const
Returns the current node that's being parsed by the YAML Parser.
Definition: YAMLTraits.cpp:100
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
Definition: SourceMgr.h:89
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
Definition: LineIterator.h:53
void postflightFlowElement(void *) override
Definition: YAMLTraits.cpp:543
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
Definition: Allocator.h:208
void(* DiagHandlerTy)(const SMDiagnostic &, void *Context)
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
Definition: SourceMgr.h:46
bool setCurrentDocument()
Definition: YAMLTraits.cpp:75
void endFlowSequence() override
Definition: YAMLTraits.cpp:525
bool preflightKey(const char *key, bool, bool, bool &, void *&) override
Definition: YAMLTraits.cpp:444
A scalar node is an opaque datum that can be presented as a series of zero or more Unicode scalar val...
Definition: YAMLParser.h:190
bool preflightFlowElement(unsigned, void *&) override
Definition: YAMLTraits.cpp:530
virtual ~IO()
Definition: YAMLTraits.cpp:32
This class represents a YAML stream potentially containing multiple documents.
Definition: YAMLParser.h:76
This class should be specialized by type that requires custom conversion to/from a yaml scalar...
Definition: YAMLTraits.h:109
void endBitSetScalar() override
Definition: YAMLTraits.cpp:590
bool bitSetMatch(const char *, bool) override
Definition: YAMLTraits.cpp:580
void setContext(void *)
Definition: YAMLTraits.cpp:39
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:285
bool equals(StringRef RHS) const
equals - Check for string equality, this is more efficient than compare() when the relative ordering ...
Definition: StringRef.h:136
unsigned beginFlowSequence() override
Definition: YAMLTraits.cpp:516
IO(void *Ctxt=nullptr)
Definition: YAMLTraits.cpp:29
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
A block scalar node is an opaque datum that can be presented as a series of zero or more Unicode scal...
Definition: YAMLParser.h:233
Represents a YAML map created from either a block map for a flow map.
Definition: YAMLParser.h:374
bool isNull(StringRef S)
Definition: YAMLTraits.h:422
LLVM Value Representation.
Definition: Value.h:69
Input(StringRef InputContent, void *Ctxt=nullptr, SourceMgr::DiagHandlerTy DiagHandler=nullptr, void *DiagHandlerCtxt=nullptr)
Definition: YAMLTraits.cpp:47
void beginEnumScalar() override
Definition: YAMLTraits.cpp:547
iterator end() const
Definition: StringRef.h:92
unsigned beginSequence() override
Definition: YAMLTraits.cpp:499
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
void endEnumScalar() override
Definition: YAMLTraits.cpp:567
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
Definition: StringRef.cpp:380
void postflightKey(void *) override
Definition: YAMLTraits.cpp:460
void blockScalarString(StringRef &) override
Definition: YAMLTraits.cpp:625
bool canElideEmptySequence() override
Definition: YAMLTraits.cpp:646
~Input() override
Definition: YAMLTraits.cpp:59
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110
Abstract base class for all Nodes.
Definition: YAMLParser.h:103