37IO::IO(
void *Context) : Ctxt(Context) {}
59 :
IO(Ctxt), Strm(new
Stream(InputContent, SrcMgr,
false, &EC)) {
61 SrcMgr.setDiagHandler(
DiagHandler, DiagHandlerCtxt);
62 DocIterator = Strm->begin();
69 SrcMgr.setDiagHandler(
DiagHandler, DiagHandlerCtxt);
70 DocIterator = Strm->begin();
82 if (DocIterator != Strm->end()) {
83 Node *
N = DocIterator->getRoot();
94 releaseHNodeBuffers();
95 TopNode = createHNodes(
N);
96 CurrentNode = TopNode;
103 return ++DocIterator != Strm->end();
107 return CurrentNode ? CurrentNode->_node :
nullptr;
117 if (foundTag.empty()) {
122 return Tag == foundTag;
131 MN->ValidKeys.clear();
137 std::vector<StringRef> Ret;
139 setError(CurrentNode,
"not a mapping");
142 for (
auto &
P : MN->Mapping)
143 Ret.push_back(
P.first());
147bool Input::preflightKey(StringRef
Key,
bool Required,
bool,
bool &UseDefault,
166 setError(CurrentNode,
"not a mapping");
171 MN->ValidKeys.push_back(
Key.str());
172 HNode *
Value = MN->Mapping[
Key].first;
175 setError(CurrentNode, Twine(
"missing required key '") +
Key +
"'");
180 SaveInfo = CurrentNode;
185void Input::postflightKey(
void *saveInfo) {
186 CurrentNode =
reinterpret_cast<HNode *
>(saveInfo);
196 for (
const auto &NN : MN->Mapping) {
198 const SMRange &ReportLoc = NN.second.second;
199 if (!AllowUnknownKeys) {
200 setError(ReportLoc, Twine(
"unknown key '") + NN.first() +
"'");
203 reportWarning(ReportLoc, Twine(
"unknown key '") + NN.first() +
"'");
214 return SQ->Entries.size();
223 setError(CurrentNode,
"not a sequence");
230bool Input::preflightElement(
unsigned Index,
void *&SaveInfo) {
234 SaveInfo = CurrentNode;
235 CurrentNode = SQ->Entries[
Index];
241void Input::postflightElement(
void *SaveInfo) {
242 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
247bool Input::preflightFlowElement(
unsigned index,
void *&SaveInfo) {
251 SaveInfo = CurrentNode;
252 CurrentNode = SQ->Entries[index];
258void Input::postflightFlowElement(
void *SaveInfo) {
259 CurrentNode =
reinterpret_cast<HNode *
>(SaveInfo);
266 ScalarMatchFound =
false;
269bool Input::matchEnumScalar(StringRef Str,
bool) {
270 if (ScalarMatchFound)
273 if (SN->value() == Str) {
274 ScalarMatchFound =
true;
282 if (ScalarMatchFound)
284 ScalarMatchFound =
true;
289 if (!ScalarMatchFound) {
290 setError(CurrentNode,
"unknown enumerated scalar");
294bool Input::beginBitSetScalar(
bool &DoClear) {
295 BitValuesUsed.clear();
297 BitValuesUsed.resize(SQ->Entries.size());
299 setError(CurrentNode,
"expected sequence of bit values");
305bool Input::bitSetMatch(StringRef Str,
bool) {
310 for (
auto &
N : SQ->Entries) {
312 if (SN->value() == Str) {
313 BitValuesUsed[
Index] =
true;
317 setError(CurrentNode,
"unexpected scalar in sequence of bit values");
322 setError(CurrentNode,
"expected sequence of bit values");
331 assert(BitValuesUsed.size() == SQ->Entries.size());
332 for (
unsigned i = 0; i < SQ->Entries.size(); ++i) {
333 if (!BitValuesUsed[i]) {
334 setError(SQ->Entries[i],
"unknown bit value");
341void Input::scalarString(StringRef &S,
QuotingType) {
345 setError(CurrentNode,
"unexpected scalar");
349void Input::blockScalarString(StringRef &S) { scalarString(S,
QuotingType::None); }
351void Input::scalarTag(std::string &
Tag) {
352 Tag = CurrentNode->_node->getVerbatimTag();
355void Input::setError(HNode *hnode,
const Twine &message) {
356 assert(hnode &&
"HNode must not be NULL");
357 setError(hnode->_node, message);
370void Input::setError(
Node *node,
const Twine &message) {
371 Strm->printError(node, message);
375void Input::setError(
const SMRange &range,
const Twine &message) {
376 Strm->printError(range, message);
380void Input::reportWarning(HNode *hnode,
const Twine &message) {
381 assert(hnode &&
"HNode must not be NULL");
385void Input::reportWarning(
Node *node,
const Twine &message) {
389void Input::reportWarning(
const SMRange &range,
const Twine &message) {
393void Input::releaseHNodeBuffers() {
394 EmptyHNodeAllocator.DestroyAll();
395 ScalarHNodeAllocator.DestroyAll();
396 SequenceHNodeAllocator.DestroyAll();
397 MapHNodeAllocator.DestroyAll();
400void Input::saveAliasHNode(
Node *
N, HNode *HN) {
401 StringRef Anchor =
N->getAnchor();
409 AliasMap[Anchor] = HN;
412Input::HNode *Input::createHNodes(
Node *
N) {
413 SmallString<128> StringStorage;
414 switch (
N->getType()) {
417 StringRef KeyStr = SN->
getValue(StringStorage);
418 if (!StringStorage.
empty()) {
420 KeyStr = StringStorage.
str().
copy(StringAllocator);
422 auto *SHNode =
new (ScalarHNodeAllocator.Allocate()) ScalarHNode(
N, KeyStr);
423 saveAliasHNode(SN, SHNode);
428 StringRef ValueCopy = BSN->
getValue().
copy(StringAllocator);
430 new (ScalarHNodeAllocator.Allocate()) ScalarHNode(
N, ValueCopy);
431 saveAliasHNode(BSN, BSHNode);
436 auto SQHNode =
new (SequenceHNodeAllocator.Allocate()) SequenceHNode(
N);
437 for (Node &SN : *SQ) {
438 auto Entry = createHNodes(&SN);
441 SQHNode->Entries.push_back(Entry);
443 saveAliasHNode(SQ, SQHNode);
448 auto mapHNode =
new (MapHNodeAllocator.Allocate()) MapHNode(
N);
449 for (KeyValueNode &KVN : *
Map) {
450 Node *KeyNode = KVN.getKey();
455 setError(KeyNode,
"Map key must be a scalar");
457 setError(KeyNode,
"Map value must not be empty");
460 StringStorage.
clear();
461 StringRef KeyStr =
Key->getValue(StringStorage);
462 if (!StringStorage.
empty()) {
464 KeyStr = StringStorage.
str().
copy(StringAllocator);
466 if (mapHNode->Mapping.count(KeyStr))
470 setError(KeyNode, Twine(
"duplicated mapping key '") + KeyStr +
"'");
471 auto ValueHNode = createHNodes(
Value);
474 mapHNode->Mapping[KeyStr] =
475 std::make_pair(std::move(ValueHNode), KeyNode->getSourceRange());
477 saveAliasHNode(
Map, mapHNode);
478 return std::move(mapHNode);
483 return new (EmptyHNodeAllocator.Allocate()) EmptyHNode(
N);
486 auto AliasName = AN->
getName();
487 auto AHN = AliasMap.
find(AliasName);
488 if (AHN == AliasMap.end()) {
489 setError(AN, Twine(
"undefined alias '" + AliasName +
"'"));
495 setError(
N,
"unknown node kind");
500void Input::setError(
const Twine &Message) {
501 setError(CurrentNode, Message);
515 :
IO(context), Out(yout), WrapColumn(WrapColumn) {}
524 StateStack.push_back(inMapFirstKey);
525 PaddingBeforeContainer = Padding;
534 bool SequenceElement =
false;
535 if (StateStack.size() > 1) {
536 auto &E = StateStack[StateStack.size() - 2];
537 SequenceElement = inSeqAnyElement(E) || inFlowSeqAnyElement(E);
539 if (SequenceElement && StateStack.back() == inMapFirstKey) {
545 if (SequenceElement) {
548 if (StateStack.back() == inMapFirstKey) {
549 StateStack.pop_back();
550 StateStack.push_back(inMapOtherKey);
562 if (StateStack.back() == inMapFirstKey) {
563 Padding = PaddingBeforeContainer;
568 StateStack.pop_back();
576 bool &UseDefault,
void *&SaveInfo) {
579 if (
Required || !SameAsDefault || WriteDefaultValues) {
580 auto State = StateStack.back();
581 if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
593 if (StateStack.back() == inMapFirstKey) {
594 StateStack.pop_back();
595 StateStack.push_back(inMapOtherKey);
596 }
else if (StateStack.back() == inFlowMapFirstKey) {
597 StateStack.pop_back();
598 StateStack.push_back(inFlowMapOtherKey);
603 StateStack.push_back(inFlowMapFirstKey);
605 ColumnAtMapFlowStart = Column;
610 StateStack.pop_back();
611 outputUpToEndOfLine(
" }");
615 outputUpToEndOfLine(
"---");
620 outputUpToEndOfLine(
"\n---");
632 StateStack.push_back(inSeqFirstElement);
633 PaddingBeforeContainer = Padding;
640 if (StateStack.back() == inSeqFirstElement) {
641 Padding = PaddingBeforeContainer;
646 StateStack.pop_back();
655 if (StateStack.back() == inSeqFirstElement) {
656 StateStack.pop_back();
657 StateStack.push_back(inSeqOtherElement);
658 }
else if (StateStack.back() == inFlowSeqFirstElement) {
659 StateStack.pop_back();
660 StateStack.push_back(inFlowSeqOtherElement);
665 StateStack.push_back(inFlowSeqFirstElement);
667 ColumnAtFlowStart = Column;
669 NeedFlowSequenceComma =
false;
674 StateStack.pop_back();
675 outputUpToEndOfLine(
" ]");
679 if (NeedFlowSequenceComma)
681 if (WrapColumn && Column > WrapColumn) {
683 for (
int i = 0; i < ColumnAtFlowStart; ++i)
685 Column = ColumnAtFlowStart;
693 NeedFlowSequenceComma =
true;
697 EnumerationMatchFound =
false;
701 if (Match && !EnumerationMatchFound) {
703 outputUpToEndOfLine(Str);
704 EnumerationMatchFound =
true;
710 if (EnumerationMatchFound)
712 EnumerationMatchFound =
true;
717 if (!EnumerationMatchFound)
724 NeedBitValueComma =
false;
731 if (NeedBitValueComma)
734 NeedBitValueComma =
true;
740 outputUpToEndOfLine(
" ]");
748 outputUpToEndOfLine(
"''");
751 output(S, MustQuote);
752 outputUpToEndOfLine(
"");
756 if (!StateStack.empty())
760 unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
763 for (
line_iterator Lines(*Buffer,
false); !Lines.is_at_end(); ++Lines) {
765 for (
unsigned I = 0;
I < Indent; ++
I) {
770 outputUpToEndOfLine(
"");
792 if (StateStack.size() < 2)
794 if (StateStack.back() != inMapFirstKey)
796 return !inSeqAnyElement(StateStack[StateStack.size() - 2]);
827 unsigned End = S.
size();
834 output(StringRef(&
Base[i], j - i));
835 output(StringLiteral(
"''"));
840 output(StringRef(&
Base[i], j - i));
844void Output::outputUpToEndOfLine(StringRef s) {
846 if (StateStack.empty() || (!inFlowSeqAnyElement(StateStack.back()) &&
847 !inFlowMapAnyKey(StateStack.back())))
851void Output::outputNewLine() {
860void Output::newLineCheck(
bool EmptySequence) {
861 if (Padding !=
"\n") {
869 if (StateStack.size() == 0 || EmptySequence)
872 unsigned Indent = StateStack.size() - 1;
873 bool PossiblyNestedSeq =
false;
874 auto I = StateStack.rbegin(),
E = StateStack.rend();
876 if (inSeqAnyElement(*
I)) {
877 PossiblyNestedSeq =
true;
879 }
else if (*
I == inMapFirstKey || *
I == inFlowMapFirstKey ||
880 inFlowSeqAnyElement(*
I)) {
881 PossiblyNestedSeq =
true;
885 unsigned OutputDashCount = 0;
886 if (PossiblyNestedSeq) {
891 if (!inSeqAnyElement(*
I))
897 if (*
I++ != inSeqFirstElement)
902 for (
unsigned I = OutputDashCount;
I < Indent; ++
I)
905 for (
unsigned I = 0;
I < OutputDashCount; ++
I)
909void Output::paddedKey(StringRef key) {
919void Output::flowKey(StringRef
Key) {
920 if (StateStack.back() == inFlowMapOtherKey)
922 if (WrapColumn && Column > WrapColumn) {
924 for (
int I = 0;
I < ColumnAtMapFlowStart; ++
I)
926 Column = ColumnAtMapFlowStart;
935bool Output::inSeqAnyElement(InState State) {
936 return State == inSeqFirstElement || State == inSeqOtherElement;
939bool Output::inFlowSeqAnyElement(InState State) {
940 return State == inFlowSeqFirstElement || State == inFlowSeqOtherElement;
943bool Output::inMapAnyKey(InState State) {
944 return State == inMapFirstKey || State == inMapOtherKey;
947bool Output::inFlowMapAnyKey(InState State) {
948 return State == inFlowMapFirstKey || State == inFlowMapOtherKey;
956 Out << (Val ?
"true" :
"false");
964 return "invalid boolean";
997 unsigned long long n;
999 return "invalid number";
1001 return "out of range number";
1013 unsigned long long n;
1015 return "invalid number";
1017 return "out of range number";
1029 unsigned long long n;
1031 return "invalid number";
1032 if (n > 0xFFFFFFFFUL)
1033 return "out of range number";
1045 unsigned long long N;
1047 return "invalid number";
1061 return "invalid number";
1062 if ((
N > 127) || (
N < -128))
1063 return "out of range number";
1076 return "invalid number";
1077 if ((
N > INT16_MAX) || (
N < INT16_MIN))
1078 return "out of range number";
1091 return "invalid number";
1092 if ((
N > INT32_MAX) || (
N < INT32_MIN))
1093 return "out of range number";
1106 return "invalid number";
1112 Out <<
format(
"%g", Val);
1118 return "invalid floating point number";
1122 Out <<
format(
"%g", Val);
1128 return "invalid floating point number";
1132 Out <<
format(
"0x%" PRIX8, (uint8_t)Val);
1136 unsigned long long n;
1138 return "invalid hex8 number";
1140 return "out of range hex8 number";
1146 Out <<
format(
"0x%" PRIX16, (uint16_t)Val);
1150 unsigned long long n;
1152 return "invalid hex16 number";
1154 return "out of range hex16 number";
1160 Out <<
format(
"0x%" PRIX32, (uint32_t)Val);
1164 unsigned long long n;
1166 return "invalid hex32 number";
1167 if (n > 0xFFFFFFFFUL)
1168 return "out of range hex32 number";
1174 Out <<
format(
"0x%" PRIX64, (uint64_t)Val);
1178 unsigned long long Num;
1180 return "invalid hex64 number";
1186 llvm::raw_ostream &Out) {
1191 VersionTuple &Val) {
1193 return "invalid version format";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the SmallString class.
static void DiagHandler(const SMDiagnostic &Diag, void *Context)
Defines the llvm::VersionTuple class, which represents a version in the form major[....
static std::unique_ptr< MemoryBuffer > getMemBuffer(StringRef InputData, StringRef BufferName="", bool RequiresNullTerminator=true)
Open the specified memory range as a MemoryBuffer.
StringRef str() const
Explicit conversion to StringRef.
void(*)(const SMDiagnostic &, void *Context) DiagHandlerTy
Clients that want to handle their own diagnostics in a custom way can register a function pointer+con...
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
StringRef copy(Allocator &A) const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
LLVM_ABI bool tryParse(StringRef string)
Try to parse the given string as a version number.
LLVM_ABI std::string getAsString() const
Retrieve a string representation of the version number.
A forward iterator which reads text lines from a buffer.
This class implements an extremely fast bulk output stream that can only output to a stream.
StringRef getName() const
StringRef getValue() const
Gets the value of this node as a StringRef.
virtual bool canElideEmptySequence()=0
virtual NodeKind getNodeKind()=0
virtual void endSequence()=0
virtual void endEnumScalar()=0
virtual bool outputting() const =0
virtual unsigned beginFlowSequence()=0
virtual void endFlowSequence()=0
virtual void beginMapping()=0
virtual void setAllowUnknownKeys(bool Allow)
virtual void endMapping()=0
virtual unsigned beginSequence()=0
virtual void beginEnumScalar()=0
void * getContext() const
virtual void endFlowMapping()=0
virtual void beginFlowMapping()=0
virtual bool matchEnumFallback()=0
virtual void endBitSetScalar()=0
virtual std::vector< StringRef > keys()=0
Abstract base class for all Nodes.
std::string getVerbatimTag() const
Get the verbatium tag for a given Node.
unsigned beginFlowSequence() override
std::vector< StringRef > keys() override
Output(raw_ostream &, void *Ctxt=nullptr, int WrapColumn=70)
void setError(const Twine &message) override
void scalarString(StringRef &, QuotingType) override
void endBitSetScalar() override
void beginFlowMapping() override
void endFlowMapping() override
void endFlowSequence() override
void postflightElement(void *) override
void endEnumScalar() override
void blockScalarString(StringRef &) override
bool preflightDocument(unsigned)
bool bitSetMatch(StringRef, bool) override
bool canElideEmptySequence() override
void beginMapping() override
void postflightFlowElement(void *) override
void scalarTag(std::string &) override
bool beginBitSetScalar(bool &) override
bool mapTag(StringRef, bool) override
bool preflightElement(unsigned, void *&) override
bool matchEnumFallback() override
void beginEnumScalar() override
bool preflightKey(StringRef Key, bool, bool, bool &, void *&) override
void endSequence() override
bool matchEnumScalar(StringRef, bool) override
bool outputting() const override
unsigned beginSequence() override
NodeKind getNodeKind() override
void endMapping() override
std::error_code error() override
void postflightKey(void *) override
void postflightDocument()
bool preflightFlowElement(unsigned, void *&) override
StringRef getValue(SmallVectorImpl< char > &Storage) const
Gets the value of this node as a StringRef.
This class represents a YAML stream potentially containing multiple documents.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
NodeAddr< NodeBase * > Node
QuotingType
Describe which type of quotes should be used when quoting is necessary.
LLVM_ABI std::optional< bool > parseBool(StringRef S)
Parse S as a bool according to https://yaml.org/type/bool.html.
QuotingType needsQuotes(StringRef S, bool ForcePreserveAsString=true)
LLVM_ABI std::string escape(StringRef Input, bool EscapePrintable=true)
Escape Input for a double quoted scalar; if EscapePrintable is true, all UTF8 sequences will be escap...
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result)
std::error_code make_error_code(BitcodeError E)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
bool to_float(const Twine &T, float &Num)
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix, unsigned long long &Result)
Helper functions for StringRef::getAsInteger.
@ Default
The result value is uniform if and only if all operands are uniform.
This class should be specialized by type that requires custom conversion to/from a yaml scalar.