Bug Summary

File:tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp
Location:line 654, column 12
Description:Potential leak of memory pointed to by 't'

Annotated Source Code

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