diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2018-11-05 19:33:59 +0000 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2018-11-05 19:33:59 +0000 |
commit | 77198bc79b54267f2ce981c3a6c9c0d6384cac01 (patch) | |
tree | 1bd65fa94b3e566a6e17c315d11eb00ee0378794 /lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp | |
parent | 115209ece5c55dedf2ce4fb40beca79803c7676e (diff) | |
download | bcm5719-llvm-77198bc79b54267f2ce981c3a6c9c0d6384cac01.tar.gz bcm5719-llvm-77198bc79b54267f2ce981c3a6c9c0d6384cac01.zip |
Remove Go debugger plugin
In January Davide sent an e-mail to the mailing list to suggest removing
unmaintained language plugins such as Go and Java. The plan was to have
some cool down period to allow users to speak up, however after that the
plugins were never actually removed.
This patch removes the Go debugger plugin.
The plugin can be added again in the future if it is mature enough both
in terms of testing and maintenance commitment.
Discussion on the mailing list:
http://lists.llvm.org/pipermail/lldb-dev/2018-January/013171.html
Differential revision: https://reviews.llvm.org/D54057
llvm-svn: 346157
Diffstat (limited to 'lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp')
-rw-r--r-- | lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp | 886 |
1 files changed, 0 insertions, 886 deletions
diff --git a/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp b/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp deleted file mode 100644 index 9c845d02bca..00000000000 --- a/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp +++ /dev/null @@ -1,886 +0,0 @@ -//===-- GoParser.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include <vector> - -#include "GoParser.h" - -#include "Plugins/ExpressionParser/Go/GoAST.h" -#include "lldb/Utility/Status.h" -#include "llvm/ADT/SmallString.h" - -using namespace lldb_private; -using namespace lldb; - -namespace { -llvm::StringRef DescribeToken(GoLexer::TokenType t) { - switch (t) { - case GoLexer::TOK_EOF: - return "<eof>"; - case GoLexer::TOK_IDENTIFIER: - return "identifier"; - case GoLexer::LIT_FLOAT: - return "float"; - case GoLexer::LIT_IMAGINARY: - return "imaginary"; - case GoLexer::LIT_INTEGER: - return "integer"; - case GoLexer::LIT_RUNE: - return "rune"; - case GoLexer::LIT_STRING: - return "string"; - default: - return GoLexer::LookupToken(t); - } -} -} // namespace - -class GoParser::Rule { -public: - Rule(llvm::StringRef name, GoParser *p) - : m_name(name), m_parser(p), m_pos(p->m_pos) {} - - std::nullptr_t error() { - if (!m_parser->m_failed) { - // Set m_error in case this is the top level. - if (m_parser->m_last_tok == GoLexer::TOK_INVALID) - m_parser->m_error = m_parser->m_last; - else - m_parser->m_error = DescribeToken(m_parser->m_last_tok); - // And set m_last in case it isn't. - m_parser->m_last = m_name; - m_parser->m_last_tok = GoLexer::TOK_INVALID; - m_parser->m_pos = m_pos; - } - return nullptr; - } - -private: - llvm::StringRef m_name; - GoParser *m_parser; - size_t m_pos; -}; - -GoParser::GoParser(const char *src) - : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID), - m_failed(false) {} - -GoASTStmt *GoParser::Statement() { - Rule r("Statement", this); - GoLexer::TokenType t = peek(); - GoASTStmt *ret = nullptr; - switch (t) { - case GoLexer::TOK_EOF: - case GoLexer::OP_SEMICOLON: - case GoLexer::OP_RPAREN: - case GoLexer::OP_RBRACE: - case GoLexer::TOK_INVALID: - return EmptyStmt(); - case GoLexer::OP_LBRACE: - return Block(); - - /* TODO: -case GoLexer::KEYWORD_GO: - return GoStmt(); -case GoLexer::KEYWORD_RETURN: - return ReturnStmt(); -case GoLexer::KEYWORD_BREAK: -case GoLexer::KEYWORD_CONTINUE: -case GoLexer::KEYWORD_GOTO: -case GoLexer::KEYWORD_FALLTHROUGH: - return BranchStmt(); -case GoLexer::KEYWORD_IF: - return IfStmt(); -case GoLexer::KEYWORD_SWITCH: - return SwitchStmt(); -case GoLexer::KEYWORD_SELECT: - return SelectStmt(); -case GoLexer::KEYWORD_FOR: - return ForStmt(); -case GoLexer::KEYWORD_DEFER: - return DeferStmt(); -case GoLexer::KEYWORD_CONST: -case GoLexer::KEYWORD_TYPE: -case GoLexer::KEYWORD_VAR: - return DeclStmt(); -case GoLexer::TOK_IDENTIFIER: - if ((ret = LabeledStmt()) || - (ret = ShortVarDecl())) - { - return ret; - } -*/ - default: - break; - } - GoASTExpr *expr = Expression(); - if (expr == nullptr) - return r.error(); - if (/*(ret = SendStmt(expr)) ||*/ - (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) || - (ret = ExpressionStmt(expr))) { - return ret; - } - delete expr; - return r.error(); -} - -GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) { - if (Semicolon()) - return new GoASTExprStmt(e); - return nullptr; -} - -GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) { - Rule r("IncDecStmt", this); - if (match(GoLexer::OP_PLUS_PLUS)) - return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS) - : r.error(); - if (match(GoLexer::OP_MINUS_MINUS)) - return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS) - : r.error(); - return nullptr; -} - -GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) { - Rule r("Assignment", this); - std::vector<std::unique_ptr<GoASTExpr>> lhs; - for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList()) - lhs.push_back(std::unique_ptr<GoASTExpr>(l)); - switch (peek()) { - case GoLexer::OP_EQ: - case GoLexer::OP_PLUS_EQ: - case GoLexer::OP_MINUS_EQ: - case GoLexer::OP_PIPE_EQ: - case GoLexer::OP_CARET_EQ: - case GoLexer::OP_STAR_EQ: - case GoLexer::OP_SLASH_EQ: - case GoLexer::OP_PERCENT_EQ: - case GoLexer::OP_LSHIFT_EQ: - case GoLexer::OP_RSHIFT_EQ: - case GoLexer::OP_AMP_EQ: - case GoLexer::OP_AMP_CARET_EQ: - break; - default: - return r.error(); - } - // We don't want to own e until we know this is an assignment. - std::unique_ptr<GoASTAssignStmt> stmt(new GoASTAssignStmt(false)); - stmt->AddLhs(e); - for (auto &l : lhs) - stmt->AddLhs(l.release()); - for (GoASTExpr *r = Expression(); r; r = MoreExpressionList()) - stmt->AddRhs(r); - if (!Semicolon() || stmt->NumRhs() == 0) - return new GoASTBadStmt; - return stmt.release(); -} - -GoASTStmt *GoParser::EmptyStmt() { - if (match(GoLexer::TOK_EOF)) - return nullptr; - if (Semicolon()) - return new GoASTEmptyStmt; - return nullptr; -} - -GoASTStmt *GoParser::GoStmt() { - if (match(GoLexer::KEYWORD_GO)) { - if (GoASTCallExpr *e = - llvm::dyn_cast_or_null<GoASTCallExpr>(Expression())) { - return FinishStmt(new GoASTGoStmt(e)); - } - m_last = "call expression"; - m_failed = true; - return new GoASTBadStmt(); - } - return nullptr; -} - -GoASTStmt *GoParser::ReturnStmt() { - if (match(GoLexer::KEYWORD_RETURN)) { - std::unique_ptr<GoASTReturnStmt> r(new GoASTReturnStmt()); - for (GoASTExpr *e = Expression(); e; e = MoreExpressionList()) - r->AddResults(e); - return FinishStmt(r.release()); - } - return nullptr; -} - -GoASTStmt *GoParser::BranchStmt() { - GoLexer::Token *tok; - if ((tok = match(GoLexer::KEYWORD_BREAK)) || - (tok = match(GoLexer::KEYWORD_CONTINUE)) || - (tok = match(GoLexer::KEYWORD_GOTO))) { - auto *e = Identifier(); - if (tok->m_type == GoLexer::KEYWORD_GOTO && !e) - return syntaxerror(); - return FinishStmt(new GoASTBranchStmt(e, tok->m_type)); - } - if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH))) - return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type)); - - return nullptr; -} - -GoASTIdent *GoParser::Identifier() { - if (auto *tok = match(GoLexer::TOK_IDENTIFIER)) - return new GoASTIdent(*tok); - return nullptr; -} - -GoASTExpr *GoParser::MoreExpressionList() { - if (match(GoLexer::OP_COMMA)) { - auto *e = Expression(); - if (!e) - return syntaxerror(); - return e; - } - return nullptr; -} - -GoASTIdent *GoParser::MoreIdentifierList() { - if (match(GoLexer::OP_COMMA)) { - auto *i = Identifier(); - if (!i) - return syntaxerror(); - return i; - } - return nullptr; -} - -GoASTExpr *GoParser::Expression() { - Rule r("Expression", this); - if (GoASTExpr *ret = OrExpr()) - return ret; - return r.error(); -} - -GoASTExpr *GoParser::UnaryExpr() { - switch (peek()) { - case GoLexer::OP_PLUS: - case GoLexer::OP_MINUS: - case GoLexer::OP_BANG: - case GoLexer::OP_CARET: - case GoLexer::OP_STAR: - case GoLexer::OP_AMP: - case GoLexer::OP_LT_MINUS: { - const GoLexer::Token t = next(); - if (GoASTExpr *e = UnaryExpr()) { - if (t.m_type == GoLexer::OP_STAR) - return new GoASTStarExpr(e); - else - return new GoASTUnaryExpr(t.m_type, e); - } - return syntaxerror(); - } - default: - return PrimaryExpr(); - } -} - -GoASTExpr *GoParser::OrExpr() { - std::unique_ptr<GoASTExpr> l(AndExpr()); - if (l) { - while (match(GoLexer::OP_PIPE_PIPE)) { - GoASTExpr *r = AndExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::AndExpr() { - std::unique_ptr<GoASTExpr> l(RelExpr()); - if (l) { - while (match(GoLexer::OP_AMP_AMP)) { - GoASTExpr *r = RelExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::RelExpr() { - std::unique_ptr<GoASTExpr> l(AddExpr()); - if (l) { - for (GoLexer::Token *t; - (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) || - (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) || - (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) { - GoLexer::TokenType op = t->m_type; - GoASTExpr *r = AddExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, op)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::AddExpr() { - std::unique_ptr<GoASTExpr> l(MulExpr()); - if (l) { - for (GoLexer::Token *t; - (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) || - (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) { - GoLexer::TokenType op = t->m_type; - GoASTExpr *r = MulExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, op)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::MulExpr() { - std::unique_ptr<GoASTExpr> l(UnaryExpr()); - if (l) { - for (GoLexer::Token *t; - (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) || - (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) || - (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) || - (t = match(GoLexer::OP_AMP_CARET));) { - GoLexer::TokenType op = t->m_type; - GoASTExpr *r = UnaryExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, op)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::PrimaryExpr() { - GoASTExpr *l; - GoASTExpr *r; - (l = Conversion()) || (l = Operand()); - if (!l) - return nullptr; - while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) || - (r = Arguments(l))) { - l = r; - } - return l; -} - -GoASTExpr *GoParser::Operand() { - GoLexer::Token *lit; - if ((lit = match(GoLexer::LIT_INTEGER)) || - (lit = match(GoLexer::LIT_FLOAT)) || - (lit = match(GoLexer::LIT_IMAGINARY)) || - (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING))) - return new GoASTBasicLit(*lit); - if (match(GoLexer::OP_LPAREN)) { - GoASTExpr *e; - if (!((e = Expression()) && match(GoLexer::OP_RPAREN))) - return syntaxerror(); - return e; - } - // MethodExpr should be handled by Selector - if (GoASTExpr *e = CompositeLit()) - return e; - if (GoASTExpr *n = Name()) - return n; - return FunctionLit(); -} - -GoASTExpr *GoParser::FunctionLit() { - if (!match(GoLexer::KEYWORD_FUNC)) - return nullptr; - auto *sig = Signature(); - if (!sig) - return syntaxerror(); - auto *body = Block(); - if (!body) { - delete sig; - return syntaxerror(); - } - return new GoASTFuncLit(sig, body); -} - -GoASTBlockStmt *GoParser::Block() { - if (!match(GoLexer::OP_LBRACE)) - return nullptr; - std::unique_ptr<GoASTBlockStmt> block(new GoASTBlockStmt); - for (auto *s = Statement(); s; s = Statement()) - block->AddList(s); - if (!match(GoLexer::OP_RBRACE)) - return syntaxerror(); - return block.release(); -} - -GoASTExpr *GoParser::CompositeLit() { - Rule r("CompositeLit", this); - GoASTExpr *type; - (type = StructType()) || (type = ArrayOrSliceType(true)) || - (type = MapType()) || (type = Name()); - if (!type) - return r.error(); - GoASTCompositeLit *lit = LiteralValue(); - if (!lit) { - delete type; - return r.error(); - } - lit->SetType(type); - return lit; -} - -GoASTCompositeLit *GoParser::LiteralValue() { - if (!match(GoLexer::OP_LBRACE)) - return nullptr; - std::unique_ptr<GoASTCompositeLit> lit(new GoASTCompositeLit); - for (GoASTExpr *e = Element(); e; e = Element()) { - lit->AddElts(e); - if (!match(GoLexer::OP_COMMA)) - break; - } - if (!mustMatch(GoLexer::OP_RBRACE)) - return nullptr; - return lit.release(); -} - -GoASTExpr *GoParser::Element() { - GoASTExpr *key; - if (!((key = Expression()) || (key = LiteralValue()))) - return nullptr; - if (!match(GoLexer::OP_COLON)) - return key; - GoASTExpr *value; - if ((value = Expression()) || (value = LiteralValue())) - return new GoASTKeyValueExpr(key, value); - delete key; - return syntaxerror(); -} - -GoASTExpr *GoParser::Selector(GoASTExpr *e) { - Rule r("Selector", this); - if (match(GoLexer::OP_DOT)) { - if (auto *name = Identifier()) - return new GoASTSelectorExpr(e, name); - } - return r.error(); -} - -GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) { - Rule r("IndexOrSlice", this); - if (match(GoLexer::OP_LBRACK)) { - std::unique_ptr<GoASTExpr> i1(Expression()), i2, i3; - bool slice = false; - if (match(GoLexer::OP_COLON)) { - slice = true; - i2.reset(Expression()); - if (i2 && match(GoLexer::OP_COLON)) { - i3.reset(Expression()); - if (!i3) - return syntaxerror(); - } - } - if (!(slice || i1)) - return syntaxerror(); - if (!mustMatch(GoLexer::OP_RBRACK)) - return nullptr; - if (slice) { - bool slice3 = i3.get(); - return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(), - slice3); - } - return new GoASTIndexExpr(e, i1.release()); - } - return r.error(); -} - -GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) { - Rule r("TypeAssertion", this); - if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) { - if (auto *t = Type()) { - if (!mustMatch(GoLexer::OP_RPAREN)) - return nullptr; - return new GoASTTypeAssertExpr(e, t); - } - return syntaxerror(); - } - return r.error(); -} - -GoASTExpr *GoParser::Arguments(GoASTExpr *e) { - if (match(GoLexer::OP_LPAREN)) { - std::unique_ptr<GoASTCallExpr> call(new GoASTCallExpr(false)); - GoASTExpr *arg; - // ( ExpressionList | Type [ "," ExpressionList ] ) - for ((arg = Expression()) || (arg = Type()); arg; - arg = MoreExpressionList()) { - call->AddArgs(arg); - } - if (match(GoLexer::OP_DOTS)) - call->SetEllipsis(true); - - // Eat trailing comma - match(GoLexer::OP_COMMA); - - if (!mustMatch(GoLexer::OP_RPAREN)) - return nullptr; - call->SetFun(e); - return call.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::Conversion() { - Rule r("Conversion", this); - if (GoASTExpr *t = Type2()) { - std::unique_ptr<GoASTExpr> owner(t); - if (match(GoLexer::OP_LPAREN)) { - GoASTExpr *v = Expression(); - if (!v) - return syntaxerror(); - match(GoLexer::OP_COMMA); - if (!mustMatch(GoLexer::OP_RPAREN)) - return r.error(); - GoASTCallExpr *call = new GoASTCallExpr(false); - call->SetFun(t); - owner.release(); - call->AddArgs(v); - return call; - } - } - return r.error(); -} - -GoASTExpr *GoParser::Type2() { - switch (peek()) { - case GoLexer::OP_LBRACK: - return ArrayOrSliceType(false); - case GoLexer::KEYWORD_STRUCT: - return StructType(); - case GoLexer::KEYWORD_FUNC: - return FunctionType(); - case GoLexer::KEYWORD_INTERFACE: - return InterfaceType(); - case GoLexer::KEYWORD_MAP: - return MapType(); - case GoLexer::KEYWORD_CHAN: - return ChanType2(); - default: - return nullptr; - } -} - -GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) { - Rule r("ArrayType", this); - if (match(GoLexer::OP_LBRACK)) { - std::unique_ptr<GoASTExpr> len; - if (allowEllipsis && match(GoLexer::OP_DOTS)) { - len.reset(new GoASTEllipsis(nullptr)); - } else { - len.reset(Expression()); - } - - if (!match(GoLexer::OP_RBRACK)) - return r.error(); - GoASTExpr *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTArrayType(len.release(), elem); - } - return r.error(); -} - -GoASTExpr *GoParser::StructType() { - if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE))) - return nullptr; - std::unique_ptr<GoASTFieldList> fields(new GoASTFieldList); - while (auto *field = FieldDecl()) - fields->AddList(field); - if (!mustMatch(GoLexer::OP_RBRACE)) - return nullptr; - return new GoASTStructType(fields.release()); -} - -GoASTField *GoParser::FieldDecl() { - std::unique_ptr<GoASTField> f(new GoASTField); - GoASTExpr *t = FieldNamesAndType(f.get()); - if (!t) - t = AnonymousFieldType(); - if (!t) - return nullptr; - - if (auto *tok = match(GoLexer::LIT_STRING)) - f->SetTag(new GoASTBasicLit(*tok)); - if (!Semicolon()) - return syntaxerror(); - return f.release(); -} - -GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) { - Rule r("FieldNames", this); - for (auto *id = Identifier(); id; id = MoreIdentifierList()) - field->AddNames(id); - if (m_failed) - return nullptr; - GoASTExpr *t = Type(); - if (t) - return t; - return r.error(); -} - -GoASTExpr *GoParser::AnonymousFieldType() { - bool pointer = match(GoLexer::OP_STAR); - GoASTExpr *t = Type(); - if (!t) - return nullptr; - if (pointer) - return new GoASTStarExpr(t); - return t; -} - -GoASTExpr *GoParser::FunctionType() { - if (!match(GoLexer::KEYWORD_FUNC)) - return nullptr; - return Signature(); -} - -GoASTFuncType *GoParser::Signature() { - auto *params = Params(); - if (!params) - return syntaxerror(); - auto *result = Params(); - if (!result) { - if (auto *t = Type()) { - result = new GoASTFieldList; - auto *f = new GoASTField; - f->SetType(t); - result->AddList(f); - } - } - return new GoASTFuncType(params, result); -} - -GoASTFieldList *GoParser::Params() { - if (!match(GoLexer::OP_LPAREN)) - return nullptr; - std::unique_ptr<GoASTFieldList> l(new GoASTFieldList); - while (GoASTField *p = ParamDecl()) { - l->AddList(p); - if (!match(GoLexer::OP_COMMA)) - break; - } - if (!mustMatch(GoLexer::OP_RPAREN)) - return nullptr; - return l.release(); -} - -GoASTField *GoParser::ParamDecl() { - std::unique_ptr<GoASTField> field(new GoASTField); - GoASTIdent *id = Identifier(); - if (id) { - // Try `IdentifierList [ "..." ] Type`. - // If that fails, backtrack and try `[ "..." ] Type`. - Rule r("NamedParam", this); - for (; id; id = MoreIdentifierList()) - field->AddNames(id); - GoASTExpr *t = ParamType(); - if (t) { - field->SetType(t); - return field.release(); - } - field.reset(new GoASTField); - r.error(); - } - GoASTExpr *t = ParamType(); - if (t) { - field->SetType(t); - return field.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::ParamType() { - bool dots = match(GoLexer::OP_DOTS); - GoASTExpr *t = Type(); - if (!dots) - return t; - if (!t) - return syntaxerror(); - return new GoASTEllipsis(t); -} - -GoASTExpr *GoParser::InterfaceType() { - if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE)) - return nullptr; - std::unique_ptr<GoASTFieldList> methods(new GoASTFieldList); - while (true) { - Rule r("MethodSpec", this); - // ( identifier Signature | TypeName ) ; - std::unique_ptr<GoASTIdent> id(Identifier()); - if (!id) - break; - GoASTExpr *type = Signature(); - if (!type) { - r.error(); - id.reset(); - type = Name(); - } - if (!Semicolon()) - return syntaxerror(); - auto *f = new GoASTField; - if (id) - f->AddNames(id.release()); - f->SetType(type); - methods->AddList(f); - } - if (!mustMatch(GoLexer::OP_RBRACE)) - return nullptr; - return new GoASTInterfaceType(methods.release()); -} - -GoASTExpr *GoParser::MapType() { - if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK))) - return nullptr; - std::unique_ptr<GoASTExpr> key(Type()); - if (!key) - return syntaxerror(); - if (!mustMatch(GoLexer::OP_RBRACK)) - return nullptr; - auto *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTMapType(key.release(), elem); -} - -GoASTExpr *GoParser::ChanType() { - Rule r("chan", this); - if (match(GoLexer::OP_LT_MINUS)) { - if (match(GoLexer::KEYWORD_CHAN)) { - auto *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTChanType(GoASTNode::eChanRecv, elem); - } - return r.error(); - } - return ChanType2(); -} - -GoASTExpr *GoParser::ChanType2() { - if (!match(GoLexer::KEYWORD_CHAN)) - return nullptr; - auto dir = GoASTNode::eChanBidir; - if (match(GoLexer::OP_LT_MINUS)) - dir = GoASTNode::eChanSend; - auto *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTChanType(dir, elem); -} - -GoASTExpr *GoParser::Type() { - if (GoASTExpr *t = Type2()) - return t; - if (GoASTExpr *t = Name()) - return t; - if (GoASTExpr *t = ChanType()) - return t; - if (match(GoLexer::OP_STAR)) { - GoASTExpr *t = Type(); - if (!t) - return syntaxerror(); - return new GoASTStarExpr(t); - } - if (match(GoLexer::OP_LPAREN)) { - std::unique_ptr<GoASTExpr> t(Type()); - if (!t || !match(GoLexer::OP_RPAREN)) - return syntaxerror(); - return t.release(); - } - return nullptr; -} - -bool GoParser::Semicolon() { - if (match(GoLexer::OP_SEMICOLON)) - return true; - switch (peek()) { - case GoLexer::OP_RPAREN: - case GoLexer::OP_RBRACE: - case GoLexer::TOK_EOF: - return true; - default: - return false; - } -} - -GoASTExpr *GoParser::Name() { - if (auto *id = Identifier()) { - if (GoASTExpr *qual = QualifiedIdent(id)) - return qual; - return id; - } - return nullptr; -} - -GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) { - Rule r("QualifiedIdent", this); - llvm::SmallString<32> path(p->GetName().m_value); - GoLexer::Token *next; - bool have_slashes = false; - // LLDB extension: support full/package/path.name - while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) { - have_slashes = true; - path.append("/"); - path.append(next->m_value); - } - if (match(GoLexer::OP_DOT)) { - auto *name = Identifier(); - if (name) { - if (have_slashes) { - p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path))); - } - return new GoASTSelectorExpr(p, name); - } - } - return r.error(); -} - -llvm::StringRef GoParser::CopyString(llvm::StringRef s) { - return m_strings.insert(std::make_pair(s, 'x')).first->getKey(); -} - -void GoParser::GetError(Status &error) { - llvm::StringRef want; - if (m_failed) - want = - m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last; - else - want = m_error; - size_t len = m_lexer.BytesRemaining(); - if (len > 10) - len = 10; - llvm::StringRef got; - if (len == 0) - got = "<eof>"; - else - got = m_lexer.GetString(len); - error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.", - want.str().c_str(), got.str().c_str()); -} |