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