LLVM  14.0.0git
YAMLTraits.cpp
Go to the documentation of this file.
1 //===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/ADT/Twine.h"
15 #include "llvm/Support/Casting.h"
16 #include "llvm/Support/Errc.h"
18 #include "llvm/Support/Format.h"
21 #include "llvm/Support/Unicode.h"
24 #include <algorithm>
25 #include <cassert>
26 #include <cstdint>
27 #include <cstdlib>
28 #include <cstring>
29 #include <string>
30 #include <vector>
31 
32 using namespace llvm;
33 using namespace yaml;
34 
35 //===----------------------------------------------------------------------===//
36 // IO
37 //===----------------------------------------------------------------------===//
38 
39 IO::IO(void *Context) : Ctxt(Context) {}
40 
41 IO::~IO() = default;
42 
43 void *IO::getContext() const {
44  return Ctxt;
45 }
46 
47 void IO::setContext(void *Context) {
48  Ctxt = Context;
49 }
50 
51 void IO::setAllowUnknownKeys(bool Allow) {
52  llvm_unreachable("Only supported for Input");
53 }
54 
55 //===----------------------------------------------------------------------===//
56 // Input
57 //===----------------------------------------------------------------------===//
58 
59 Input::Input(StringRef InputContent, void *Ctxt,
60  SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
61  : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) {
62  if (DiagHandler)
63  SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
64  DocIterator = Strm->begin();
65 }
66 
67 Input::Input(MemoryBufferRef Input, void *Ctxt,
68  SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt)
69  : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) {
70  if (DiagHandler)
71  SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt);
72  DocIterator = Strm->begin();
73 }
74 
75 Input::~Input() = default;
76 
77 std::error_code Input::error() { return EC; }
78 
79 // Pin the vtables to this file.
80 void Input::HNode::anchor() {}
81 void Input::EmptyHNode::anchor() {}
82 void Input::ScalarHNode::anchor() {}
83 void Input::MapHNode::anchor() {}
84 void Input::SequenceHNode::anchor() {}
85 
86 bool Input::outputting() const {
87  return false;
88 }
89 
90 bool Input::setCurrentDocument() {
91  if (DocIterator != Strm->end()) {
92  Node *N = DocIterator->getRoot();
93  if (!N) {
95  return false;
96  }
97 
98  if (isa<NullNode>(N)) {
99  // Empty files are allowed and ignored
100  ++DocIterator;
101  return setCurrentDocument();
102  }
103  TopNode = createHNodes(N);
104  CurrentNode = TopNode.get();
105  return true;
106  }
107  return false;
108 }
109 
110 bool Input::nextDocument() {
111  return ++DocIterator != Strm->end();
112 }
113 
114 const Node *Input::getCurrentNode() const {
115  return CurrentNode ? CurrentNode->_node : nullptr;
116 }
117 
118 bool Input::mapTag(StringRef Tag, bool Default) {
119  // CurrentNode can be null if setCurrentDocument() was unable to
120  // parse the document because it was invalid or empty.
121  if (!CurrentNode)
122  return false;
123 
124  std::string foundTag = CurrentNode->_node->getVerbatimTag();
125  if (foundTag.empty()) {
126  // If no tag found and 'Tag' is the default, say it was found.
127  return Default;
128  }
129  // Return true iff found tag matches supplied tag.
130  return Tag.equals(foundTag);
131 }
132 
133 void Input::beginMapping() {
134  if (EC)
135  return;
136  // CurrentNode can be null if the document is empty.
137  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
138  if (MN) {
139  MN->ValidKeys.clear();
140  }
141 }
142 
143 std::vector<StringRef> Input::keys() {
144  MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
145  std::vector<StringRef> Ret;
146  if (!MN) {
147  setError(CurrentNode, "not a mapping");
148  return Ret;
149  }
150  for (auto &P : MN->Mapping)
151  Ret.push_back(P.first());
152  return Ret;
153 }
154 
155 bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
156  void *&SaveInfo) {
157  UseDefault = false;
158  if (EC)
159  return false;
160 
161  // CurrentNode is null for empty documents, which is an error in case required
162  // nodes are present.
163  if (!CurrentNode) {
164  if (Required)
166  return false;
167  }
168 
169  MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
170  if (!MN) {
171  if (Required || !isa<EmptyHNode>(CurrentNode))
172  setError(CurrentNode, "not a mapping");
173  else
174  UseDefault = true;
175  return false;
176  }
177  MN->ValidKeys.push_back(Key);
178  HNode *Value = MN->Mapping[Key].first.get();
179  if (!Value) {
180  if (Required)
181  setError(CurrentNode, Twine("missing required key '") + Key + "'");
182  else
183  UseDefault = true;
184  return false;
185  }
186  SaveInfo = CurrentNode;
187  CurrentNode = Value;
188  return true;
189 }
190 
191 void Input::postflightKey(void *saveInfo) {
192  CurrentNode = reinterpret_cast<HNode *>(saveInfo);
193 }
194 
195 void Input::endMapping() {
196  if (EC)
197  return;
198  // CurrentNode can be null if the document is empty.
199  MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode);
200  if (!MN)
201  return;
202  for (const auto &NN : MN->Mapping) {
203  if (!is_contained(MN->ValidKeys, NN.first())) {
204  const SMRange &ReportLoc = NN.second.second;
205  if (!AllowUnknownKeys) {
206  setError(ReportLoc, Twine("unknown key '") + NN.first() + "'");
207  break;
208  } else
209  reportWarning(ReportLoc, Twine("unknown key '") + NN.first() + "'");
210  }
211  }
212 }
213 
214 void Input::beginFlowMapping() { beginMapping(); }
215 
216 void Input::endFlowMapping() { endMapping(); }
217 
218 unsigned Input::beginSequence() {
219  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
220  return SQ->Entries.size();
221  if (isa<EmptyHNode>(CurrentNode))
222  return 0;
223  // Treat case where there's a scalar "null" value as an empty sequence.
224  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
225  if (isNull(SN->value()))
226  return 0;
227  }
228  // Any other type of HNode is an error.
229  setError(CurrentNode, "not a sequence");
230  return 0;
231 }
232 
233 void Input::endSequence() {
234 }
235 
236 bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
237  if (EC)
238  return false;
239  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
240  SaveInfo = CurrentNode;
241  CurrentNode = SQ->Entries[Index].get();
242  return true;
243  }
244  return false;
245 }
246 
247 void Input::postflightElement(void *SaveInfo) {
248  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
249 }
250 
251 unsigned Input::beginFlowSequence() { return beginSequence(); }
252 
253 bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
254  if (EC)
255  return false;
256  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
257  SaveInfo = CurrentNode;
258  CurrentNode = SQ->Entries[index].get();
259  return true;
260  }
261  return false;
262 }
263 
264 void Input::postflightFlowElement(void *SaveInfo) {
265  CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
266 }
267 
268 void Input::endFlowSequence() {
269 }
270 
271 void Input::beginEnumScalar() {
272  ScalarMatchFound = false;
273 }
274 
275 bool Input::matchEnumScalar(const char *Str, bool) {
276  if (ScalarMatchFound)
277  return false;
278  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
279  if (SN->value().equals(Str)) {
280  ScalarMatchFound = true;
281  return true;
282  }
283  }
284  return false;
285 }
286 
287 bool Input::matchEnumFallback() {
288  if (ScalarMatchFound)
289  return false;
290  ScalarMatchFound = true;
291  return true;
292 }
293 
294 void Input::endEnumScalar() {
295  if (!ScalarMatchFound) {
296  setError(CurrentNode, "unknown enumerated scalar");
297  }
298 }
299 
300 bool Input::beginBitSetScalar(bool &DoClear) {
301  BitValuesUsed.clear();
302  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
303  BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false);
304  } else {
305  setError(CurrentNode, "expected sequence of bit values");
306  }
307  DoClear = true;
308  return true;
309 }
310 
311 bool Input::bitSetMatch(const char *Str, bool) {
312  if (EC)
313  return false;
314  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
315  unsigned Index = 0;
316  for (auto &N : SQ->Entries) {
317  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) {
318  if (SN->value().equals(Str)) {
319  BitValuesUsed[Index] = true;
320  return true;
321  }
322  } else {
323  setError(CurrentNode, "unexpected scalar in sequence of bit values");
324  }
325  ++Index;
326  }
327  } else {
328  setError(CurrentNode, "expected sequence of bit values");
329  }
330  return false;
331 }
332 
333 void Input::endBitSetScalar() {
334  if (EC)
335  return;
336  if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
337  assert(BitValuesUsed.size() == SQ->Entries.size());
338  for (unsigned i = 0; i < SQ->Entries.size(); ++i) {
339  if (!BitValuesUsed[i]) {
340  setError(SQ->Entries[i].get(), "unknown bit value");
341  return;
342  }
343  }
344  }
345 }
346 
347 void Input::scalarString(StringRef &S, QuotingType) {
348  if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
349  S = SN->value();
350  } else {
351  setError(CurrentNode, "unexpected scalar");
352  }
353 }
354 
355 void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); }
356 
357 void Input::scalarTag(std::string &Tag) {
358  Tag = CurrentNode->_node->getVerbatimTag();
359 }
360 
361 void Input::setError(HNode *hnode, const Twine &message) {
362  assert(hnode && "HNode must not be NULL");
363  setError(hnode->_node, message);
364 }
365 
366 NodeKind Input::getNodeKind() {
367  if (isa<ScalarHNode>(CurrentNode))
368  return NodeKind::Scalar;
369  else if (isa<MapHNode>(CurrentNode))
370  return NodeKind::Map;
371  else if (isa<SequenceHNode>(CurrentNode))
372  return NodeKind::Sequence;
373  llvm_unreachable("Unsupported node kind");
374 }
375 
376 void Input::setError(Node *node, const Twine &message) {
377  Strm->printError(node, message);
379 }
380 
381 void Input::setError(const SMRange &range, const Twine &message) {
382  Strm->printError(range, message);
384 }
385 
386 void Input::reportWarning(HNode *hnode, const Twine &message) {
387  assert(hnode && "HNode must not be NULL");
388  Strm->printError(hnode->_node, message, SourceMgr::DK_Warning);
389 }
390 
391 void Input::reportWarning(Node *node, const Twine &message) {
392  Strm->printError(node, message, SourceMgr::DK_Warning);
393 }
394 
395 void Input::reportWarning(const SMRange &range, const Twine &message) {
396  Strm->printError(range, message, SourceMgr::DK_Warning);
397 }
398 
399 std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) {
400  SmallString<128> StringStorage;
401  if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) {
402  StringRef KeyStr = SN->getValue(StringStorage);
403  if (!StringStorage.empty()) {
404  // Copy string to permanent storage
405  KeyStr = StringStorage.str().copy(StringAllocator);
406  }
407  return std::make_unique<ScalarHNode>(N, KeyStr);
408  } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
409  StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
410  return std::make_unique<ScalarHNode>(N, ValueCopy);
411  } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
412  auto SQHNode = std::make_unique<SequenceHNode>(N);
413  for (Node &SN : *SQ) {
414  auto Entry = createHNodes(&SN);
415  if (EC)
416  break;
417  SQHNode->Entries.push_back(std::move(Entry));
418  }
419  return std::move(SQHNode);
420  } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) {
421  auto mapHNode = std::make_unique<MapHNode>(N);
422  for (KeyValueNode &KVN : *Map) {
423  Node *KeyNode = KVN.getKey();
424  ScalarNode *Key = dyn_cast_or_null<ScalarNode>(KeyNode);
425  Node *Value = KVN.getValue();
426  if (!Key || !Value) {
427  if (!Key)
428  setError(KeyNode, "Map key must be a scalar");
429  if (!Value)
430  setError(KeyNode, "Map value must not be empty");
431  break;
432  }
433  StringStorage.clear();
434  StringRef KeyStr = Key->getValue(StringStorage);
435  if (!StringStorage.empty()) {
436  // Copy string to permanent storage
437  KeyStr = StringStorage.str().copy(StringAllocator);
438  }
439  auto ValueHNode = createHNodes(Value);
440  if (EC)
441  break;
442  mapHNode->Mapping[KeyStr] =
443  std::make_pair(std::move(ValueHNode), KeyNode->getSourceRange());
444  }
445  return std::move(mapHNode);
446  } else if (isa<NullNode>(N)) {
447  return std::make_unique<EmptyHNode>(N);
448  } else {
449  setError(N, "unknown node kind");
450  return nullptr;
451  }
452 }
453 
454 void Input::setError(const Twine &Message) {
455  setError(CurrentNode, Message);
456 }
457 
458 void Input::setAllowUnknownKeys(bool Allow) { AllowUnknownKeys = Allow; }
459 
460 bool Input::canElideEmptySequence() {
461  return false;
462 }
463 
464 //===----------------------------------------------------------------------===//
465 // Output
466 //===----------------------------------------------------------------------===//
467 
468 Output::Output(raw_ostream &yout, void *context, int WrapColumn)
469  : IO(context), Out(yout), WrapColumn(WrapColumn) {}
470 
471 Output::~Output() = default;
472 
473 bool Output::outputting() const {
474  return true;
475 }
476 
477 void Output::beginMapping() {
478  StateStack.push_back(inMapFirstKey);
479  PaddingBeforeContainer = Padding;
480  Padding = "\n";
481 }
482 
483 bool Output::mapTag(StringRef Tag, bool Use) {
484  if (Use) {
485  // If this tag is being written inside a sequence we should write the start
486  // of the sequence before writing the tag, otherwise the tag won't be
487  // attached to the element in the sequence, but rather the sequence itself.
488  bool SequenceElement = false;
489  if (StateStack.size() > 1) {
490  auto &E = StateStack[StateStack.size() - 2];
491  SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E);
492  }
493  if (SequenceElement && StateStack.back() == inMapFirstKey) {
494  newLineCheck();
495  } else {
496  output(" ");
497  }
498  output(Tag);
499  if (SequenceElement) {
500  // If we're writing the tag during the first element of a map, the tag
501  // takes the place of the first element in the sequence.
502  if (StateStack.back() == inMapFirstKey) {
503  StateStack.pop_back();
504  StateStack.push_back(inMapOtherKey);
505  }
506  // Tags inside maps in sequences should act as keys in the map from a
507  // formatting perspective, so we always want a newline in a sequence.
508  Padding = "\n";
509  }
510  }
511  return Use;
512 }
513 
514 void Output::endMapping() {
515  // If we did not map anything, we should explicitly emit an empty map
516  if (StateStack.back() == inMapFirstKey) {
517  Padding = PaddingBeforeContainer;
518  newLineCheck();
519  output("{}");
520  Padding = "\n";
521  }
522  StateStack.pop_back();
523 }
524 
525 std::vector<StringRef> Output::keys() {
526  report_fatal_error("invalid call");
527 }
528 
529 bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault,
530  bool &UseDefault, void *&) {
531  UseDefault = false;
532  if (Required || !SameAsDefault || WriteDefaultValues) {
533  auto State = StateStack.back();
534  if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
535  flowKey(Key);
536  } else {
537  newLineCheck();
538  paddedKey(Key);
539  }
540  return true;
541  }
542  return false;
543 }
544 
545 void Output::postflightKey(void *) {
546  if (StateStack.back() == inMapFirstKey) {
547  StateStack.pop_back();
548  StateStack.push_back(inMapOtherKey);
549  } else if (StateStack.back() == inFlowMapFirstKey) {
550  StateStack.pop_back();
551  StateStack.push_back(inFlowMapOtherKey);
552  }
553 }
554 
555 void Output::beginFlowMapping() {
556  StateStack.push_back(inFlowMapFirstKey);
557  newLineCheck();
558  ColumnAtMapFlowStart = Column;
559  output("{ ");
560 }
561 
562 void Output::endFlowMapping() {
563  StateStack.pop_back();
564  outputUpToEndOfLine(" }");
565 }
566 
567 void Output::beginDocuments() {
568  outputUpToEndOfLine("---");
569 }
570 
571 bool Output::preflightDocument(unsigned index) {
572  if (index > 0)
573  outputUpToEndOfLine("\n---");
574  return true;
575 }
576 
577 void Output::postflightDocument() {
578 }
579 
580 void Output::endDocuments() {
581  output("\n...\n");
582 }
583 
584 unsigned Output::beginSequence() {
585  StateStack.push_back(inSeqFirstElement);
586  PaddingBeforeContainer = Padding;
587  Padding = "\n";
588  return 0;
589 }
590 
591 void Output::endSequence() {
592  // If we did not emit anything, we should explicitly emit an empty sequence
593  if (StateStack.back() == inSeqFirstElement) {
594  Padding = PaddingBeforeContainer;
595  newLineCheck(/*EmptySequence=*/true);
596  output("[]");
597  Padding = "\n";
598  }
599  StateStack.pop_back();
600 }
601 
602 bool Output::preflightElement(unsigned, void *&) {
603  return true;
604 }
605 
606 void Output::postflightElement(void *) {
607  if (StateStack.back() == inSeqFirstElement) {
608  StateStack.pop_back();
609  StateStack.push_back(inSeqOtherElement);
610  } else if (StateStack.back() == inFlowSeqFirstElement) {
611  StateStack.pop_back();
612  StateStack.push_back(inFlowSeqOtherElement);
613  }
614 }
615 
616 unsigned Output::beginFlowSequence() {
617  StateStack.push_back(inFlowSeqFirstElement);
618  newLineCheck();
619  ColumnAtFlowStart = Column;
620  output("[ ");
621  NeedFlowSequenceComma = false;
622  return 0;
623 }
624 
625 void Output::endFlowSequence() {
626  StateStack.pop_back();
627  outputUpToEndOfLine(" ]");
628 }
629 
630 bool Output::preflightFlowElement(unsigned, void *&) {
631  if (NeedFlowSequenceComma)
632  output(", ");
633  if (WrapColumn && Column > WrapColumn) {
634  output("\n");
635  for (int i = 0; i < ColumnAtFlowStart; ++i)
636  output(" ");
637  Column = ColumnAtFlowStart;
638  output(" ");
639  }
640  return true;
641 }
642 
643 void Output::postflightFlowElement(void *) {
644  NeedFlowSequenceComma = true;
645 }
646 
647 void Output::beginEnumScalar() {
648  EnumerationMatchFound = false;
649 }
650 
651 bool Output::matchEnumScalar(const char *Str, bool Match) {
652  if (Match && !EnumerationMatchFound) {
653  newLineCheck();
654  outputUpToEndOfLine(Str);
655  EnumerationMatchFound = true;
656  }
657  return false;
658 }
659 
660 bool Output::matchEnumFallback() {
661  if (EnumerationMatchFound)
662  return false;
663  EnumerationMatchFound = true;
664  return true;
665 }
666 
667 void Output::endEnumScalar() {
668  if (!EnumerationMatchFound)
669  llvm_unreachable("bad runtime enum value");
670 }
671 
672 bool Output::beginBitSetScalar(bool &DoClear) {
673  newLineCheck();
674  output("[ ");
675  NeedBitValueComma = false;
676  DoClear = false;
677  return true;
678 }
679 
680 bool Output::bitSetMatch(const char *Str, bool Matches) {
681  if (Matches) {
682  if (NeedBitValueComma)
683  output(", ");
684  output(Str);
685  NeedBitValueComma = true;
686  }
687  return false;
688 }
689 
690 void Output::endBitSetScalar() {
691  outputUpToEndOfLine(" ]");
692 }
693 
694 void Output::scalarString(StringRef &S, QuotingType MustQuote) {
695  newLineCheck();
696  if (S.empty()) {
697  // Print '' for the empty string because leaving the field empty is not
698  // allowed.
699  outputUpToEndOfLine("''");
700  return;
701  }
702  if (MustQuote == QuotingType::None) {
703  // Only quote if we must.
704  outputUpToEndOfLine(S);
705  return;
706  }
707 
708  const char *const Quote = MustQuote == QuotingType::Single ? "'" : "\"";
709  output(Quote); // Starting quote.
710 
711  // When using double-quoted strings (and only in that case), non-printable characters may be
712  // present, and will be escaped using a variety of unicode-scalar and special short-form
713  // escapes. This is handled in yaml::escape.
714  if (MustQuote == QuotingType::Double) {
715  output(yaml::escape(S, /* EscapePrintable= */ false));
716  outputUpToEndOfLine(Quote);
717  return;
718  }
719 
720  unsigned i = 0;
721  unsigned j = 0;
722  unsigned End = S.size();
723  const char *Base = S.data();
724 
725  // When using single-quoted strings, any single quote ' must be doubled to be escaped.
726  while (j < End) {
727  if (S[j] == '\'') { // Escape quotes.
728  output(StringRef(&Base[i], j - i)); // "flush".
729  output(StringLiteral("''")); // Print it as ''
730  i = j + 1;
731  }
732  ++j;
733  }
734  output(StringRef(&Base[i], j - i));
735  outputUpToEndOfLine(Quote); // Ending quote.
736 }
737 
738 void Output::blockScalarString(StringRef &S) {
739  if (!StateStack.empty())
740  newLineCheck();
741  output(" |");
742  outputNewLine();
743 
744  unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
745 
746  auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
747  for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
748  for (unsigned I = 0; I < Indent; ++I) {
749  output(" ");
750  }
751  output(*Lines);
752  outputNewLine();
753  }
754 }
755 
756 void Output::scalarTag(std::string &Tag) {
757  if (Tag.empty())
758  return;
759  newLineCheck();
760  output(Tag);
761  output(" ");
762 }
763 
764 void Output::setError(const Twine &message) {
765 }
766 
767 bool Output::canElideEmptySequence() {
768  // Normally, with an optional key/value where the value is an empty sequence,
769  // the whole key/value can be not written. But, that produces wrong yaml
770  // if the key/value is the only thing in the map and the map is used in
771  // a sequence. This detects if the this sequence is the first key/value
772  // in map that itself is embedded in a sequence.
773  if (StateStack.size() < 2)
774  return true;
775  if (StateStack.back() != inMapFirstKey)
776  return true;
777  return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
778 }
779 
780 void Output::output(StringRef s) {
781  Column += s.size();
782  Out << s;
783 }
784 
785 void Output::outputUpToEndOfLine(StringRef s) {
786  output(s);
787  if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
788  !inFlowMapAnyKey(StateStack.back())))
789  Padding = "\n";
790 }
791 
792 void Output::outputNewLine() {
793  Out << "\n";
794  Column = 0;
795 }
796 
797 // if seq at top, indent as if map, then add "- "
798 // if seq in middle, use "- " if firstKey, else use " "
799 //
800 
801 void Output::newLineCheck(bool EmptySequence) {
802  if (Padding != "\n") {
803  output(Padding);
804  Padding = {};
805  return;
806  }
807  outputNewLine();
808  Padding = {};
809 
810  if (StateStack.size() == 0 || EmptySequence)
811  return;
812 
813  unsigned Indent = StateStack.size() - 1;
814  bool OutputDash = false;
815 
816  if (StateStack.back() == inSeqFirstElement ||
817  StateStack.back() == inSeqOtherElement) {
818  OutputDash = true;
819  } else if ((StateStack.size() > 1) &&
820  ((StateStack.back() == inMapFirstKey) ||
821  inFlowSeqAnyElement(StateStack.back()) ||
822  (StateStack.back() == inFlowMapFirstKey)) &&
823  inSeqAnyElement(StateStack[StateStack.size() - 2])) {
824  --Indent;
825  OutputDash = true;
826  }
827 
828  for (unsigned i = 0; i < Indent; ++i) {
829  output(" ");
830  }
831  if (OutputDash) {
832  output("- ");
833  }
834 }
835 
836 void Output::paddedKey(StringRef key) {
837  output(key);
838  output(":");
839  const char *spaces = " ";
840  if (key.size() < strlen(spaces))
841  Padding = &spaces[key.size()];
842  else
843  Padding = " ";
844 }
845 
846 void Output::flowKey(StringRef Key) {
847  if (StateStack.back() == inFlowMapOtherKey)
848  output(", ");
849  if (WrapColumn && Column > WrapColumn) {
850  output("\n");
851  for (int I = 0; I < ColumnAtMapFlowStart; ++I)
852  output(" ");
853  Column = ColumnAtMapFlowStart;
854  output(" ");
855  }
856  output(Key);
857  output(": ");
858 }
859 
860 NodeKind Output::getNodeKind() { report_fatal_error("invalid call"); }
861 
862 bool Output::inSeqAnyElement(InState State) {
863  return State == inSeqFirstElement || State == inSeqOtherElement;
864 }
865 
866 bool Output::inFlowSeqAnyElement(InState State) {
867  return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
868 }
869 
870 bool Output::inMapAnyKey(InState State) {
871  return State == inMapFirstKey || State == inMapOtherKey;
872 }
873 
874 bool Output::inFlowMapAnyKey(InState State) {
875  return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
876 }
877 
878 //===----------------------------------------------------------------------===//
879 // traits for built-in types
880 //===----------------------------------------------------------------------===//
881 
882 void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) {
883  Out << (Val ? "true" : "false");
884 }
885 
886 StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) {
887  if (llvm::Optional<bool> Parsed = parseBool(Scalar)) {
888  Val = *Parsed;
889  return StringRef();
890  }
891  return "invalid boolean";
892 }
893 
894 void ScalarTraits<StringRef>::output(const StringRef &Val, void *,
895  raw_ostream &Out) {
896  Out << Val;
897 }
898 
900  StringRef &Val) {
901  Val = Scalar;
902  return StringRef();
903 }
904 
905 void ScalarTraits<std::string>::output(const std::string &Val, void *,
906  raw_ostream &Out) {
907  Out << Val;
908 }
909 
911  std::string &Val) {
912  Val = Scalar.str();
913  return StringRef();
914 }
915 
916 void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *,
917  raw_ostream &Out) {
918  // use temp uin32_t because ostream thinks uint8_t is a character
919  uint32_t Num = Val;
920  Out << Num;
921 }
922 
923 StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) {
924  unsigned long long n;
925  if (getAsUnsignedInteger(Scalar, 0, n))
926  return "invalid number";
927  if (n > 0xFF)
928  return "out of range number";
929  Val = n;
930  return StringRef();
931 }
932 
933 void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *,
934  raw_ostream &Out) {
935  Out << Val;
936 }
937 
939  uint16_t &Val) {
940  unsigned long long n;
941  if (getAsUnsignedInteger(Scalar, 0, n))
942  return "invalid number";
943  if (n > 0xFFFF)
944  return "out of range number";
945  Val = n;
946  return StringRef();
947 }
948 
949 void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *,
950  raw_ostream &Out) {
951  Out << Val;
952 }
953 
955  uint32_t &Val) {
956  unsigned long long n;
957  if (getAsUnsignedInteger(Scalar, 0, n))
958  return "invalid number";
959  if (n > 0xFFFFFFFFUL)
960  return "out of range number";
961  Val = n;
962  return StringRef();
963 }
964 
965 void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *,
966  raw_ostream &Out) {
967  Out << Val;
968 }
969 
971  uint64_t &Val) {
972  unsigned long long N;
973  if (getAsUnsignedInteger(Scalar, 0, N))
974  return "invalid number";
975  Val = N;
976  return StringRef();
977 }
978 
979 void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) {
980  // use temp in32_t because ostream thinks int8_t is a character
981  int32_t Num = Val;
982  Out << Num;
983 }
984 
985 StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) {
986  long long N;
987  if (getAsSignedInteger(Scalar, 0, N))
988  return "invalid number";
989  if ((N > 127) || (N < -128))
990  return "out of range number";
991  Val = N;
992  return StringRef();
993 }
994 
995 void ScalarTraits<int16_t>::output(const int16_t &Val, void *,
996  raw_ostream &Out) {
997  Out << Val;
998 }
999 
1000 StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) {
1001  long long N;
1002  if (getAsSignedInteger(Scalar, 0, N))
1003  return "invalid number";
1004  if ((N > INT16_MAX) || (N < INT16_MIN))
1005  return "out of range number";
1006  Val = N;
1007  return StringRef();
1008 }
1009 
1010 void ScalarTraits<int32_t>::output(const int32_t &Val, void *,
1011  raw_ostream &Out) {
1012  Out << Val;
1013 }
1014 
1015 StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) {
1016  long long N;
1017  if (getAsSignedInteger(Scalar, 0, N))
1018  return "invalid number";
1019  if ((N > INT32_MAX) || (N < INT32_MIN))
1020  return "out of range number";
1021  Val = N;
1022  return StringRef();
1023 }
1024 
1025 void ScalarTraits<int64_t>::output(const int64_t &Val, void *,
1026  raw_ostream &Out) {
1027  Out << Val;
1028 }
1029 
1030 StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) {
1031  long long N;
1032  if (getAsSignedInteger(Scalar, 0, N))
1033  return "invalid number";
1034  Val = N;
1035  return StringRef();
1036 }
1037 
1038 void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) {
1039  Out << format("%g", Val);
1040 }
1041 
1042 StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) {
1043  if (to_float(Scalar, Val))
1044  return StringRef();
1045  return "invalid floating point number";
1046 }
1047 
1048 void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) {
1049  Out << format("%g", Val);
1050 }
1051 
1052 StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) {
1053  if (to_float(Scalar, Val))
1054  return StringRef();
1055  return "invalid floating point number";
1056 }
1057 
1058 void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) {
1059  Out << format("0x%" PRIX8, (uint8_t)Val);
1060 }
1061 
1062 StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) {
1063  unsigned long long n;
1064  if (getAsUnsignedInteger(Scalar, 0, n))
1065  return "invalid hex8 number";
1066  if (n > 0xFF)
1067  return "out of range hex8 number";
1068  Val = n;
1069  return StringRef();
1070 }
1071 
1072 void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) {
1073  Out << format("0x%" PRIX16, (uint16_t)Val);
1074 }
1075 
1076 StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) {
1077  unsigned long long n;
1078  if (getAsUnsignedInteger(Scalar, 0, n))
1079  return "invalid hex16 number";
1080  if (n > 0xFFFF)
1081  return "out of range hex16 number";
1082  Val = n;
1083  return StringRef();
1084 }
1085 
1086 void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) {
1087  Out << format("0x%" PRIX32, (uint32_t)Val);
1088 }
1089 
1090 StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) {
1091  unsigned long long n;
1092  if (getAsUnsignedInteger(Scalar, 0, n))
1093  return "invalid hex32 number";
1094  if (n > 0xFFFFFFFFUL)
1095  return "out of range hex32 number";
1096  Val = n;
1097  return StringRef();
1098 }
1099 
1100 void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) {
1101  Out << format("0x%" PRIX64, (uint64_t)Val);
1102 }
1103 
1104 StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) {
1105  unsigned long long Num;
1106  if (getAsUnsignedInteger(Scalar, 0, Num))
1107  return "invalid hex64 number";
1108  Val = Num;
1109  return StringRef();
1110 }
1111 
1112 void ScalarTraits<VersionTuple>::output(const VersionTuple &Val, void *,
1113  llvm::raw_ostream &Out) {
1114  Out << Val.getAsString();
1115 }
1116 
1118  VersionTuple &Val) {
1119  if (Val.tryParse(Scalar))
1120  return "invalid version format";
1121  return StringRef();
1122 }
llvm::StringRef::copy
LLVM_NODISCARD StringRef copy(Allocator &A) const
Definition: StringRef.h:174
i
i
Definition: README.txt:29
MemoryBuffer.h
llvm::errc::invalid_argument
@ invalid_argument
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::objcarc::Sequence
Sequence
Definition: PtrState.h:41
llvm::VersionTuple::tryParse
bool tryParse(StringRef string)
Try to parse the given string as a version number.
Definition: VersionTuple.cpp:63
llvm::yaml::Node::getSourceRange
SMRange getSourceRange() const
Definition: YAMLParser.h:165
llvm::line_iterator
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
llvm::codeview::DebugSubsectionKind::Lines
@ Lines
llvm::yaml::escape
std::string escape(StringRef Input, bool EscapePrintable=true)
Escape Input for a double quoted scalar; if EscapePrintable is true, all UTF8 sequences will be escap...
Definition: YAMLParser.cpp:683
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::yaml::Node
Abstract base class for all Nodes.
Definition: YAMLParser.h:119
YAMLParser.h
output
Current output
Definition: README.txt:1350
ErrorHandling.h
Errc.h
llvm::yaml::ScalarNode
A scalar node is an opaque datum that can be presented as a series of zero or more Unicode scalar val...
Definition: YAMLParser.h:212
error
#define error(X)
Definition: SymbolRecordMapping.cpp:14
llvm::Optional< bool >
llvm::yaml::MappingNode
Represents a YAML map created from either a block map for a flow map.
Definition: YAMLParser.h:414
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
STLExtras.h
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:104
Format.h
llvm::MemoryBufferRef
Definition: MemoryBufferRef.h:22
llvm::pdb::Double
@ Double
Definition: PDBTypes.h:401
new
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
Definition: README.txt:125
Context
ManagedStatic< detail::RecordContext > Context
Definition: Record.cpp:96
llvm::StringLiteral
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
Definition: StringRef.h:890
llvm::MemoryBuffer::getMemBuffer
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
Definition: MemoryBuffer.cpp:113
SmallString.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::cl::Required
@ Required
Definition: CommandLine.h:121
Twine.h
llvm::getAsUnsignedInteger
bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
Definition: StringRef.cpp:485
llvm::SrcMgr
SourceMgr SrcMgr
Definition: Error.cpp:24
llvm::yaml::SequenceNode
Represents a YAML sequence created from either a block sequence for a flow sequence.
Definition: YAMLParser.h:462
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:481
false
Definition: StackSlotColoring.cpp:142
LineIterator.h
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::yaml::parseBool
llvm::Optional< bool > parseBool(StringRef S)
Parse S as a bool according to https://yaml.org/type/bool.html.
Definition: YAMLParser.cpp:749
llvm::VersionTuple
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:29
input
The initial backend is deliberately restricted to z10 We should add support for later architectures at some point If an asm ties an i32 r result to an i64 input
Definition: README.txt:10
llvm::SourceMgr::setDiagHandler
void setDiagHandler(DiagHandlerTy DH, void *Ctx=nullptr)
Specify a diagnostic handler to be invoked every time PrintMessage is called.
Definition: SourceMgr.h:109
llvm::NVPTX::PTXLdStInstCode::Scalar
@ Scalar
Definition: NVPTX.h:122
llvm::None
const NoneType None
Definition: None.h:23
llvm::SmallString< 128 >
llvm::yaml::BlockScalarNode
A block scalar node is an opaque datum that can be presented as a series of zero or more Unicode scal...
Definition: YAMLParser.h:255
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
index
splat index
Definition: README_ALTIVEC.txt:181
uint64_t
llvm::SourceMgr::DK_Warning
@ DK_Warning
Definition: SourceMgr.h:35
s
multiplies can be turned into SHL s
Definition: README.txt:370
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::SourceMgr::DiagHandlerTy
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
Definition: SourceMgr.h:43
I
#define I(x, y, z)
Definition: MD5.cpp:59
StringExtras.h
node
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper node
Definition: README-SSE.txt:406
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1665
message
message(STATUS "Targeting ${t}") add_subdirectory($
Definition: CMakeLists.txt:33
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::codeview::CompileSym2Flags::EC
@ EC
YAMLTraits.h
DiagHandler
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
Definition: TextStub.cpp:1095
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::yaml::Node::getVerbatimTag
std::string getVerbatimTag() const
Get the verbatium tag for a given Node.
Definition: YAMLParser.cpp:1890
llvm::yaml::KeyValueNode
A key and value pair.
Definition: YAMLParser.h:285
uint32_t
llvm::yaml::Stream
This class represents a YAML stream potentially containing multiple documents.
Definition: YAMLParser.h:86
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
Unicode.h
llvm::pdb::Single
@ Single
Definition: PDBTypes.h:400
llvm::make_error_code
std::error_code make_error_code(BitcodeError E)
Definition: BitcodeReader.h:270
j
return j(j<< 16)
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
uint16_t
llvm::VersionTuple::getAsString
std::string getAsString() const
Retrieve a string representation of the version number.
Definition: VersionTuple.cpp:21
Casting.h
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::TargetStackID::Default
@ Default
Definition: TargetFrameLowering.h:28
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::SmallString::str
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:259
llvm::getAsSignedInteger
bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
Definition: StringRef.cpp:495
llvm::ms_demangle::NodeKind
NodeKind
Definition: MicrosoftDemangleNodes.h:227
llvm::SMRange
Represents a range in source code.
Definition: SMLoc.h:48
llvm::TPLoop::Allow
@ Allow
Definition: ARMTargetTransformInfo.h:53
N
#define N
spaces
Infer address spaces
Definition: InferAddressSpaces.cpp:263
raw_ostream.h
n
The same transformation can work with an even modulo with the addition of a and shrink the compare RHS by the same amount Unless the target supports that transformation probably isn t worthwhile The transformation can also easily be made to work with non zero equality for n
Definition: README.txt:685
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:156
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:44