@@ -26,49 +26,47 @@ using llvm::yaml::SequenceNode;
2626
2727class Parser {
2828 llvm::SourceMgr &SM;
29+ bool HadError = false ;
2930
3031public:
3132 Parser (llvm::SourceMgr &SM) : SM(SM) {}
3233
3334 // Tries to parse N into F, returning false if it failed and we couldn't
34- // meaningfully recover (e.g. YAML syntax error broke the stream).
35- // The private parse() helpers follow the same pattern.
35+ // meaningfully recover (YAML syntax error, or hard semantic error).
3636 bool parse (Fragment &F, Node &N) {
3737 DictParser Dict (" Config" , this );
38- Dict.handle (" If" , [&](Node &N) { return parse (F.If , N); });
39- Dict.handle (" CompileFlags" ,
40- [&](Node &N) { return parse (F. CompileFlags , N); } );
41- return Dict. parse (N );
38+ Dict.handle (" If" , [&](Node &N) { parse (F.If , N); });
39+ Dict.handle (" CompileFlags" , [&](Node &N) { parse (F. CompileFlags , N); });
40+ Dict. parse (N );
41+ return !(N. failed () || HadError );
4242 }
4343
4444private:
45- bool parse (Fragment::IfBlock &F, Node &N) {
45+ void parse (Fragment::IfBlock &F, Node &N) {
4646 DictParser Dict (" If" , this );
4747 Dict.unrecognized (
4848 [&](llvm::StringRef) { F.HasUnrecognizedCondition = true ; });
4949 Dict.handle (" PathMatch" , [&](Node &N) {
5050 if (auto Values = scalarValues (N))
5151 F.PathMatch = std::move (*Values);
52- return !N.failed ();
5352 });
54- return Dict.parse (N);
53+ Dict.parse (N);
5554 }
5655
57- bool parse (Fragment::CompileFlagsBlock &F, Node &N) {
56+ void parse (Fragment::CompileFlagsBlock &F, Node &N) {
5857 DictParser Dict (" CompileFlags" , this );
5958 Dict.handle (" Add" , [&](Node &N) {
6059 if (auto Values = scalarValues (N))
6160 F.Add = std::move (*Values);
62- return !N.failed ();
6361 });
64- return Dict.parse (N);
62+ Dict.parse (N);
6563 }
6664
6765 // Helper for parsing mapping nodes (dictionaries).
6866 // We don't use YamlIO as we want to control over unknown keys.
6967 class DictParser {
7068 llvm::StringRef Description;
71- std::vector<std::pair<llvm::StringRef, std::function<bool (Node &)>>> Keys;
69+ std::vector<std::pair<llvm::StringRef, std::function<void (Node &)>>> Keys;
7270 std::function<void (llvm::StringRef)> Unknown;
7371 Parser *Outer;
7472
@@ -79,7 +77,7 @@ class Parser {
7977 // Parse is called when Key is encountered, and passed the associated value.
8078 // It should emit diagnostics if the value is invalid (e.g. wrong type).
8179 // If Key is seen twice, Parse runs only once and an error is reported.
82- void handle (llvm::StringLiteral Key, std::function<bool (Node &)> Parse) {
80+ void handle (llvm::StringLiteral Key, std::function<void (Node &)> Parse) {
8381 for (const auto &Entry : Keys) {
8482 (void ) Entry;
8583 assert (Entry.first != Key && " duplicate key handler" );
@@ -94,16 +92,17 @@ class Parser {
9492 }
9593
9694 // Process a mapping node and call handlers for each key/value pair.
97- bool parse (Node &N) const {
95+ void parse (Node &N) const {
9896 if (N.getType () != Node::NK_Mapping) {
9997 Outer->error (Description + " should be a dictionary" , N);
100- return false ;
98+ return ;
10199 }
102100 llvm::SmallSet<std::string, 8 > Seen;
101+ // We *must* consume all items, even on error, or the parser will assert.
103102 for (auto &KV : llvm::cast<MappingNode>(N)) {
104103 auto *K = KV.getKey ();
105104 if (!K) // YAMLParser emitted an error.
106- return false ;
105+ continue ;
107106 auto Key = Outer->scalarValue (*K, " Dictionary key" );
108107 if (!Key)
109108 continue ;
@@ -113,13 +112,12 @@ class Parser {
113112 }
114113 auto *Value = KV.getValue ();
115114 if (!Value) // YAMLParser emitted an error.
116- return false ;
115+ continue ;
117116 bool Matched = false ;
118117 for (const auto &Handler : Keys) {
119118 if (Handler.first == **Key) {
120- if (!Handler.second (*Value))
121- return false ;
122119 Matched = true ;
120+ Handler.second (*Value);
123121 break ;
124122 }
125123 }
@@ -129,7 +127,6 @@ class Parser {
129127 Unknown (**Key);
130128 }
131129 }
132- return true ;
133130 }
134131 };
135132
@@ -154,6 +151,7 @@ class Parser {
154151 } else if (auto *S = llvm::dyn_cast<BlockScalarNode>(&N)) {
155152 Result.emplace_back (S->getValue ().str (), N.getSourceRange ());
156153 } else if (auto *S = llvm::dyn_cast<SequenceNode>(&N)) {
154+ // We *must* consume all items, even on error, or the parser will assert.
157155 for (auto &Child : *S) {
158156 if (auto Value = scalarValue (Child, " List item" ))
159157 Result.push_back (std::move (*Value));
@@ -167,6 +165,7 @@ class Parser {
167165
168166 // Report a "hard" error, reflecting a config file that can never be valid.
169167 void error (const llvm::Twine &Msg, const Node &N) {
168+ HadError = true ;
170169 SM.PrintMessage (N.getSourceRange ().Start , llvm::SourceMgr::DK_Error, Msg,
171170 N.getSourceRange ());
172171 }
@@ -196,7 +195,7 @@ std::vector<Fragment> Fragment::parseYAML(llvm::StringRef YAML,
196195 &Diags);
197196 std::vector<Fragment> Result;
198197 for (auto &Doc : llvm::yaml::Stream (*Buf, *SM)) {
199- if (Node *N = Doc.parseBlockNode ()) {
198+ if (Node *N = Doc.getRoot ()) {
200199 Fragment Fragment;
201200 Fragment.Source .Manager = SM;
202201 Fragment.Source .Location = N->getSourceRange ().Start ;
0 commit comments