1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | #include "llvm/Support/YAMLTraits.h" |
11 | #include "llvm/ADT/Twine.h" |
12 | #include "llvm/Support/Casting.h" |
13 | #include "llvm/Support/ErrorHandling.h" |
14 | #include "llvm/Support/Format.h" |
15 | #include "llvm/Support/YAMLParser.h" |
16 | #include "llvm/Support/raw_ostream.h" |
17 | #include <cstring> |
18 | using namespace llvm; |
19 | using namespace yaml; |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | IO::IO(void *Context) : Ctxt(Context) { |
26 | } |
27 | |
28 | IO::~IO() { |
29 | } |
30 | |
31 | void *IO::getContext() { |
32 | return Ctxt; |
33 | } |
34 | |
35 | void IO::setContext(void *Context) { |
36 | Ctxt = Context; |
37 | } |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | Input::Input(StringRef InputContent, void *Ctxt) |
44 | : IO(Ctxt), |
45 | Strm(new Stream(InputContent, SrcMgr)), |
46 | CurrentNode(NULL__null) { |
47 | DocIterator = Strm->begin(); |
48 | } |
49 | |
50 | Input::~Input() { |
51 | |
52 | } |
53 | |
54 | error_code Input::error() { |
55 | return EC; |
56 | } |
57 | |
58 | void Input::setDiagHandler(SourceMgr::DiagHandlerTy Handler, void *Ctxt) { |
59 | SrcMgr.setDiagHandler(Handler, Ctxt); |
60 | } |
61 | |
62 | bool Input::outputting() { |
63 | return false; |
64 | } |
65 | |
66 | bool Input::setCurrentDocument() { |
67 | if (DocIterator != Strm->end()) { |
68 | Node *N = DocIterator->getRoot(); |
69 | if (isa<NullNode>(N)) { |
70 | |
71 | ++DocIterator; |
72 | return setCurrentDocument(); |
73 | } |
74 | TopNode.reset(this->createHNodes(N)); |
75 | CurrentNode = TopNode.get(); |
76 | return true; |
77 | } |
78 | return false; |
79 | } |
80 | |
81 | void Input::nextDocument() { |
82 | ++DocIterator; |
83 | } |
84 | |
85 | void Input::beginMapping() { |
86 | if (EC) |
87 | return; |
88 | MapHNode *MN = dyn_cast<MapHNode>(CurrentNode); |
89 | if (MN) { |
90 | MN->ValidKeys.clear(); |
91 | } |
92 | } |
93 | |
94 | bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault, |
95 | void *&SaveInfo) { |
96 | UseDefault = false; |
97 | if (EC) |
98 | return false; |
99 | MapHNode *MN = dyn_cast<MapHNode>(CurrentNode); |
100 | if (!MN) { |
101 | setError(CurrentNode, "not a mapping"); |
102 | return false; |
103 | } |
104 | MN->ValidKeys.push_back(Key); |
105 | HNode *Value = MN->Mapping[Key]; |
106 | if (!Value) { |
107 | if (Required) |
108 | setError(CurrentNode, Twine("missing required key '") + Key + "'"); |
109 | else |
110 | UseDefault = true; |
111 | return false; |
112 | } |
113 | SaveInfo = CurrentNode; |
114 | CurrentNode = Value; |
115 | return true; |
116 | } |
117 | |
118 | void Input::postflightKey(void *saveInfo) { |
119 | CurrentNode = reinterpret_cast<HNode *>(saveInfo); |
120 | } |
121 | |
122 | void Input::endMapping() { |
123 | if (EC) |
124 | return; |
125 | MapHNode *MN = dyn_cast<MapHNode>(CurrentNode); |
126 | if (!MN) |
127 | return; |
128 | for (MapHNode::NameToNode::iterator i = MN->Mapping.begin(), |
129 | End = MN->Mapping.end(); i != End; ++i) { |
130 | if (!MN->isValidKey(i->first)) { |
131 | setError(i->second, Twine("unknown key '") + i->first + "'"); |
132 | break; |
133 | } |
134 | } |
135 | } |
136 | |
137 | unsigned Input::beginSequence() { |
138 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
139 | return SQ->Entries.size(); |
140 | } |
141 | return 0; |
142 | } |
143 | |
144 | void Input::endSequence() { |
145 | } |
146 | |
147 | bool Input::preflightElement(unsigned Index, void *&SaveInfo) { |
148 | if (EC) |
149 | return false; |
150 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
151 | SaveInfo = CurrentNode; |
152 | CurrentNode = SQ->Entries[Index]; |
153 | return true; |
154 | } |
155 | return false; |
156 | } |
157 | |
158 | void Input::postflightElement(void *SaveInfo) { |
159 | CurrentNode = reinterpret_cast<HNode *>(SaveInfo); |
160 | } |
161 | |
162 | unsigned Input::beginFlowSequence() { |
163 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
164 | return SQ->Entries.size(); |
165 | } |
166 | return 0; |
167 | } |
168 | |
169 | bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) { |
170 | if (EC) |
171 | return false; |
172 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
173 | SaveInfo = CurrentNode; |
174 | CurrentNode = SQ->Entries[index]; |
175 | return true; |
176 | } |
177 | return false; |
178 | } |
179 | |
180 | void Input::postflightFlowElement(void *SaveInfo) { |
181 | CurrentNode = reinterpret_cast<HNode *>(SaveInfo); |
182 | } |
183 | |
184 | void Input::endFlowSequence() { |
185 | } |
186 | |
187 | void Input::beginEnumScalar() { |
188 | ScalarMatchFound = false; |
189 | } |
190 | |
191 | bool Input::matchEnumScalar(const char *Str, bool) { |
192 | if (ScalarMatchFound) |
193 | return false; |
194 | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) { |
195 | if (SN->value().equals(Str)) { |
196 | ScalarMatchFound = true; |
197 | return true; |
198 | } |
199 | } |
200 | return false; |
201 | } |
202 | |
203 | void Input::endEnumScalar() { |
204 | if (!ScalarMatchFound) { |
205 | setError(CurrentNode, "unknown enumerated scalar"); |
206 | } |
207 | } |
208 | |
209 | bool Input::beginBitSetScalar(bool &DoClear) { |
210 | BitValuesUsed.clear(); |
211 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
212 | BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false); |
213 | } else { |
214 | setError(CurrentNode, "expected sequence of bit values"); |
215 | } |
216 | DoClear = true; |
217 | return true; |
218 | } |
219 | |
220 | bool Input::bitSetMatch(const char *Str, bool) { |
221 | if (EC) |
222 | return false; |
223 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
224 | unsigned Index = 0; |
225 | for (std::vector<HNode *>::iterator i = SQ->Entries.begin(), |
226 | End = SQ->Entries.end(); i != End; ++i) { |
227 | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(*i)) { |
228 | if (SN->value().equals(Str)) { |
229 | BitValuesUsed[Index] = true; |
230 | return true; |
231 | } |
232 | } else { |
233 | setError(CurrentNode, "unexpected scalar in sequence of bit values"); |
234 | } |
235 | ++Index; |
236 | } |
237 | } else { |
238 | setError(CurrentNode, "expected sequence of bit values"); |
239 | } |
240 | return false; |
241 | } |
242 | |
243 | void Input::endBitSetScalar() { |
244 | if (EC) |
245 | return; |
246 | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
247 | assert(BitValuesUsed.size() == SQ->Entries.size())((void)0); |
248 | for (unsigned i = 0; i < SQ->Entries.size(); ++i) { |
249 | if (!BitValuesUsed[i]) { |
250 | setError(SQ->Entries[i], "unknown bit value"); |
251 | return; |
252 | } |
253 | } |
254 | } |
255 | } |
256 | |
257 | void Input::scalarString(StringRef &S) { |
258 | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) { |
259 | S = SN->value(); |
260 | } else { |
261 | setError(CurrentNode, "unexpected scalar"); |
262 | } |
263 | } |
264 | |
265 | void Input::setError(HNode *hnode, const Twine &message) { |
266 | this->setError(hnode->_node, message); |
267 | } |
268 | |
269 | void Input::setError(Node *node, const Twine &message) { |
270 | Strm->printError(node, message); |
271 | EC = make_error_code(errc::invalid_argument); |
272 | } |
273 | |
274 | Input::HNode *Input::createHNodes(Node *N) { |
275 | SmallString<128> StringStorage; |
276 | if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) { |
| |
| |
277 | StringRef KeyStr = SN->getValue(StringStorage); |
278 | if (!StringStorage.empty()) { |
279 | |
280 | unsigned Len = StringStorage.size(); |
281 | char *Buf = StringAllocator.Allocate<char>(Len); |
282 | memcpy(Buf, &StringStorage[0], Len); |
283 | KeyStr = StringRef(Buf, Len); |
284 | } |
285 | return new ScalarHNode(N, KeyStr); |
286 | } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) { |
| |
| |
287 | SequenceHNode *SQHNode = new SequenceHNode(N); |
288 | for (SequenceNode::iterator i = SQ->begin(), End = SQ->end(); i != End; |
289 | ++i) { |
290 | HNode *Entry = this->createHNodes(i); |
291 | if (EC) |
292 | break; |
293 | SQHNode->Entries.push_back(Entry); |
294 | } |
295 | return SQHNode; |
296 | } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) { |
| 3 | | Assuming 'Map' is non-null | |
|
| |
| |
297 | MapHNode *mapHNode = new MapHNode(N); |
298 | for (MappingNode::iterator i = Map->begin(), End = Map->end(); i != End; |
| 5 | | Loop condition is true. Entering loop body | |
|
299 | ++i) { |
300 | ScalarNode *KeyScalar = dyn_cast<ScalarNode>(i->getKey()); |
301 | StringStorage.clear(); |
302 | StringRef KeyStr = KeyScalar->getValue(StringStorage); |
303 | if (!StringStorage.empty()) { |
| |
304 | |
305 | unsigned Len = StringStorage.size(); |
306 | char *Buf = StringAllocator.Allocate<char>(Len); |
307 | memcpy(Buf, &StringStorage[0], Len); |
308 | KeyStr = StringRef(Buf, Len); |
309 | } |
310 | HNode *ValueHNode = this->createHNodes(i->getValue()); |
| 7 | | Calling 'Input::createHNodes' | |
|
| 13 | | Returned allocated memory | |
|
311 | if (EC) |
| |
312 | break; |
| 15 | | Execution continues on line 315 | |
|
313 | mapHNode->Mapping[KeyStr] = ValueHNode; |
314 | } |
315 | return mapHNode; |
| 16 | | Memory is never released; potential leak of memory pointed to by 'ValueHNode' |
|
316 | } else if (isa<NullNode>(N)) { |
| |
317 | return new EmptyHNode(N); |
| |
318 | } else { |
319 | setError(N, "unknown node kind"); |
320 | return NULL__null; |
321 | } |
322 | } |
323 | |
324 | bool Input::MapHNode::isValidKey(StringRef Key) { |
325 | for (SmallVector<const char *, 6>::iterator i = ValidKeys.begin(), |
326 | End = ValidKeys.end(); i != End; ++i) { |
327 | if (Key.equals(*i)) |
328 | return true; |
329 | } |
330 | return false; |
331 | } |
332 | |
333 | void Input::setError(const Twine &Message) { |
334 | this->setError(CurrentNode, Message); |
335 | } |
336 | |
337 | Input::MapHNode::~MapHNode() { |
338 | for (MapHNode::NameToNode::iterator i = Mapping.begin(), End = Mapping.end(); |
339 | i != End; ++i) { |
340 | delete i->second; |
341 | } |
342 | } |
343 | |
344 | Input::SequenceHNode::~SequenceHNode() { |
345 | for (std::vector<HNode*>::iterator i = Entries.begin(), End = Entries.end(); |
346 | i != End; ++i) { |
347 | delete *i; |
348 | } |
349 | } |
350 | |
351 | |
352 | |
353 | |
354 | |
355 | |
356 | |
357 | Output::Output(raw_ostream &yout, void *context) |
358 | : IO(context), |
359 | Out(yout), |
360 | Column(0), |
361 | ColumnAtFlowStart(0), |
362 | NeedBitValueComma(false), |
363 | NeedFlowSequenceComma(false), |
364 | EnumerationMatchFound(false), |
365 | NeedsNewLine(false) { |
366 | } |
367 | |
368 | Output::~Output() { |
369 | } |
370 | |
371 | bool Output::outputting() { |
372 | return true; |
373 | } |
374 | |
375 | void Output::beginMapping() { |
376 | StateStack.push_back(inMapFirstKey); |
377 | NeedsNewLine = true; |
378 | } |
379 | |
380 | void Output::endMapping() { |
381 | StateStack.pop_back(); |
382 | } |
383 | |
384 | bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault, |
385 | bool &UseDefault, void *&) { |
386 | UseDefault = false; |
387 | if (Required || !SameAsDefault) { |
388 | this->newLineCheck(); |
389 | this->paddedKey(Key); |
390 | return true; |
391 | } |
392 | return false; |
393 | } |
394 | |
395 | void Output::postflightKey(void *) { |
396 | if (StateStack.back() == inMapFirstKey) { |
397 | StateStack.pop_back(); |
398 | StateStack.push_back(inMapOtherKey); |
399 | } |
400 | } |
401 | |
402 | void Output::beginDocuments() { |
403 | this->outputUpToEndOfLine("---"); |
404 | } |
405 | |
406 | bool Output::preflightDocument(unsigned index) { |
407 | if (index > 0) |
408 | this->outputUpToEndOfLine("\n---"); |
409 | return true; |
410 | } |
411 | |
412 | void Output::postflightDocument() { |
413 | } |
414 | |
415 | void Output::endDocuments() { |
416 | output("\n...\n"); |
417 | } |
418 | |
419 | unsigned Output::beginSequence() { |
420 | StateStack.push_back(inSeq); |
421 | NeedsNewLine = true; |
422 | return 0; |
423 | } |
424 | |
425 | void Output::endSequence() { |
426 | StateStack.pop_back(); |
427 | } |
428 | |
429 | bool Output::preflightElement(unsigned, void *&) { |
430 | return true; |
431 | } |
432 | |
433 | void Output::postflightElement(void *) { |
434 | } |
435 | |
436 | unsigned Output::beginFlowSequence() { |
437 | StateStack.push_back(inFlowSeq); |
438 | this->newLineCheck(); |
439 | ColumnAtFlowStart = Column; |
440 | output("[ "); |
441 | NeedFlowSequenceComma = false; |
442 | return 0; |
443 | } |
444 | |
445 | void Output::endFlowSequence() { |
446 | StateStack.pop_back(); |
447 | this->outputUpToEndOfLine(" ]"); |
448 | } |
449 | |
450 | bool Output::preflightFlowElement(unsigned, void *&) { |
451 | if (NeedFlowSequenceComma) |
452 | output(", "); |
453 | if (Column > 70) { |
454 | output("\n"); |
455 | for (int i = 0; i < ColumnAtFlowStart; ++i) |
456 | output(" "); |
457 | Column = ColumnAtFlowStart; |
458 | output(" "); |
459 | } |
460 | return true; |
461 | } |
462 | |
463 | void Output::postflightFlowElement(void *) { |
464 | NeedFlowSequenceComma = true; |
465 | } |
466 | |
467 | void Output::beginEnumScalar() { |
468 | EnumerationMatchFound = false; |
469 | } |
470 | |
471 | bool Output::matchEnumScalar(const char *Str, bool Match) { |
472 | if (Match && !EnumerationMatchFound) { |
473 | this->newLineCheck(); |
474 | this->outputUpToEndOfLine(Str); |
475 | EnumerationMatchFound = true; |
476 | } |
477 | return false; |
478 | } |
479 | |
480 | void Output::endEnumScalar() { |
481 | if (!EnumerationMatchFound) |
482 | llvm_unreachable("bad runtime enum value")__builtin_unreachable(); |
483 | } |
484 | |
485 | bool Output::beginBitSetScalar(bool &DoClear) { |
486 | this->newLineCheck(); |
487 | output("[ "); |
488 | NeedBitValueComma = false; |
489 | DoClear = false; |
490 | return true; |
491 | } |
492 | |
493 | bool Output::bitSetMatch(const char *Str, bool Matches) { |
494 | if (Matches) { |
495 | if (NeedBitValueComma) |
496 | output(", "); |
497 | this->output(Str); |
498 | NeedBitValueComma = true; |
499 | } |
500 | return false; |
501 | } |
502 | |
503 | void Output::endBitSetScalar() { |
504 | this->outputUpToEndOfLine(" ]"); |
505 | } |
506 | |
507 | void Output::scalarString(StringRef &S) { |
508 | this->newLineCheck(); |
509 | if (S.find('\n') == StringRef::npos) { |
510 | |
511 | this->outputUpToEndOfLine(S); |
512 | return; |
513 | } |
514 | unsigned i = 0; |
515 | unsigned j = 0; |
516 | unsigned End = S.size(); |
517 | output("'"); |
518 | const char *Base = S.data(); |
519 | while (j < End) { |
520 | |
521 | if (S[j] == '\'') { |
522 | output(StringRef(&Base[i], j - i + 1)); |
523 | output("'"); |
524 | i = j + 1; |
525 | } |
526 | ++j; |
527 | } |
528 | output(StringRef(&Base[i], j - i)); |
529 | this->outputUpToEndOfLine("'"); |
530 | } |
531 | |
532 | void Output::setError(const Twine &message) { |
533 | } |
534 | |
535 | void Output::output(StringRef s) { |
536 | Column += s.size(); |
537 | Out << s; |
538 | } |
539 | |
540 | void Output::outputUpToEndOfLine(StringRef s) { |
541 | this->output(s); |
542 | if (StateStack.empty() || StateStack.back() != inFlowSeq) |
543 | NeedsNewLine = true; |
544 | } |
545 | |
546 | void Output::outputNewLine() { |
547 | Out << "\n"; |
548 | Column = 0; |
549 | } |
550 | |
551 | |
552 | |
553 | |
554 | |
555 | void Output::newLineCheck() { |
556 | if (!NeedsNewLine) |
557 | return; |
558 | NeedsNewLine = false; |
559 | |
560 | this->outputNewLine(); |
561 | |
562 | assert(StateStack.size() > 0)((void)0); |
563 | unsigned Indent = StateStack.size() - 1; |
564 | bool OutputDash = false; |
565 | |
566 | if (StateStack.back() == inSeq) { |
567 | OutputDash = true; |
568 | } else if ((StateStack.size() > 1) && (StateStack.back() == inMapFirstKey) && |
569 | (StateStack[StateStack.size() - 2] == inSeq)) { |
570 | --Indent; |
571 | OutputDash = true; |
572 | } |
573 | |
574 | for (unsigned i = 0; i < Indent; ++i) { |
575 | output(" "); |
576 | } |
577 | if (OutputDash) { |
578 | output("- "); |
579 | } |
580 | |
581 | } |
582 | |
583 | void Output::paddedKey(StringRef key) { |
584 | output(key); |
585 | output(":"); |
586 | const char *spaces = " "; |
587 | if (key.size() < strlen(spaces)) |
588 | output(&spaces[key.size()]); |
589 | else |
590 | output(" "); |
591 | } |
592 | |
593 | |
594 | |
595 | |
596 | |
597 | void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) { |
598 | Out << (Val ? "true" : "false"); |
599 | } |
600 | |
601 | StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) { |
602 | if (Scalar.equals("true")) { |
603 | Val = true; |
604 | return StringRef(); |
605 | } else if (Scalar.equals("false")) { |
606 | Val = false; |
607 | return StringRef(); |
608 | } |
609 | return "invalid boolean"; |
610 | } |
611 | |
612 | void ScalarTraits<StringRef>::output(const StringRef &Val, void *, |
613 | raw_ostream &Out) { |
614 | Out << Val; |
615 | } |
616 | |
617 | StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *, |
618 | StringRef &Val) { |
619 | Val = Scalar; |
620 | return StringRef(); |
621 | } |
622 | |
623 | void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *, |
624 | raw_ostream &Out) { |
625 | |
626 | uint32_t Num = Val; |
627 | Out << Num; |
628 | } |
629 | |
630 | StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) { |
631 | unsigned long long n; |
632 | if (getAsUnsignedInteger(Scalar, 0, n)) |
633 | return "invalid number"; |
634 | if (n > 0xFF) |
635 | return "out of range number"; |
636 | Val = n; |
637 | return StringRef(); |
638 | } |
639 | |
640 | void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *, |
641 | raw_ostream &Out) { |
642 | Out << Val; |
643 | } |
644 | |
645 | StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *, |
646 | uint16_t &Val) { |
647 | unsigned long long n; |
648 | if (getAsUnsignedInteger(Scalar, 0, n)) |
649 | return "invalid number"; |
650 | if (n > 0xFFFF) |
651 | return "out of range number"; |
652 | Val = n; |
653 | return StringRef(); |
654 | } |
655 | |
656 | void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *, |
657 | raw_ostream &Out) { |
658 | Out << Val; |
659 | } |
660 | |
661 | StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *, |
662 | uint32_t &Val) { |
663 | unsigned long long n; |
664 | if (getAsUnsignedInteger(Scalar, 0, n)) |
665 | return "invalid number"; |
666 | if (n > 0xFFFFFFFFUL) |
667 | return "out of range number"; |
668 | Val = n; |
669 | return StringRef(); |
670 | } |
671 | |
672 | void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *, |
673 | raw_ostream &Out) { |
674 | Out << Val; |
675 | } |
676 | |
677 | StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *, |
678 | uint64_t &Val) { |
679 | unsigned long long N; |
680 | if (getAsUnsignedInteger(Scalar, 0, N)) |
681 | return "invalid number"; |
682 | Val = N; |
683 | return StringRef(); |
684 | } |
685 | |
686 | void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) { |
687 | |
688 | int32_t Num = Val; |
689 | Out << Num; |
690 | } |
691 | |
692 | StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) { |
693 | long long N; |
694 | if (getAsSignedInteger(Scalar, 0, N)) |
695 | return "invalid number"; |
696 | if ((N > 127) || (N < -128)) |
697 | return "out of range number"; |
698 | Val = N; |
699 | return StringRef(); |
700 | } |
701 | |
702 | void ScalarTraits<int16_t>::output(const int16_t &Val, void *, |
703 | raw_ostream &Out) { |
704 | Out << Val; |
705 | } |
706 | |
707 | StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) { |
708 | long long N; |
709 | if (getAsSignedInteger(Scalar, 0, N)) |
710 | return "invalid number"; |
711 | if ((N > INT16_MAX32767) || (N < INT16_MIN(-32768))) |
712 | return "out of range number"; |
713 | Val = N; |
714 | return StringRef(); |
715 | } |
716 | |
717 | void ScalarTraits<int32_t>::output(const int32_t &Val, void *, |
718 | raw_ostream &Out) { |
719 | Out << Val; |
720 | } |
721 | |
722 | StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) { |
723 | long long N; |
724 | if (getAsSignedInteger(Scalar, 0, N)) |
725 | return "invalid number"; |
726 | if ((N > INT32_MAX2147483647) || (N < INT32_MIN(-2147483647 - 1))) |
727 | return "out of range number"; |
728 | Val = N; |
729 | return StringRef(); |
730 | } |
731 | |
732 | void ScalarTraits<int64_t>::output(const int64_t &Val, void *, |
733 | raw_ostream &Out) { |
734 | Out << Val; |
735 | } |
736 | |
737 | StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) { |
738 | long long N; |
739 | if (getAsSignedInteger(Scalar, 0, N)) |
740 | return "invalid number"; |
741 | Val = N; |
742 | return StringRef(); |
743 | } |
744 | |
745 | void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) { |
746 | Out << format("%g", Val); |
747 | } |
748 | |
749 | StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) { |
750 | SmallString<32> buff(Scalar.begin(), Scalar.end()); |
751 | char *end; |
752 | Val = strtod(buff.c_str(), &end); |
753 | if (*end != '\0') |
754 | return "invalid floating point number"; |
755 | return StringRef(); |
756 | } |
757 | |
758 | void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) { |
759 | Out << format("%g", Val); |
760 | } |
761 | |
762 | StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) { |
763 | SmallString<32> buff(Scalar.begin(), Scalar.end()); |
764 | char *end; |
765 | Val = strtod(buff.c_str(), &end); |
766 | if (*end != '\0') |
767 | return "invalid floating point number"; |
768 | return StringRef(); |
769 | } |
770 | |
771 | void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) { |
772 | uint8_t Num = Val; |
773 | Out << format("0x%02X", Num); |
774 | } |
775 | |
776 | StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) { |
777 | unsigned long long n; |
778 | if (getAsUnsignedInteger(Scalar, 0, n)) |
779 | return "invalid hex8 number"; |
780 | if (n > 0xFF) |
781 | return "out of range hex8 number"; |
782 | Val = n; |
783 | return StringRef(); |
784 | } |
785 | |
786 | void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) { |
787 | uint16_t Num = Val; |
788 | Out << format("0x%04X", Num); |
789 | } |
790 | |
791 | StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) { |
792 | unsigned long long n; |
793 | if (getAsUnsignedInteger(Scalar, 0, n)) |
794 | return "invalid hex16 number"; |
795 | if (n > 0xFFFF) |
796 | return "out of range hex16 number"; |
797 | Val = n; |
798 | return StringRef(); |
799 | } |
800 | |
801 | void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) { |
802 | uint32_t Num = Val; |
803 | Out << format("0x%08X", Num); |
804 | } |
805 | |
806 | StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) { |
807 | unsigned long long n; |
808 | if (getAsUnsignedInteger(Scalar, 0, n)) |
809 | return "invalid hex32 number"; |
810 | if (n > 0xFFFFFFFFUL) |
811 | return "out of range hex32 number"; |
812 | Val = n; |
813 | return StringRef(); |
814 | } |
815 | |
816 | void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) { |
817 | uint64_t Num = Val; |
818 | Out << format("0x%016llX", Num); |
819 | } |
820 | |
821 | StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) { |
822 | unsigned long long Num; |
823 | if (getAsUnsignedInteger(Scalar, 0, Num)) |
824 | return "invalid hex64 number"; |
825 | Val = Num; |
826 | return StringRef(); |
827 | } |