]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp
MFC r345703:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / ExpressionParser / Go / GoParser.cpp
1 //===-- GoParser.cpp ---------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <vector>
11
12 #include "GoParser.h"
13
14 #include "Plugins/ExpressionParser/Go/GoAST.h"
15 #include "lldb/Utility/Status.h"
16 #include "llvm/ADT/SmallString.h"
17
18 using namespace lldb_private;
19 using namespace lldb;
20
21 namespace {
22 llvm::StringRef DescribeToken(GoLexer::TokenType t) {
23   switch (t) {
24   case GoLexer::TOK_EOF:
25     return "<eof>";
26   case GoLexer::TOK_IDENTIFIER:
27     return "identifier";
28   case GoLexer::LIT_FLOAT:
29     return "float";
30   case GoLexer::LIT_IMAGINARY:
31     return "imaginary";
32   case GoLexer::LIT_INTEGER:
33     return "integer";
34   case GoLexer::LIT_RUNE:
35     return "rune";
36   case GoLexer::LIT_STRING:
37     return "string";
38   default:
39     return GoLexer::LookupToken(t);
40   }
41 }
42 } // namespace
43
44 class GoParser::Rule {
45 public:
46   Rule(llvm::StringRef name, GoParser *p)
47       : m_name(name), m_parser(p), m_pos(p->m_pos) {}
48
49   std::nullptr_t error() {
50     if (!m_parser->m_failed) {
51       // Set m_error in case this is the top level.
52       if (m_parser->m_last_tok == GoLexer::TOK_INVALID)
53         m_parser->m_error = m_parser->m_last;
54       else
55         m_parser->m_error = DescribeToken(m_parser->m_last_tok);
56       // And set m_last in case it isn't.
57       m_parser->m_last = m_name;
58       m_parser->m_last_tok = GoLexer::TOK_INVALID;
59       m_parser->m_pos = m_pos;
60     }
61     return nullptr;
62   }
63
64 private:
65   llvm::StringRef m_name;
66   GoParser *m_parser;
67   size_t m_pos;
68 };
69
70 GoParser::GoParser(const char *src)
71     : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID),
72       m_failed(false) {}
73
74 GoASTStmt *GoParser::Statement() {
75   Rule r("Statement", this);
76   GoLexer::TokenType t = peek();
77   GoASTStmt *ret = nullptr;
78   switch (t) {
79   case GoLexer::TOK_EOF:
80   case GoLexer::OP_SEMICOLON:
81   case GoLexer::OP_RPAREN:
82   case GoLexer::OP_RBRACE:
83   case GoLexer::TOK_INVALID:
84     return EmptyStmt();
85   case GoLexer::OP_LBRACE:
86     return Block();
87
88   /*      TODO:
89 case GoLexer::KEYWORD_GO:
90   return GoStmt();
91 case GoLexer::KEYWORD_RETURN:
92   return ReturnStmt();
93 case GoLexer::KEYWORD_BREAK:
94 case GoLexer::KEYWORD_CONTINUE:
95 case GoLexer::KEYWORD_GOTO:
96 case GoLexer::KEYWORD_FALLTHROUGH:
97   return BranchStmt();
98 case GoLexer::KEYWORD_IF:
99   return IfStmt();
100 case GoLexer::KEYWORD_SWITCH:
101   return SwitchStmt();
102 case GoLexer::KEYWORD_SELECT:
103   return SelectStmt();
104 case GoLexer::KEYWORD_FOR:
105   return ForStmt();
106 case GoLexer::KEYWORD_DEFER:
107   return DeferStmt();
108 case GoLexer::KEYWORD_CONST:
109 case GoLexer::KEYWORD_TYPE:
110 case GoLexer::KEYWORD_VAR:
111   return DeclStmt();
112 case GoLexer::TOK_IDENTIFIER:
113   if ((ret = LabeledStmt()) ||
114       (ret = ShortVarDecl()))
115   {
116       return ret;
117   }
118 */
119   default:
120     break;
121   }
122   GoASTExpr *expr = Expression();
123   if (expr == nullptr)
124     return r.error();
125   if (/*(ret = SendStmt(expr)) ||*/
126       (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) ||
127       (ret = ExpressionStmt(expr))) {
128     return ret;
129   }
130   delete expr;
131   return r.error();
132 }
133
134 GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) {
135   if (Semicolon())
136     return new GoASTExprStmt(e);
137   return nullptr;
138 }
139
140 GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) {
141   Rule r("IncDecStmt", this);
142   if (match(GoLexer::OP_PLUS_PLUS))
143     return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS)
144                        : r.error();
145   if (match(GoLexer::OP_MINUS_MINUS))
146     return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS)
147                        : r.error();
148   return nullptr;
149 }
150
151 GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) {
152   Rule r("Assignment", this);
153   std::vector<std::unique_ptr<GoASTExpr>> lhs;
154   for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList())
155     lhs.push_back(std::unique_ptr<GoASTExpr>(l));
156   switch (peek()) {
157   case GoLexer::OP_EQ:
158   case GoLexer::OP_PLUS_EQ:
159   case GoLexer::OP_MINUS_EQ:
160   case GoLexer::OP_PIPE_EQ:
161   case GoLexer::OP_CARET_EQ:
162   case GoLexer::OP_STAR_EQ:
163   case GoLexer::OP_SLASH_EQ:
164   case GoLexer::OP_PERCENT_EQ:
165   case GoLexer::OP_LSHIFT_EQ:
166   case GoLexer::OP_RSHIFT_EQ:
167   case GoLexer::OP_AMP_EQ:
168   case GoLexer::OP_AMP_CARET_EQ:
169     break;
170   default:
171     return r.error();
172   }
173   // We don't want to own e until we know this is an assignment.
174   std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false));
175   stmt->AddLhs(e);
176   for (auto &l : lhs)
177     stmt->AddLhs(l.release());
178   for (GoASTExpr *r = Expression(); r; r = MoreExpressionList())
179     stmt->AddRhs(r);
180   if (!Semicolon() || stmt->NumRhs() == 0)
181     return new GoASTBadStmt;
182   return stmt.release();
183 }
184
185 GoASTStmt *GoParser::EmptyStmt() {
186   if (match(GoLexer::TOK_EOF))
187     return nullptr;
188   if (Semicolon())
189     return new GoASTEmptyStmt;
190   return nullptr;
191 }
192
193 GoASTStmt *GoParser::GoStmt() {
194   if (match(GoLexer::KEYWORD_GO)) {
195     if (GoASTCallExpr *e =
196             llvm::dyn_cast_or_null<GoASTCallExpr>(Expression())) {
197       return FinishStmt(new GoASTGoStmt(e));
198     }
199     m_last = "call expression";
200     m_failed = true;
201     return new GoASTBadStmt();
202   }
203   return nullptr;
204 }
205
206 GoASTStmt *GoParser::ReturnStmt() {
207   if (match(GoLexer::KEYWORD_RETURN)) {
208     std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt());
209     for (GoASTExpr *e = Expression(); e; e = MoreExpressionList())
210       r->AddResults(e);
211     return FinishStmt(r.release());
212   }
213   return nullptr;
214 }
215
216 GoASTStmt *GoParser::BranchStmt() {
217   GoLexer::Token *tok;
218   if ((tok = match(GoLexer::KEYWORD_BREAK)) ||
219       (tok = match(GoLexer::KEYWORD_CONTINUE)) ||
220       (tok = match(GoLexer::KEYWORD_GOTO))) {
221     auto *e = Identifier();
222     if (tok->m_type == GoLexer::KEYWORD_GOTO && !e)
223       return syntaxerror();
224     return FinishStmt(new GoASTBranchStmt(e, tok->m_type));
225   }
226   if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH)))
227     return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type));
228
229   return nullptr;
230 }
231
232 GoASTIdent *GoParser::Identifier() {
233   if (auto *tok = match(GoLexer::TOK_IDENTIFIER))
234     return new GoASTIdent(*tok);
235   return nullptr;
236 }
237
238 GoASTExpr *GoParser::MoreExpressionList() {
239   if (match(GoLexer::OP_COMMA)) {
240     auto *e = Expression();
241     if (!e)
242       return syntaxerror();
243     return e;
244   }
245   return nullptr;
246 }
247
248 GoASTIdent *GoParser::MoreIdentifierList() {
249   if (match(GoLexer::OP_COMMA)) {
250     auto *i = Identifier();
251     if (!i)
252       return syntaxerror();
253     return i;
254   }
255   return nullptr;
256 }
257
258 GoASTExpr *GoParser::Expression() {
259   Rule r("Expression", this);
260   if (GoASTExpr *ret = OrExpr())
261     return ret;
262   return r.error();
263 }
264
265 GoASTExpr *GoParser::UnaryExpr() {
266   switch (peek()) {
267   case GoLexer::OP_PLUS:
268   case GoLexer::OP_MINUS:
269   case GoLexer::OP_BANG:
270   case GoLexer::OP_CARET:
271   case GoLexer::OP_STAR:
272   case GoLexer::OP_AMP:
273   case GoLexer::OP_LT_MINUS: {
274     const GoLexer::Token t = next();
275     if (GoASTExpr *e = UnaryExpr()) {
276       if (t.m_type == GoLexer::OP_STAR)
277         return new GoASTStarExpr(e);
278       else
279         return new GoASTUnaryExpr(t.m_type, e);
280     }
281     return syntaxerror();
282   }
283   default:
284     return PrimaryExpr();
285   }
286 }
287
288 GoASTExpr *GoParser::OrExpr() {
289   std::unique_ptr<GoASTExpr> l(AndExpr());
290   if (l) {
291     while (match(GoLexer::OP_PIPE_PIPE)) {
292       GoASTExpr *r = AndExpr();
293       if (r)
294         l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE));
295       else
296         return syntaxerror();
297     }
298     return l.release();
299   }
300   return nullptr;
301 }
302
303 GoASTExpr *GoParser::AndExpr() {
304   std::unique_ptr<GoASTExpr> l(RelExpr());
305   if (l) {
306     while (match(GoLexer::OP_AMP_AMP)) {
307       GoASTExpr *r = RelExpr();
308       if (r)
309         l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP));
310       else
311         return syntaxerror();
312     }
313     return l.release();
314   }
315   return nullptr;
316 }
317
318 GoASTExpr *GoParser::RelExpr() {
319   std::unique_ptr<GoASTExpr> l(AddExpr());
320   if (l) {
321     for (GoLexer::Token *t;
322          (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) ||
323          (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) ||
324          (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) {
325       GoLexer::TokenType op = t->m_type;
326       GoASTExpr *r = AddExpr();
327       if (r)
328         l.reset(new GoASTBinaryExpr(l.release(), r, op));
329       else
330         return syntaxerror();
331     }
332     return l.release();
333   }
334   return nullptr;
335 }
336
337 GoASTExpr *GoParser::AddExpr() {
338   std::unique_ptr<GoASTExpr> l(MulExpr());
339   if (l) {
340     for (GoLexer::Token *t;
341          (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) ||
342          (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) {
343       GoLexer::TokenType op = t->m_type;
344       GoASTExpr *r = MulExpr();
345       if (r)
346         l.reset(new GoASTBinaryExpr(l.release(), r, op));
347       else
348         return syntaxerror();
349     }
350     return l.release();
351   }
352   return nullptr;
353 }
354
355 GoASTExpr *GoParser::MulExpr() {
356   std::unique_ptr<GoASTExpr> l(UnaryExpr());
357   if (l) {
358     for (GoLexer::Token *t;
359          (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) ||
360          (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) ||
361          (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) ||
362          (t = match(GoLexer::OP_AMP_CARET));) {
363       GoLexer::TokenType op = t->m_type;
364       GoASTExpr *r = UnaryExpr();
365       if (r)
366         l.reset(new GoASTBinaryExpr(l.release(), r, op));
367       else
368         return syntaxerror();
369     }
370     return l.release();
371   }
372   return nullptr;
373 }
374
375 GoASTExpr *GoParser::PrimaryExpr() {
376   GoASTExpr *l;
377   GoASTExpr *r;
378   (l = Conversion()) || (l = Operand());
379   if (!l)
380     return nullptr;
381   while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) ||
382          (r = Arguments(l))) {
383     l = r;
384   }
385   return l;
386 }
387
388 GoASTExpr *GoParser::Operand() {
389   GoLexer::Token *lit;
390   if ((lit = match(GoLexer::LIT_INTEGER)) ||
391       (lit = match(GoLexer::LIT_FLOAT)) ||
392       (lit = match(GoLexer::LIT_IMAGINARY)) ||
393       (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING)))
394     return new GoASTBasicLit(*lit);
395   if (match(GoLexer::OP_LPAREN)) {
396     GoASTExpr *e;
397     if (!((e = Expression()) && match(GoLexer::OP_RPAREN)))
398       return syntaxerror();
399     return e;
400   }
401   // MethodExpr should be handled by Selector
402   if (GoASTExpr *e = CompositeLit())
403     return e;
404   if (GoASTExpr *n = Name())
405     return n;
406   return FunctionLit();
407 }
408
409 GoASTExpr *GoParser::FunctionLit() {
410   if (!match(GoLexer::KEYWORD_FUNC))
411     return nullptr;
412   auto *sig = Signature();
413   if (!sig)
414     return syntaxerror();
415   auto *body = Block();
416   if (!body) {
417     delete sig;
418     return syntaxerror();
419   }
420   return new GoASTFuncLit(sig, body);
421 }
422
423 GoASTBlockStmt *GoParser::Block() {
424   if (!match(GoLexer::OP_LBRACE))
425     return nullptr;
426   std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt);
427   for (auto *s = Statement(); s; s = Statement())
428     block->AddList(s);
429   if (!match(GoLexer::OP_RBRACE))
430     return syntaxerror();
431   return block.release();
432 }
433
434 GoASTExpr *GoParser::CompositeLit() {
435   Rule r("CompositeLit", this);
436   GoASTExpr *type;
437   (type = StructType()) || (type = ArrayOrSliceType(true)) ||
438       (type = MapType()) || (type = Name());
439   if (!type)
440     return r.error();
441   GoASTCompositeLit *lit = LiteralValue();
442   if (!lit) {
443     delete type;
444     return r.error();
445   }
446   lit->SetType(type);
447   return lit;
448 }
449
450 GoASTCompositeLit *GoParser::LiteralValue() {
451   if (!match(GoLexer::OP_LBRACE))
452     return nullptr;
453   std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit);
454   for (GoASTExpr *e = Element(); e; e = Element()) {
455     lit->AddElts(e);
456     if (!match(GoLexer::OP_COMMA))
457       break;
458   }
459   if (!mustMatch(GoLexer::OP_RBRACE))
460     return nullptr;
461   return lit.release();
462 }
463
464 GoASTExpr *GoParser::Element() {
465   GoASTExpr *key;
466   if (!((key = Expression()) || (key = LiteralValue())))
467     return nullptr;
468   if (!match(GoLexer::OP_COLON))
469     return key;
470   GoASTExpr *value;
471   if ((value = Expression()) || (value = LiteralValue()))
472     return new GoASTKeyValueExpr(key, value);
473   delete key;
474   return syntaxerror();
475 }
476
477 GoASTExpr *GoParser::Selector(GoASTExpr *e) {
478   Rule r("Selector", this);
479   if (match(GoLexer::OP_DOT)) {
480     if (auto *name = Identifier())
481       return new GoASTSelectorExpr(e, name);
482   }
483   return r.error();
484 }
485
486 GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) {
487   Rule r("IndexOrSlice", this);
488   if (match(GoLexer::OP_LBRACK)) {
489     std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3;
490     bool slice = false;
491     if (match(GoLexer::OP_COLON)) {
492       slice = true;
493       i2.reset(Expression());
494       if (i2 && match(GoLexer::OP_COLON)) {
495         i3.reset(Expression());
496         if (!i3)
497           return syntaxerror();
498       }
499     }
500     if (!(slice || i1))
501       return syntaxerror();
502     if (!mustMatch(GoLexer::OP_RBRACK))
503       return nullptr;
504     if (slice) {
505       bool slice3 = i3.get();
506       return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(),
507                                 slice3);
508     }
509     return new GoASTIndexExpr(e, i1.release());
510   }
511   return r.error();
512 }
513
514 GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) {
515   Rule r("TypeAssertion", this);
516   if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) {
517     if (auto *t = Type()) {
518       if (!mustMatch(GoLexer::OP_RPAREN))
519         return nullptr;
520       return new GoASTTypeAssertExpr(e, t);
521     }
522     return syntaxerror();
523   }
524   return r.error();
525 }
526
527 GoASTExpr *GoParser::Arguments(GoASTExpr *e) {
528   if (match(GoLexer::OP_LPAREN)) {
529     std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false));
530     GoASTExpr *arg;
531     // ( ExpressionList | Type [ "," ExpressionList ] )
532     for ((arg = Expression()) || (arg = Type()); arg;
533          arg = MoreExpressionList()) {
534       call->AddArgs(arg);
535     }
536     if (match(GoLexer::OP_DOTS))
537       call->SetEllipsis(true);
538
539     // Eat trailing comma
540     match(GoLexer::OP_COMMA);
541
542     if (!mustMatch(GoLexer::OP_RPAREN))
543       return nullptr;
544     call->SetFun(e);
545     return call.release();
546   }
547   return nullptr;
548 }
549
550 GoASTExpr *GoParser::Conversion() {
551   Rule r("Conversion", this);
552   if (GoASTExpr *t = Type2()) {
553     std::unique_ptr<GoASTExpr> owner(t);
554     if (match(GoLexer::OP_LPAREN)) {
555       GoASTExpr *v = Expression();
556       if (!v)
557         return syntaxerror();
558       match(GoLexer::OP_COMMA);
559       if (!mustMatch(GoLexer::OP_RPAREN))
560         return r.error();
561       GoASTCallExpr *call = new GoASTCallExpr(false);
562       call->SetFun(t);
563       owner.release();
564       call->AddArgs(v);
565       return call;
566     }
567   }
568   return r.error();
569 }
570
571 GoASTExpr *GoParser::Type2() {
572   switch (peek()) {
573   case GoLexer::OP_LBRACK:
574     return ArrayOrSliceType(false);
575   case GoLexer::KEYWORD_STRUCT:
576     return StructType();
577   case GoLexer::KEYWORD_FUNC:
578     return FunctionType();
579   case GoLexer::KEYWORD_INTERFACE:
580     return InterfaceType();
581   case GoLexer::KEYWORD_MAP:
582     return MapType();
583   case GoLexer::KEYWORD_CHAN:
584     return ChanType2();
585   default:
586     return nullptr;
587   }
588 }
589
590 GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) {
591   Rule r("ArrayType", this);
592   if (match(GoLexer::OP_LBRACK)) {
593     std::unique_ptr<GoASTExpr> len;
594     if (allowEllipsis && match(GoLexer::OP_DOTS)) {
595       len.reset(new GoASTEllipsis(nullptr));
596     } else {
597       len.reset(Expression());
598     }
599
600     if (!match(GoLexer::OP_RBRACK))
601       return r.error();
602     GoASTExpr *elem = Type();
603     if (!elem)
604       return syntaxerror();
605     return new GoASTArrayType(len.release(), elem);
606   }
607   return r.error();
608 }
609
610 GoASTExpr *GoParser::StructType() {
611   if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE)))
612     return nullptr;
613   std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList);
614   while (auto *field = FieldDecl())
615     fields->AddList(field);
616   if (!mustMatch(GoLexer::OP_RBRACE))
617     return nullptr;
618   return new GoASTStructType(fields.release());
619 }
620
621 GoASTField *GoParser::FieldDecl() {
622   std::unique_ptr<GoASTField> f(new GoASTField);
623   GoASTExpr *t = FieldNamesAndType(f.get());
624   if (!t)
625     t = AnonymousFieldType();
626   if (!t)
627     return nullptr;
628
629   if (auto *tok = match(GoLexer::LIT_STRING))
630     f->SetTag(new GoASTBasicLit(*tok));
631   if (!Semicolon())
632     return syntaxerror();
633   return f.release();
634 }
635
636 GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) {
637   Rule r("FieldNames", this);
638   for (auto *id = Identifier(); id; id = MoreIdentifierList())
639     field->AddNames(id);
640   if (m_failed)
641     return nullptr;
642   GoASTExpr *t = Type();
643   if (t)
644     return t;
645   return r.error();
646 }
647
648 GoASTExpr *GoParser::AnonymousFieldType() {
649   bool pointer = match(GoLexer::OP_STAR);
650   GoASTExpr *t = Type();
651   if (!t)
652     return nullptr;
653   if (pointer)
654     return new GoASTStarExpr(t);
655   return t;
656 }
657
658 GoASTExpr *GoParser::FunctionType() {
659   if (!match(GoLexer::KEYWORD_FUNC))
660     return nullptr;
661   return Signature();
662 }
663
664 GoASTFuncType *GoParser::Signature() {
665   auto *params = Params();
666   if (!params)
667     return syntaxerror();
668   auto *result = Params();
669   if (!result) {
670     if (auto *t = Type()) {
671       result = new GoASTFieldList;
672       auto *f = new GoASTField;
673       f->SetType(t);
674       result->AddList(f);
675     }
676   }
677   return new GoASTFuncType(params, result);
678 }
679
680 GoASTFieldList *GoParser::Params() {
681   if (!match(GoLexer::OP_LPAREN))
682     return nullptr;
683   std::unique_ptr<GoASTFieldList> l(new GoASTFieldList);
684   while (GoASTField *p = ParamDecl()) {
685     l->AddList(p);
686     if (!match(GoLexer::OP_COMMA))
687       break;
688   }
689   if (!mustMatch(GoLexer::OP_RPAREN))
690     return nullptr;
691   return l.release();
692 }
693
694 GoASTField *GoParser::ParamDecl() {
695   std::unique_ptr<GoASTField> field(new GoASTField);
696   GoASTIdent *id = Identifier();
697   if (id) {
698     // Try `IdentifierList [ "..." ] Type`.
699     // If that fails, backtrack and try `[ "..." ] Type`.
700     Rule r("NamedParam", this);
701     for (; id; id = MoreIdentifierList())
702       field->AddNames(id);
703     GoASTExpr *t = ParamType();
704     if (t) {
705       field->SetType(t);
706       return field.release();
707     }
708     field.reset(new GoASTField);
709     r.error();
710   }
711   GoASTExpr *t = ParamType();
712   if (t) {
713     field->SetType(t);
714     return field.release();
715   }
716   return nullptr;
717 }
718
719 GoASTExpr *GoParser::ParamType() {
720   bool dots = match(GoLexer::OP_DOTS);
721   GoASTExpr *t = Type();
722   if (!dots)
723     return t;
724   if (!t)
725     return syntaxerror();
726   return new GoASTEllipsis(t);
727 }
728
729 GoASTExpr *GoParser::InterfaceType() {
730   if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE))
731     return nullptr;
732   std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList);
733   while (true) {
734     Rule r("MethodSpec", this);
735     // ( identifier Signature | TypeName ) ;
736     std::unique_ptr<GoASTIdent> id(Identifier());
737     if (!id)
738       break;
739     GoASTExpr *type = Signature();
740     if (!type) {
741       r.error();
742       id.reset();
743       type = Name();
744     }
745     if (!Semicolon())
746       return syntaxerror();
747     auto *f = new GoASTField;
748     if (id)
749       f->AddNames(id.release());
750     f->SetType(type);
751     methods->AddList(f);
752   }
753   if (!mustMatch(GoLexer::OP_RBRACE))
754     return nullptr;
755   return new GoASTInterfaceType(methods.release());
756 }
757
758 GoASTExpr *GoParser::MapType() {
759   if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK)))
760     return nullptr;
761   std::unique_ptr<GoASTExpr> key(Type());
762   if (!key)
763     return syntaxerror();
764   if (!mustMatch(GoLexer::OP_RBRACK))
765     return nullptr;
766   auto *elem = Type();
767   if (!elem)
768     return syntaxerror();
769   return new GoASTMapType(key.release(), elem);
770 }
771
772 GoASTExpr *GoParser::ChanType() {
773   Rule r("chan", this);
774   if (match(GoLexer::OP_LT_MINUS)) {
775     if (match(GoLexer::KEYWORD_CHAN)) {
776       auto *elem = Type();
777       if (!elem)
778         return syntaxerror();
779       return new GoASTChanType(GoASTNode::eChanRecv, elem);
780     }
781     return r.error();
782   }
783   return ChanType2();
784 }
785
786 GoASTExpr *GoParser::ChanType2() {
787   if (!match(GoLexer::KEYWORD_CHAN))
788     return nullptr;
789   auto dir = GoASTNode::eChanBidir;
790   if (match(GoLexer::OP_LT_MINUS))
791     dir = GoASTNode::eChanSend;
792   auto *elem = Type();
793   if (!elem)
794     return syntaxerror();
795   return new GoASTChanType(dir, elem);
796 }
797
798 GoASTExpr *GoParser::Type() {
799   if (GoASTExpr *t = Type2())
800     return t;
801   if (GoASTExpr *t = Name())
802     return t;
803   if (GoASTExpr *t = ChanType())
804     return t;
805   if (match(GoLexer::OP_STAR)) {
806     GoASTExpr *t = Type();
807     if (!t)
808       return syntaxerror();
809     return new GoASTStarExpr(t);
810   }
811   if (match(GoLexer::OP_LPAREN)) {
812     std::unique_ptr<GoASTExpr> t(Type());
813     if (!t || !match(GoLexer::OP_RPAREN))
814       return syntaxerror();
815     return t.release();
816   }
817   return nullptr;
818 }
819
820 bool GoParser::Semicolon() {
821   if (match(GoLexer::OP_SEMICOLON))
822     return true;
823   switch (peek()) {
824   case GoLexer::OP_RPAREN:
825   case GoLexer::OP_RBRACE:
826   case GoLexer::TOK_EOF:
827     return true;
828   default:
829     return false;
830   }
831 }
832
833 GoASTExpr *GoParser::Name() {
834   if (auto *id = Identifier()) {
835     if (GoASTExpr *qual = QualifiedIdent(id))
836       return qual;
837     return id;
838   }
839   return nullptr;
840 }
841
842 GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) {
843   Rule r("QualifiedIdent", this);
844   llvm::SmallString<32> path(p->GetName().m_value);
845   GoLexer::Token *next;
846   bool have_slashes = false;
847   // LLDB extension: support full/package/path.name
848   while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) {
849     have_slashes = true;
850     path.append("/");
851     path.append(next->m_value);
852   }
853   if (match(GoLexer::OP_DOT)) {
854     auto *name = Identifier();
855     if (name) {
856       if (have_slashes) {
857         p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path)));
858       }
859       return new GoASTSelectorExpr(p, name);
860     }
861   }
862   return r.error();
863 }
864
865 llvm::StringRef GoParser::CopyString(llvm::StringRef s) {
866   return m_strings.insert(std::make_pair(s, 'x')).first->getKey();
867 }
868
869 void GoParser::GetError(Status &error) {
870   llvm::StringRef want;
871   if (m_failed)
872     want =
873         m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last;
874   else
875     want = m_error;
876   size_t len = m_lexer.BytesRemaining();
877   if (len > 10)
878     len = 10;
879   llvm::StringRef got;
880   if (len == 0)
881     got = "<eof>";
882   else
883     got = m_lexer.GetString(len);
884   error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.",
885                                  want.str().c_str(), got.str().c_str());
886 }