/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Support/YAMLTraits.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | |
9 | | #include "llvm/Support/YAMLTraits.h" |
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" |
17 | | #include "llvm/Support/ErrorHandling.h" |
18 | | #include "llvm/Support/Format.h" |
19 | | #include "llvm/Support/LineIterator.h" |
20 | | #include "llvm/Support/MemoryBuffer.h" |
21 | | #include "llvm/Support/Unicode.h" |
22 | | #include "llvm/Support/YAMLParser.h" |
23 | | #include "llvm/Support/raw_ostream.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 | 20.2k | IO::IO(void *Context) : Ctxt(Context) {} |
40 | | |
41 | 20.1k | IO::~IO() = default; |
42 | | |
43 | 1.11M | void *IO::getContext() { |
44 | 1.11M | return Ctxt; |
45 | 1.11M | } |
46 | | |
47 | 5.27k | void IO::setContext(void *Context) { |
48 | 5.27k | Ctxt = Context; |
49 | 5.27k | } |
50 | | |
51 | | //===----------------------------------------------------------------------===// |
52 | | // Input |
53 | | //===----------------------------------------------------------------------===// |
54 | | |
55 | | Input::Input(StringRef InputContent, void *Ctxt, |
56 | | SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt) |
57 | 4.41k | : IO(Ctxt), Strm(new Stream(InputContent, SrcMgr, false, &EC)) { |
58 | 4.41k | if (DiagHandler) |
59 | 2.30k | SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt); |
60 | 4.41k | DocIterator = Strm->begin(); |
61 | 4.41k | } |
62 | | |
63 | | Input::Input(MemoryBufferRef Input, void *Ctxt, |
64 | | SourceMgr::DiagHandlerTy DiagHandler, void *DiagHandlerCtxt) |
65 | 3 | : IO(Ctxt), Strm(new Stream(Input, SrcMgr, false, &EC)) { |
66 | 3 | if (DiagHandler) |
67 | 1 | SrcMgr.setDiagHandler(DiagHandler, DiagHandlerCtxt); |
68 | 3 | DocIterator = Strm->begin(); |
69 | 3 | } |
70 | | |
71 | 4.31k | Input::~Input() = default; |
72 | | |
73 | 14.0k | std::error_code Input::error() { return EC; } |
74 | | |
75 | | // Pin the vtables to this file. |
76 | 0 | void Input::HNode::anchor() {} |
77 | 0 | void Input::EmptyHNode::anchor() {} |
78 | 0 | void Input::ScalarHNode::anchor() {} |
79 | 0 | void Input::MapHNode::anchor() {} |
80 | 0 | void Input::SequenceHNode::anchor() {} |
81 | | |
82 | 2.00M | bool Input::outputting() { |
83 | 2.00M | return false; |
84 | 2.00M | } |
85 | | |
86 | 17.4k | bool Input::setCurrentDocument() { |
87 | 17.4k | if (DocIterator != Strm->end()) { |
88 | 14.7k | Node *N = DocIterator->getRoot(); |
89 | 14.7k | if (!N) { |
90 | 2 | assert(Strm->failed() && "Root is NULL iff parsing failed"); |
91 | 2 | EC = make_error_code(errc::invalid_argument); |
92 | 2 | return false; |
93 | 2 | } |
94 | 14.7k | |
95 | 14.7k | if (isa<NullNode>(N)) { |
96 | 176 | // Empty files are allowed and ignored |
97 | 176 | ++DocIterator; |
98 | 176 | return setCurrentDocument(); |
99 | 176 | } |
100 | 14.6k | TopNode = createHNodes(N); |
101 | 14.6k | CurrentNode = TopNode.get(); |
102 | 14.6k | return true; |
103 | 14.6k | } |
104 | 2.64k | return false; |
105 | 2.64k | } |
106 | | |
107 | 14.1k | bool Input::nextDocument() { |
108 | 14.1k | return ++DocIterator != Strm->end(); |
109 | 14.1k | } |
110 | | |
111 | 62.6k | const Node *Input::getCurrentNode() const { |
112 | 62.6k | return CurrentNode ? CurrentNode->_node62.6k : nullptr5 ; |
113 | 62.6k | } |
114 | | |
115 | 5.65k | bool Input::mapTag(StringRef Tag, bool Default) { |
116 | 5.65k | // CurrentNode can be null if setCurrentDocument() was unable to |
117 | 5.65k | // parse the document because it was invalid or empty. |
118 | 5.65k | if (!CurrentNode) |
119 | 30 | return false; |
120 | 5.62k | |
121 | 5.62k | std::string foundTag = CurrentNode->_node->getVerbatimTag(); |
122 | 5.62k | if (foundTag.empty()) { |
123 | 0 | // If no tag found and 'Tag' is the default, say it was found. |
124 | 0 | return Default; |
125 | 0 | } |
126 | 5.62k | // Return true iff found tag matches supplied tag. |
127 | 5.62k | return Tag.equals(foundTag); |
128 | 5.62k | } |
129 | | |
130 | 61.7k | void Input::beginMapping() { |
131 | 61.7k | if (EC) |
132 | 4 | return; |
133 | 61.7k | // CurrentNode can be null if the document is empty. |
134 | 61.7k | MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode); |
135 | 61.7k | if (MN) { |
136 | 61.6k | MN->ValidKeys.clear(); |
137 | 61.6k | } |
138 | 61.7k | } |
139 | | |
140 | 1.22k | std::vector<StringRef> Input::keys() { |
141 | 1.22k | MapHNode *MN = dyn_cast<MapHNode>(CurrentNode); |
142 | 1.22k | std::vector<StringRef> Ret; |
143 | 1.22k | if (!MN) { |
144 | 0 | setError(CurrentNode, "not a mapping"); |
145 | 0 | return Ret; |
146 | 0 | } |
147 | 1.22k | for (auto &P : MN->Mapping) |
148 | 6.81k | Ret.push_back(P.first()); |
149 | 1.22k | return Ret; |
150 | 1.22k | } |
151 | | |
152 | | bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault, |
153 | 519k | void *&SaveInfo) { |
154 | 519k | UseDefault = false; |
155 | 519k | if (EC) |
156 | 130 | return false; |
157 | 519k | |
158 | 519k | // CurrentNode is null for empty documents, which is an error in case required |
159 | 519k | // nodes are present. |
160 | 519k | if (!CurrentNode) { |
161 | 2 | if (Required) |
162 | 1 | EC = make_error_code(errc::invalid_argument); |
163 | 2 | return false; |
164 | 2 | } |
165 | 519k | |
166 | 519k | MapHNode *MN = dyn_cast<MapHNode>(CurrentNode); |
167 | 519k | if (!MN) { |
168 | 26 | if (Required || !isa<EmptyHNode>(CurrentNode)) |
169 | 0 | setError(CurrentNode, "not a mapping"); |
170 | 26 | return false; |
171 | 26 | } |
172 | 519k | MN->ValidKeys.push_back(Key); |
173 | 519k | HNode *Value = MN->Mapping[Key].get(); |
174 | 519k | if (!Value) { |
175 | 291k | if (Required) |
176 | 5 | setError(CurrentNode, Twine("missing required key '") + Key + "'"); |
177 | 291k | else |
178 | 291k | UseDefault = true; |
179 | 291k | return false; |
180 | 291k | } |
181 | 227k | SaveInfo = CurrentNode; |
182 | 227k | CurrentNode = Value; |
183 | 227k | return true; |
184 | 227k | } |
185 | | |
186 | 227k | void Input::postflightKey(void *saveInfo) { |
187 | 227k | CurrentNode = reinterpret_cast<HNode *>(saveInfo); |
188 | 227k | } |
189 | | |
190 | 61.7k | void Input::endMapping() { |
191 | 61.7k | if (EC) |
192 | 64 | return; |
193 | 61.7k | // CurrentNode can be null if the document is empty. |
194 | 61.7k | MapHNode *MN = dyn_cast_or_null<MapHNode>(CurrentNode); |
195 | 61.7k | if (!MN) |
196 | 78 | return; |
197 | 516k | for (const auto &NN : MN->Mapping)61.6k { |
198 | 516k | if (!is_contained(MN->ValidKeys, NN.first())) { |
199 | 15 | setError(NN.second.get(), Twine("unknown key '") + NN.first() + "'"); |
200 | 15 | break; |
201 | 15 | } |
202 | 516k | } |
203 | 61.6k | } |
204 | | |
205 | 22.0k | void Input::beginFlowMapping() { beginMapping(); } |
206 | | |
207 | 22.0k | void Input::endFlowMapping() { endMapping(); } |
208 | | |
209 | 14.5k | unsigned Input::beginSequence() { |
210 | 14.5k | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) |
211 | 11.9k | return SQ->Entries.size(); |
212 | 2.58k | if (isa<EmptyHNode>(CurrentNode)) |
213 | 2.57k | return 0; |
214 | 6 | // Treat case where there's a scalar "null" value as an empty sequence. |
215 | 6 | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) { |
216 | 4 | if (isNull(SN->value())) |
217 | 3 | return 0; |
218 | 3 | } |
219 | 3 | // Any other type of HNode is an error. |
220 | 3 | setError(CurrentNode, "not a sequence"); |
221 | 3 | return 0; |
222 | 3 | } |
223 | | |
224 | 13.5k | void Input::endSequence() { |
225 | 13.5k | } |
226 | | |
227 | 41.0k | bool Input::preflightElement(unsigned Index, void *&SaveInfo) { |
228 | 41.0k | if (EC) |
229 | 0 | return false; |
230 | 41.0k | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
231 | 41.0k | SaveInfo = CurrentNode; |
232 | 41.0k | CurrentNode = SQ->Entries[Index].get(); |
233 | 41.0k | return true; |
234 | 41.0k | } |
235 | 0 | return false; |
236 | 0 | } |
237 | | |
238 | 41.0k | void Input::postflightElement(void *SaveInfo) { |
239 | 41.0k | CurrentNode = reinterpret_cast<HNode *>(SaveInfo); |
240 | 41.0k | } |
241 | | |
242 | 1.02k | unsigned Input::beginFlowSequence() { return beginSequence(); } |
243 | | |
244 | 12.6k | bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) { |
245 | 12.6k | if (EC) |
246 | 0 | return false; |
247 | 12.6k | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
248 | 12.6k | SaveInfo = CurrentNode; |
249 | 12.6k | CurrentNode = SQ->Entries[index].get(); |
250 | 12.6k | return true; |
251 | 12.6k | } |
252 | 0 | return false; |
253 | 0 | } |
254 | | |
255 | 12.6k | void Input::postflightFlowElement(void *SaveInfo) { |
256 | 12.6k | CurrentNode = reinterpret_cast<HNode *>(SaveInfo); |
257 | 12.6k | } |
258 | | |
259 | 1.02k | void Input::endFlowSequence() { |
260 | 1.02k | } |
261 | | |
262 | 27.4k | void Input::beginEnumScalar() { |
263 | 27.4k | ScalarMatchFound = false; |
264 | 27.4k | } |
265 | | |
266 | 1.35M | bool Input::matchEnumScalar(const char *Str, bool) { |
267 | 1.35M | if (ScalarMatchFound) |
268 | 988k | return false; |
269 | 364k | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) { |
270 | 364k | if (SN->value().equals(Str)) { |
271 | 27.3k | ScalarMatchFound = true; |
272 | 27.3k | return true; |
273 | 27.3k | } |
274 | 336k | } |
275 | 336k | return false; |
276 | 336k | } |
277 | | |
278 | 7.21k | bool Input::matchEnumFallback() { |
279 | 7.21k | if (ScalarMatchFound) |
280 | 7.05k | return false; |
281 | 160 | ScalarMatchFound = true; |
282 | 160 | return true; |
283 | 160 | } |
284 | | |
285 | 27.4k | void Input::endEnumScalar() { |
286 | 27.4k | if (!ScalarMatchFound) { |
287 | 2 | setError(CurrentNode, "unknown enumerated scalar"); |
288 | 2 | } |
289 | 27.4k | } |
290 | | |
291 | 4.01k | bool Input::beginBitSetScalar(bool &DoClear) { |
292 | 4.01k | BitValuesUsed.clear(); |
293 | 4.01k | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
294 | 4.01k | BitValuesUsed.insert(BitValuesUsed.begin(), SQ->Entries.size(), false); |
295 | 4.01k | } else { |
296 | 0 | setError(CurrentNode, "expected sequence of bit values"); |
297 | 0 | } |
298 | 4.01k | DoClear = true; |
299 | 4.01k | return true; |
300 | 4.01k | } |
301 | | |
302 | 46.7k | bool Input::bitSetMatch(const char *Str, bool) { |
303 | 46.7k | if (EC) |
304 | 0 | return false; |
305 | 46.7k | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
306 | 46.7k | unsigned Index = 0; |
307 | 89.0k | for (auto &N : SQ->Entries) { |
308 | 89.0k | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(N.get())) { |
309 | 89.0k | if (SN->value().equals(Str)) { |
310 | 6.95k | BitValuesUsed[Index] = true; |
311 | 6.95k | return true; |
312 | 6.95k | } |
313 | 0 | } else { |
314 | 0 | setError(CurrentNode, "unexpected scalar in sequence of bit values"); |
315 | 0 | } |
316 | 89.0k | ++Index; |
317 | 82.0k | } |
318 | 46.7k | } else { |
319 | 0 | setError(CurrentNode, "expected sequence of bit values"); |
320 | 0 | } |
321 | 46.7k | return false39.7k ; |
322 | 46.7k | } |
323 | | |
324 | 4.01k | void Input::endBitSetScalar() { |
325 | 4.01k | if (EC) |
326 | 0 | return; |
327 | 4.01k | if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) { |
328 | 4.01k | assert(BitValuesUsed.size() == SQ->Entries.size()); |
329 | 10.9k | for (unsigned i = 0; i < SQ->Entries.size(); ++i6.95k ) { |
330 | 6.95k | if (!BitValuesUsed[i]) { |
331 | 1 | setError(SQ->Entries[i].get(), "unknown bit value"); |
332 | 1 | return; |
333 | 1 | } |
334 | 6.95k | } |
335 | 4.01k | } |
336 | 4.01k | } |
337 | | |
338 | 187k | void Input::scalarString(StringRef &S, QuotingType) { |
339 | 187k | if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) { |
340 | 187k | S = SN->value(); |
341 | 187k | } else { |
342 | 0 | setError(CurrentNode, "unexpected scalar"); |
343 | 0 | } |
344 | 187k | } |
345 | | |
346 | 11.2k | void Input::blockScalarString(StringRef &S) { scalarString(S, QuotingType::None); } |
347 | | |
348 | 6.63k | void Input::scalarTag(std::string &Tag) { |
349 | 6.63k | Tag = CurrentNode->_node->getVerbatimTag(); |
350 | 6.63k | } |
351 | | |
352 | 71 | void Input::setError(HNode *hnode, const Twine &message) { |
353 | 71 | assert(hnode && "HNode must not be NULL"); |
354 | 71 | setError(hnode->_node, message); |
355 | 71 | } |
356 | | |
357 | 8.00k | NodeKind Input::getNodeKind() { |
358 | 8.00k | if (isa<ScalarHNode>(CurrentNode)) |
359 | 6.63k | return NodeKind::Scalar; |
360 | 1.37k | else if (isa<MapHNode>(CurrentNode)) |
361 | 1.08k | return NodeKind::Map; |
362 | 289 | else if (isa<SequenceHNode>(CurrentNode)) |
363 | 289 | return NodeKind::Sequence; |
364 | 0 | llvm_unreachable("Unsupported node kind"); |
365 | 0 | } |
366 | | |
367 | 73 | void Input::setError(Node *node, const Twine &message) { |
368 | 73 | Strm->printError(node, message); |
369 | 73 | EC = make_error_code(errc::invalid_argument); |
370 | 73 | } |
371 | | |
372 | 301k | std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) { |
373 | 301k | SmallString<128> StringStorage; |
374 | 301k | if (ScalarNode *SN = dyn_cast<ScalarNode>(N)) { |
375 | 208k | StringRef KeyStr = SN->getValue(StringStorage); |
376 | 208k | if (!StringStorage.empty()) { |
377 | 8 | // Copy string to permanent storage |
378 | 8 | KeyStr = StringStorage.str().copy(StringAllocator); |
379 | 8 | } |
380 | 208k | return llvm::make_unique<ScalarHNode>(N, KeyStr); |
381 | 208k | } else if (BlockScalarNode *92.7k BSN92.7k = dyn_cast<BlockScalarNode>(N)) { |
382 | 12.4k | StringRef ValueCopy = BSN->getValue().copy(StringAllocator); |
383 | 12.4k | return llvm::make_unique<ScalarHNode>(N, ValueCopy); |
384 | 80.3k | } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) { |
385 | 16.0k | auto SQHNode = llvm::make_unique<SequenceHNode>(N); |
386 | 60.6k | for (Node &SN : *SQ) { |
387 | 60.6k | auto Entry = createHNodes(&SN); |
388 | 60.6k | if (EC) |
389 | 0 | break; |
390 | 60.6k | SQHNode->Entries.push_back(std::move(Entry)); |
391 | 60.6k | } |
392 | 16.0k | return std::move(SQHNode); |
393 | 64.3k | } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) { |
394 | 61.7k | auto mapHNode = llvm::make_unique<MapHNode>(N); |
395 | 226k | for (KeyValueNode &KVN : *Map) { |
396 | 226k | Node *KeyNode = KVN.getKey(); |
397 | 226k | ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode); |
398 | 226k | Node *Value = KVN.getValue(); |
399 | 226k | if (!Key || !Value225k ) { |
400 | 2 | if (!Key) |
401 | 1 | setError(KeyNode, "Map key must be a scalar"); |
402 | 2 | if (!Value) |
403 | 1 | setError(KeyNode, "Map value must not be empty"); |
404 | 2 | break; |
405 | 2 | } |
406 | 225k | StringStorage.clear(); |
407 | 225k | StringRef KeyStr = Key->getValue(StringStorage); |
408 | 225k | if (!StringStorage.empty()) { |
409 | 0 | // Copy string to permanent storage |
410 | 0 | KeyStr = StringStorage.str().copy(StringAllocator); |
411 | 0 | } |
412 | 225k | auto ValueHNode = createHNodes(Value); |
413 | 225k | if (EC) |
414 | 0 | break; |
415 | 225k | mapHNode->Mapping[KeyStr] = std::move(ValueHNode); |
416 | 225k | } |
417 | 61.7k | return std::move(mapHNode); |
418 | 61.7k | } else if (2.65k isa<NullNode>(N)2.65k ) { |
419 | 2.65k | return llvm::make_unique<EmptyHNode>(N); |
420 | 2.65k | } else { |
421 | 0 | setError(N, "unknown node kind"); |
422 | 0 | return nullptr; |
423 | 0 | } |
424 | 301k | } |
425 | | |
426 | 45 | void Input::setError(const Twine &Message) { |
427 | 45 | setError(CurrentNode, Message); |
428 | 45 | } |
429 | | |
430 | 14.4k | bool Input::canElideEmptySequence() { |
431 | 14.4k | return false; |
432 | 14.4k | } |
433 | | |
434 | | //===----------------------------------------------------------------------===// |
435 | | // Output |
436 | | //===----------------------------------------------------------------------===// |
437 | | |
438 | | Output::Output(raw_ostream &yout, void *context, int WrapColumn) |
439 | 15.8k | : IO(context), Out(yout), WrapColumn(WrapColumn) {} |
440 | | |
441 | 15.8k | Output::~Output() = default; |
442 | | |
443 | 3.22M | bool Output::outputting() { |
444 | 3.22M | return true; |
445 | 3.22M | } |
446 | | |
447 | 105k | void Output::beginMapping() { |
448 | 105k | StateStack.push_back(inMapFirstKey); |
449 | 105k | PaddingBeforeContainer = Padding; |
450 | 105k | Padding = "\n"; |
451 | 105k | } |
452 | | |
453 | 1.59k | bool Output::mapTag(StringRef Tag, bool Use) { |
454 | 1.59k | if (Use) { |
455 | 880 | // If this tag is being written inside a sequence we should write the start |
456 | 880 | // of the sequence before writing the tag, otherwise the tag won't be |
457 | 880 | // attached to the element in the sequence, but rather the sequence itself. |
458 | 880 | bool SequenceElement = false; |
459 | 880 | if (StateStack.size() > 1) { |
460 | 57 | auto &E = StateStack[StateStack.size() - 2]; |
461 | 57 | SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E)0 ; |
462 | 57 | } |
463 | 880 | if (SequenceElement && StateStack.back() == inMapFirstKey57 ) { |
464 | 57 | newLineCheck(); |
465 | 823 | } else { |
466 | 823 | output(" "); |
467 | 823 | } |
468 | 880 | output(Tag); |
469 | 880 | if (SequenceElement) { |
470 | 57 | // If we're writing the tag during the first element of a map, the tag |
471 | 57 | // takes the place of the first element in the sequence. |
472 | 57 | if (StateStack.back() == inMapFirstKey) { |
473 | 57 | StateStack.pop_back(); |
474 | 57 | StateStack.push_back(inMapOtherKey); |
475 | 57 | } |
476 | 57 | // Tags inside maps in sequences should act as keys in the map from a |
477 | 57 | // formatting perspective, so we always want a newline in a sequence. |
478 | 57 | Padding = "\n"; |
479 | 57 | } |
480 | 880 | } |
481 | 1.59k | return Use; |
482 | 1.59k | } |
483 | | |
484 | 105k | void Output::endMapping() { |
485 | 105k | // If we did not map anything, we should explicitly emit an empty map |
486 | 105k | if (StateStack.back() == inMapFirstKey) { |
487 | 6.18k | Padding = PaddingBeforeContainer; |
488 | 6.18k | newLineCheck(); |
489 | 6.18k | output("{}"); |
490 | 6.18k | Padding = "\n"; |
491 | 6.18k | } |
492 | 105k | StateStack.pop_back(); |
493 | 105k | } |
494 | | |
495 | 0 | std::vector<StringRef> Output::keys() { |
496 | 0 | report_fatal_error("invalid call"); |
497 | 0 | } |
498 | | |
499 | | bool Output::preflightKey(const char *Key, bool Required, bool SameAsDefault, |
500 | 1.15M | bool &UseDefault, void *&) { |
501 | 1.15M | UseDefault = false; |
502 | 1.15M | if (Required || !SameAsDefault713k || WriteDefaultValues581k ) { |
503 | 1.07M | auto State = StateStack.back(); |
504 | 1.07M | if (State == inFlowMapFirstKey || State == inFlowMapOtherKey990k ) { |
505 | 244k | flowKey(Key); |
506 | 830k | } else { |
507 | 830k | newLineCheck(); |
508 | 830k | paddedKey(Key); |
509 | 830k | } |
510 | 1.07M | return true; |
511 | 1.07M | } |
512 | 80.2k | return false; |
513 | 80.2k | } |
514 | | |
515 | 1.07M | void Output::postflightKey(void *) { |
516 | 1.07M | if (StateStack.back() == inMapFirstKey) { |
517 | 98.9k | StateStack.pop_back(); |
518 | 98.9k | StateStack.push_back(inMapOtherKey); |
519 | 976k | } else if (StateStack.back() == inFlowMapFirstKey) { |
520 | 85.2k | StateStack.pop_back(); |
521 | 85.2k | StateStack.push_back(inFlowMapOtherKey); |
522 | 85.2k | } |
523 | 1.07M | } |
524 | | |
525 | 85.2k | void Output::beginFlowMapping() { |
526 | 85.2k | StateStack.push_back(inFlowMapFirstKey); |
527 | 85.2k | newLineCheck(); |
528 | 85.2k | ColumnAtMapFlowStart = Column; |
529 | 85.2k | output("{ "); |
530 | 85.2k | } |
531 | | |
532 | 85.2k | void Output::endFlowMapping() { |
533 | 85.2k | StateStack.pop_back(); |
534 | 85.2k | outputUpToEndOfLine(" }"); |
535 | 85.2k | } |
536 | | |
537 | 15.9k | void Output::beginDocuments() { |
538 | 15.9k | outputUpToEndOfLine("---"); |
539 | 15.9k | } |
540 | | |
541 | 15.9k | bool Output::preflightDocument(unsigned index) { |
542 | 15.9k | if (index > 0) |
543 | 2 | outputUpToEndOfLine("\n---"); |
544 | 15.9k | return true; |
545 | 15.9k | } |
546 | | |
547 | 15.9k | void Output::postflightDocument() { |
548 | 15.9k | } |
549 | | |
550 | 15.9k | void Output::endDocuments() { |
551 | 15.9k | output("\n...\n"); |
552 | 15.9k | } |
553 | | |
554 | 84.5k | unsigned Output::beginSequence() { |
555 | 84.5k | StateStack.push_back(inSeqFirstElement); |
556 | 84.5k | PaddingBeforeContainer = Padding; |
557 | 84.5k | Padding = "\n"; |
558 | 84.5k | return 0; |
559 | 84.5k | } |
560 | | |
561 | 84.5k | void Output::endSequence() { |
562 | 84.5k | // If we did not emit anything, we should explicitly emit an empty sequence |
563 | 84.5k | if (StateStack.back() == inSeqFirstElement) { |
564 | 60.5k | Padding = PaddingBeforeContainer; |
565 | 60.5k | newLineCheck(); |
566 | 60.5k | output("[]"); |
567 | 60.5k | Padding = "\n"; |
568 | 60.5k | } |
569 | 84.5k | StateStack.pop_back(); |
570 | 84.5k | } |
571 | | |
572 | 135k | bool Output::preflightElement(unsigned, void *&) { |
573 | 135k | return true; |
574 | 135k | } |
575 | | |
576 | 135k | void Output::postflightElement(void *) { |
577 | 135k | if (StateStack.back() == inSeqFirstElement) { |
578 | 24.0k | StateStack.pop_back(); |
579 | 24.0k | StateStack.push_back(inSeqOtherElement); |
580 | 111k | } else if (StateStack.back() == inFlowSeqFirstElement) { |
581 | 0 | StateStack.pop_back(); |
582 | 0 | StateStack.push_back(inFlowSeqOtherElement); |
583 | 0 | } |
584 | 135k | } |
585 | | |
586 | 1.71k | unsigned Output::beginFlowSequence() { |
587 | 1.71k | StateStack.push_back(inFlowSeqFirstElement); |
588 | 1.71k | newLineCheck(); |
589 | 1.71k | ColumnAtFlowStart = Column; |
590 | 1.71k | output("[ "); |
591 | 1.71k | NeedFlowSequenceComma = false; |
592 | 1.71k | return 0; |
593 | 1.71k | } |
594 | | |
595 | 1.71k | void Output::endFlowSequence() { |
596 | 1.71k | StateStack.pop_back(); |
597 | 1.71k | outputUpToEndOfLine(" ]"); |
598 | 1.71k | } |
599 | | |
600 | 8.11k | bool Output::preflightFlowElement(unsigned, void *&) { |
601 | 8.11k | if (NeedFlowSequenceComma) |
602 | 6.43k | output(", "); |
603 | 8.11k | if (WrapColumn && Column > WrapColumn8.10k ) { |
604 | 359 | output("\n"); |
605 | 7.98k | for (int i = 0; i < ColumnAtFlowStart; ++i7.63k ) |
606 | 7.63k | output(" "); |
607 | 359 | Column = ColumnAtFlowStart; |
608 | 359 | output(" "); |
609 | 359 | } |
610 | 8.11k | return true; |
611 | 8.11k | } |
612 | | |
613 | 8.11k | void Output::postflightFlowElement(void *) { |
614 | 8.11k | NeedFlowSequenceComma = true; |
615 | 8.11k | } |
616 | | |
617 | 37.1k | void Output::beginEnumScalar() { |
618 | 37.1k | EnumerationMatchFound = false; |
619 | 37.1k | } |
620 | | |
621 | 1.00M | bool Output::matchEnumScalar(const char *Str, bool Match) { |
622 | 1.00M | if (Match && !EnumerationMatchFound37.1k ) { |
623 | 37.0k | newLineCheck(); |
624 | 37.0k | outputUpToEndOfLine(Str); |
625 | 37.0k | EnumerationMatchFound = true; |
626 | 37.0k | } |
627 | 1.00M | return false; |
628 | 1.00M | } |
629 | | |
630 | 7.20k | bool Output::matchEnumFallback() { |
631 | 7.20k | if (EnumerationMatchFound) |
632 | 7.17k | return false; |
633 | 27 | EnumerationMatchFound = true; |
634 | 27 | return true; |
635 | 27 | } |
636 | | |
637 | 37.1k | void Output::endEnumScalar() { |
638 | 37.1k | if (!EnumerationMatchFound) |
639 | 37.1k | llvm_unreachable0 ("bad runtime enum value"); |
640 | 37.1k | } |
641 | | |
642 | 1.66k | bool Output::beginBitSetScalar(bool &DoClear) { |
643 | 1.66k | newLineCheck(); |
644 | 1.66k | output("[ "); |
645 | 1.66k | NeedBitValueComma = false; |
646 | 1.66k | DoClear = false; |
647 | 1.66k | return true; |
648 | 1.66k | } |
649 | | |
650 | 15.6k | bool Output::bitSetMatch(const char *Str, bool Matches) { |
651 | 15.6k | if (Matches) { |
652 | 3.01k | if (NeedBitValueComma) |
653 | 1.65k | output(", "); |
654 | 3.01k | output(Str); |
655 | 3.01k | NeedBitValueComma = true; |
656 | 3.01k | } |
657 | 15.6k | return false; |
658 | 15.6k | } |
659 | | |
660 | 1.66k | void Output::endBitSetScalar() { |
661 | 1.66k | outputUpToEndOfLine(" ]"); |
662 | 1.66k | } |
663 | | |
664 | 905k | void Output::scalarString(StringRef &S, QuotingType MustQuote) { |
665 | 905k | newLineCheck(); |
666 | 905k | if (S.empty()) { |
667 | 126k | // Print '' for the empty string because leaving the field empty is not |
668 | 126k | // allowed. |
669 | 126k | outputUpToEndOfLine("''"); |
670 | 126k | return; |
671 | 126k | } |
672 | 778k | if (MustQuote == QuotingType::None) { |
673 | 731k | // Only quote if we must. |
674 | 731k | outputUpToEndOfLine(S); |
675 | 731k | return; |
676 | 731k | } |
677 | 46.8k | |
678 | 46.8k | const char *const Quote = MustQuote == QuotingType::Single ? "'"46.8k : "\""8 ; |
679 | 46.8k | output(Quote); // Starting quote. |
680 | 46.8k | |
681 | 46.8k | // When using double-quoted strings (and only in that case), non-printable characters may be |
682 | 46.8k | // present, and will be escaped using a variety of unicode-scalar and special short-form |
683 | 46.8k | // escapes. This is handled in yaml::escape. |
684 | 46.8k | if (MustQuote == QuotingType::Double) { |
685 | 8 | output(yaml::escape(S, /* EscapePrintable= */ false)); |
686 | 8 | outputUpToEndOfLine(Quote); |
687 | 8 | return; |
688 | 8 | } |
689 | 46.8k | |
690 | 46.8k | unsigned i = 0; |
691 | 46.8k | unsigned j = 0; |
692 | 46.8k | unsigned End = S.size(); |
693 | 46.8k | const char *Base = S.data(); |
694 | 46.8k | |
695 | 46.8k | // When using single-quoted strings, any single quote ' must be doubled to be escaped. |
696 | 896k | while (j < End) { |
697 | 849k | if (S[j] == '\'') { // Escape quotes. |
698 | 11 | output(StringRef(&Base[i], j - i)); // "flush". |
699 | 11 | output(StringLiteral("''")); // Print it as '' |
700 | 11 | i = j + 1; |
701 | 11 | } |
702 | 849k | ++j; |
703 | 849k | } |
704 | 46.8k | output(StringRef(&Base[i], j - i)); |
705 | 46.8k | outputUpToEndOfLine(Quote); // Ending quote. |
706 | 46.8k | } |
707 | | |
708 | 14.0k | void Output::blockScalarString(StringRef &S) { |
709 | 14.0k | if (!StateStack.empty()) |
710 | 11.9k | newLineCheck(); |
711 | 14.0k | output(" |"); |
712 | 14.0k | outputNewLine(); |
713 | 14.0k | |
714 | 14.0k | unsigned Indent = StateStack.empty() ? 12.09k : StateStack.size()11.9k ; |
715 | 14.0k | |
716 | 14.0k | auto Buffer = MemoryBuffer::getMemBuffer(S, "", false); |
717 | 235k | for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines221k ) { |
718 | 443k | for (unsigned I = 0; I < Indent; ++I221k ) { |
719 | 221k | output(" "); |
720 | 221k | } |
721 | 221k | output(*Lines); |
722 | 221k | outputNewLine(); |
723 | 221k | } |
724 | 14.0k | } |
725 | | |
726 | 169k | void Output::scalarTag(std::string &Tag) { |
727 | 169k | if (Tag.empty()) |
728 | 169k | return; |
729 | 14 | newLineCheck(); |
730 | 14 | output(Tag); |
731 | 14 | output(" "); |
732 | 14 | } |
733 | | |
734 | 0 | void Output::setError(const Twine &message) { |
735 | 0 | } |
736 | | |
737 | 18.9k | bool Output::canElideEmptySequence() { |
738 | 18.9k | // Normally, with an optional key/value where the value is an empty sequence, |
739 | 18.9k | // the whole key/value can be not written. But, that produces wrong yaml |
740 | 18.9k | // if the key/value is the only thing in the map and the map is used in |
741 | 18.9k | // a sequence. This detects if the this sequence is the first key/value |
742 | 18.9k | // in map that itself is embedded in a sequnce. |
743 | 18.9k | if (StateStack.size() < 2) |
744 | 1.62k | return true; |
745 | 17.2k | if (StateStack.back() != inMapFirstKey) |
746 | 17.2k | return true; |
747 | 80 | return !inSeqAnyElement(StateStack[StateStack.size() - 2]); |
748 | 80 | } |
749 | | |
750 | 6.64M | void Output::output(StringRef s) { |
751 | 6.64M | Column += s.size(); |
752 | 6.64M | Out << s; |
753 | 6.64M | } |
754 | | |
755 | 1.04M | void Output::outputUpToEndOfLine(StringRef s) { |
756 | 1.04M | output(s); |
757 | 1.04M | if (StateStack.empty() || (1.03M !inFlowSeqAnyElement(StateStack.back())1.03M && |
758 | 1.03M | !inFlowMapAnyKey(StateStack.back())1.02M )) |
759 | 793k | Padding = "\n"; |
760 | 1.04M | } |
761 | | |
762 | 1.15M | void Output::outputNewLine() { |
763 | 1.15M | Out << "\n"; |
764 | 1.15M | Column = 0; |
765 | 1.15M | } |
766 | | |
767 | | // if seq at top, indent as if map, then add "- " |
768 | | // if seq in middle, use "- " if firstKey, else use " " |
769 | | // |
770 | | |
771 | 1.94M | void Output::newLineCheck() { |
772 | 1.94M | if (Padding != "\n") { |
773 | 1.02M | output(Padding); |
774 | 1.02M | Padding = {}; |
775 | 1.02M | return; |
776 | 1.02M | } |
777 | 916k | outputNewLine(); |
778 | 916k | Padding = {}; |
779 | 916k | |
780 | 916k | if (StateStack.size() == 0) |
781 | 0 | return; |
782 | 916k | |
783 | 916k | unsigned Indent = StateStack.size() - 1; |
784 | 916k | bool OutputDash = false; |
785 | 916k | |
786 | 916k | if (StateStack.back() == inSeqFirstElement || |
787 | 916k | StateStack.back() == inSeqOtherElement914k ) { |
788 | 12.3k | OutputDash = true; |
789 | 903k | } else if ((StateStack.size() > 1) && |
790 | 903k | (684k (StateStack.back() == inMapFirstKey)684k || |
791 | 684k | inFlowSeqAnyElement(StateStack.back())599k || |
792 | 684k | (StateStack.back() == inFlowMapFirstKey)599k ) && |
793 | 903k | inSeqAnyElement(StateStack[StateStack.size() - 2])158k ) { |
794 | 122k | --Indent; |
795 | 122k | OutputDash = true; |
796 | 122k | } |
797 | 916k | |
798 | 2.28M | for (unsigned i = 0; i < Indent; ++i1.36M ) { |
799 | 1.36M | output(" "); |
800 | 1.36M | } |
801 | 916k | if (OutputDash) { |
802 | 135k | output("- "); |
803 | 135k | } |
804 | 916k | |
805 | 916k | } |
806 | | |
807 | 830k | void Output::paddedKey(StringRef key) { |
808 | 830k | output(key); |
809 | 830k | output(":"); |
810 | 830k | const char *spaces = " "; |
811 | 830k | if (key.size() < strlen(spaces)) |
812 | 621k | Padding = &spaces[key.size()]; |
813 | 208k | else |
814 | 208k | Padding = " "; |
815 | 830k | } |
816 | | |
817 | 244k | void Output::flowKey(StringRef Key) { |
818 | 244k | if (StateStack.back() == inFlowMapOtherKey) |
819 | 159k | output(", "); |
820 | 244k | if (WrapColumn && Column > WrapColumn243k ) { |
821 | 3.56k | output("\n"); |
822 | 19.5k | for (int I = 0; I < ColumnAtMapFlowStart; ++I16.0k ) |
823 | 16.0k | output(" "); |
824 | 3.56k | Column = ColumnAtMapFlowStart; |
825 | 3.56k | output(" "); |
826 | 3.56k | } |
827 | 244k | output(Key); |
828 | 244k | output(": "); |
829 | 244k | } |
830 | | |
831 | 0 | NodeKind Output::getNodeKind() { report_fatal_error("invalid call"); } |
832 | | |
833 | 158k | bool Output::inSeqAnyElement(InState State) { |
834 | 158k | return State == inSeqFirstElement || State == inSeqOtherElement135k ; |
835 | 158k | } |
836 | | |
837 | 1.63M | bool Output::inFlowSeqAnyElement(InState State) { |
838 | 1.63M | return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement1.62M ; |
839 | 1.63M | } |
840 | | |
841 | 0 | bool Output::inMapAnyKey(InState State) { |
842 | 0 | return State == inMapFirstKey || State == inMapOtherKey; |
843 | 0 | } |
844 | | |
845 | 1.02M | bool Output::inFlowMapAnyKey(InState State) { |
846 | 1.02M | return State == inFlowMapFirstKey || State == inFlowMapOtherKey937k ; |
847 | 1.02M | } |
848 | | |
849 | | //===----------------------------------------------------------------------===// |
850 | | // traits for built-in types |
851 | | //===----------------------------------------------------------------------===// |
852 | | |
853 | 227k | void ScalarTraits<bool>::output(const bool &Val, void *, raw_ostream &Out) { |
854 | 227k | Out << (Val ? "true"38.0k : "false"189k ); |
855 | 227k | } |
856 | | |
857 | 108k | StringRef ScalarTraits<bool>::input(StringRef Scalar, void *, bool &Val) { |
858 | 108k | if (Scalar.equals("true")) { |
859 | 15.5k | Val = true; |
860 | 15.5k | return StringRef(); |
861 | 92.4k | } else if (Scalar.equals("false")) { |
862 | 13.5k | Val = false; |
863 | 13.5k | return StringRef(); |
864 | 13.5k | } |
865 | 78.9k | return "invalid boolean"; |
866 | 78.9k | } |
867 | | |
868 | | void ScalarTraits<StringRef>::output(const StringRef &Val, void *, |
869 | 36.6k | raw_ostream &Out) { |
870 | 36.6k | Out << Val; |
871 | 36.6k | } |
872 | | |
873 | | StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *, |
874 | 23.5k | StringRef &Val) { |
875 | 23.5k | Val = Scalar; |
876 | 23.5k | return StringRef(); |
877 | 23.5k | } |
878 | | |
879 | | void ScalarTraits<std::string>::output(const std::string &Val, void *, |
880 | 8.94k | raw_ostream &Out) { |
881 | 8.94k | Out << Val; |
882 | 8.94k | } |
883 | | |
884 | | StringRef ScalarTraits<std::string>::input(StringRef Scalar, void *, |
885 | 80.2k | std::string &Val) { |
886 | 80.2k | Val = Scalar.str(); |
887 | 80.2k | return StringRef(); |
888 | 80.2k | } |
889 | | |
890 | | void ScalarTraits<uint8_t>::output(const uint8_t &Val, void *, |
891 | 6.46k | raw_ostream &Out) { |
892 | 6.46k | // use temp uin32_t because ostream thinks uint8_t is a character |
893 | 6.46k | uint32_t Num = Val; |
894 | 6.46k | Out << Num; |
895 | 6.46k | } |
896 | | |
897 | 1.16k | StringRef ScalarTraits<uint8_t>::input(StringRef Scalar, void *, uint8_t &Val) { |
898 | 1.16k | unsigned long long n; |
899 | 1.16k | if (getAsUnsignedInteger(Scalar, 0, n)) |
900 | 0 | return "invalid number"; |
901 | 1.16k | if (n > 0xFF) |
902 | 1 | return "out of range number"; |
903 | 1.16k | Val = n; |
904 | 1.16k | return StringRef(); |
905 | 1.16k | } |
906 | | |
907 | | void ScalarTraits<uint16_t>::output(const uint16_t &Val, void *, |
908 | 5.63k | raw_ostream &Out) { |
909 | 5.63k | Out << Val; |
910 | 5.63k | } |
911 | | |
912 | | StringRef ScalarTraits<uint16_t>::input(StringRef Scalar, void *, |
913 | 5.80k | uint16_t &Val) { |
914 | 5.80k | unsigned long long n; |
915 | 5.80k | if (getAsUnsignedInteger(Scalar, 0, n)) |
916 | 0 | return "invalid number"; |
917 | 5.80k | if (n > 0xFFFF) |
918 | 1 | return "out of range number"; |
919 | 5.80k | Val = n; |
920 | 5.80k | return StringRef(); |
921 | 5.80k | } |
922 | | |
923 | | void ScalarTraits<uint32_t>::output(const uint32_t &Val, void *, |
924 | 176k | raw_ostream &Out) { |
925 | 176k | Out << Val; |
926 | 176k | } |
927 | | |
928 | | StringRef ScalarTraits<uint32_t>::input(StringRef Scalar, void *, |
929 | 45.0k | uint32_t &Val) { |
930 | 45.0k | unsigned long long n; |
931 | 45.0k | if (getAsUnsignedInteger(Scalar, 0, n)) |
932 | 0 | return "invalid number"; |
933 | 45.0k | if (n > 0xFFFFFFFFUL) |
934 | 1 | return "out of range number"; |
935 | 45.0k | Val = n; |
936 | 45.0k | return StringRef(); |
937 | 45.0k | } |
938 | | |
939 | | void ScalarTraits<uint64_t>::output(const uint64_t &Val, void *, |
940 | 23.1k | raw_ostream &Out) { |
941 | 23.1k | Out << Val; |
942 | 23.1k | } |
943 | | |
944 | | StringRef ScalarTraits<uint64_t>::input(StringRef Scalar, void *, |
945 | 187k | uint64_t &Val) { |
946 | 187k | unsigned long long N; |
947 | 187k | if (getAsUnsignedInteger(Scalar, 0, N)) |
948 | 79.0k | return "invalid number"; |
949 | 108k | Val = N; |
950 | 108k | return StringRef(); |
951 | 108k | } |
952 | | |
953 | 1 | void ScalarTraits<int8_t>::output(const int8_t &Val, void *, raw_ostream &Out) { |
954 | 1 | // use temp in32_t because ostream thinks int8_t is a character |
955 | 1 | int32_t Num = Val; |
956 | 1 | Out << Num; |
957 | 1 | } |
958 | | |
959 | 10 | StringRef ScalarTraits<int8_t>::input(StringRef Scalar, void *, int8_t &Val) { |
960 | 10 | long long N; |
961 | 10 | if (getAsSignedInteger(Scalar, 0, N)) |
962 | 0 | return "invalid number"; |
963 | 10 | if ((N > 127) || (N < -128)9 ) |
964 | 2 | return "out of range number"; |
965 | 8 | Val = N; |
966 | 8 | return StringRef(); |
967 | 8 | } |
968 | | |
969 | | void ScalarTraits<int16_t>::output(const int16_t &Val, void *, |
970 | 2 | raw_ostream &Out) { |
971 | 2 | Out << Val; |
972 | 2 | } |
973 | | |
974 | 12 | StringRef ScalarTraits<int16_t>::input(StringRef Scalar, void *, int16_t &Val) { |
975 | 12 | long long N; |
976 | 12 | if (getAsSignedInteger(Scalar, 0, N)) |
977 | 0 | return "invalid number"; |
978 | 12 | if ((N > INT16_MAX) || (N < INT16_MIN)11 ) |
979 | 2 | return "out of range number"; |
980 | 10 | Val = N; |
981 | 10 | return StringRef(); |
982 | 10 | } |
983 | | |
984 | | void ScalarTraits<int32_t>::output(const int32_t &Val, void *, |
985 | 12.9k | raw_ostream &Out) { |
986 | 12.9k | Out << Val; |
987 | 12.9k | } |
988 | | |
989 | 4.24k | StringRef ScalarTraits<int32_t>::input(StringRef Scalar, void *, int32_t &Val) { |
990 | 4.24k | long long N; |
991 | 4.24k | if (getAsSignedInteger(Scalar, 0, N)) |
992 | 0 | return "invalid number"; |
993 | 4.24k | if ((N > INT32_MAX) || (N < INT32_MIN)4.24k ) |
994 | 2 | return "out of range number"; |
995 | 4.24k | Val = N; |
996 | 4.24k | return StringRef(); |
997 | 4.24k | } |
998 | | |
999 | | void ScalarTraits<int64_t>::output(const int64_t &Val, void *, |
1000 | 1.99k | raw_ostream &Out) { |
1001 | 1.99k | Out << Val; |
1002 | 1.99k | } |
1003 | | |
1004 | 79.9k | StringRef ScalarTraits<int64_t>::input(StringRef Scalar, void *, int64_t &Val) { |
1005 | 79.9k | long long N; |
1006 | 79.9k | if (getAsSignedInteger(Scalar, 0, N)) |
1007 | 79.0k | return "invalid number"; |
1008 | 950 | Val = N; |
1009 | 950 | return StringRef(); |
1010 | 950 | } |
1011 | | |
1012 | 10 | void ScalarTraits<double>::output(const double &Val, void *, raw_ostream &Out) { |
1013 | 10 | Out << format("%g", Val); |
1014 | 10 | } |
1015 | | |
1016 | 78.9k | StringRef ScalarTraits<double>::input(StringRef Scalar, void *, double &Val) { |
1017 | 78.9k | if (to_float(Scalar, Val)) |
1018 | 34 | return StringRef(); |
1019 | 78.9k | return "invalid floating point number"; |
1020 | 78.9k | } |
1021 | | |
1022 | 2 | void ScalarTraits<float>::output(const float &Val, void *, raw_ostream &Out) { |
1023 | 2 | Out << format("%g", Val); |
1024 | 2 | } |
1025 | | |
1026 | 8 | StringRef ScalarTraits<float>::input(StringRef Scalar, void *, float &Val) { |
1027 | 8 | if (to_float(Scalar, Val)) |
1028 | 7 | return StringRef(); |
1029 | 1 | return "invalid floating point number"; |
1030 | 1 | } |
1031 | | |
1032 | 409 | void ScalarTraits<Hex8>::output(const Hex8 &Val, void *, raw_ostream &Out) { |
1033 | 409 | uint8_t Num = Val; |
1034 | 409 | Out << format("0x%02X", Num); |
1035 | 409 | } |
1036 | | |
1037 | 6.33k | StringRef ScalarTraits<Hex8>::input(StringRef Scalar, void *, Hex8 &Val) { |
1038 | 6.33k | unsigned long long n; |
1039 | 6.33k | if (getAsUnsignedInteger(Scalar, 0, n)) |
1040 | 0 | return "invalid hex8 number"; |
1041 | 6.33k | if (n > 0xFF) |
1042 | 1 | return "out of range hex8 number"; |
1043 | 6.33k | Val = n; |
1044 | 6.33k | return StringRef(); |
1045 | 6.33k | } |
1046 | | |
1047 | 25 | void ScalarTraits<Hex16>::output(const Hex16 &Val, void *, raw_ostream &Out) { |
1048 | 25 | uint16_t Num = Val; |
1049 | 25 | Out << format("0x%04X", Num); |
1050 | 25 | } |
1051 | | |
1052 | 59 | StringRef ScalarTraits<Hex16>::input(StringRef Scalar, void *, Hex16 &Val) { |
1053 | 59 | unsigned long long n; |
1054 | 59 | if (getAsUnsignedInteger(Scalar, 0, n)) |
1055 | 0 | return "invalid hex16 number"; |
1056 | 59 | if (n > 0xFFFF) |
1057 | 1 | return "out of range hex16 number"; |
1058 | 58 | Val = n; |
1059 | 58 | return StringRef(); |
1060 | 58 | } |
1061 | | |
1062 | 2.98k | void ScalarTraits<Hex32>::output(const Hex32 &Val, void *, raw_ostream &Out) { |
1063 | 2.98k | uint32_t Num = Val; |
1064 | 2.98k | Out << format("0x%08X", Num); |
1065 | 2.98k | } |
1066 | | |
1067 | 3.24k | StringRef ScalarTraits<Hex32>::input(StringRef Scalar, void *, Hex32 &Val) { |
1068 | 3.24k | unsigned long long n; |
1069 | 3.24k | if (getAsUnsignedInteger(Scalar, 0, n)) |
1070 | 0 | return "invalid hex32 number"; |
1071 | 3.24k | if (n > 0xFFFFFFFFUL) |
1072 | 1 | return "out of range hex32 number"; |
1073 | 3.23k | Val = n; |
1074 | 3.23k | return StringRef(); |
1075 | 3.23k | } |
1076 | | |
1077 | 1.11k | void ScalarTraits<Hex64>::output(const Hex64 &Val, void *, raw_ostream &Out) { |
1078 | 1.11k | uint64_t Num = Val; |
1079 | 1.11k | Out << format("0x%016llX", Num); |
1080 | 1.11k | } |
1081 | | |
1082 | 6.14k | StringRef ScalarTraits<Hex64>::input(StringRef Scalar, void *, Hex64 &Val) { |
1083 | 6.14k | unsigned long long Num; |
1084 | 6.14k | if (getAsUnsignedInteger(Scalar, 0, Num)) |
1085 | 2 | return "invalid hex64 number"; |
1086 | 6.13k | Val = Num; |
1087 | 6.13k | return StringRef(); |
1088 | 6.13k | } |