blob: 3be0e5f506eea77976f00f7e4ec5e3a10a520f1f [file] [log] [blame]
import StringIO
def addNodes():
addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr")
addNode(
"AssignStmt",
"Stmt",
"lhs",
"[]Expr",
"rhs",
"[]Expr",
"define",
"bool")
addNode("BadDecl", "Decl")
addNode("BadExpr", "Expr")
addNode("BadStmt", "Stmt")
addNode("BasicLit", "Expr", "value", "Token")
addNode("BinaryExpr", "Expr", "x", "Expr", "y", "Expr", "op", "TokenType")
addNode("BlockStmt", "Stmt", "list", "[]Stmt")
addNode("Ident", "Expr", "name", "Token")
addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType")
addNode(
"CallExpr",
"Expr",
"fun",
"Expr",
"args",
"[]Expr",
"ellipsis",
"bool")
addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt")
addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr")
addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt")
addNode("CompositeLit", "Expr", "type", "Expr", "elts", "[]Expr")
addNode("DeclStmt", "Stmt", "decl", "Decl")
addNode("DeferStmt", "Stmt", "call", "CallExpr")
addNode("Ellipsis", "Expr", "elt", "Expr")
addNode("EmptyStmt", "Stmt")
addNode("ExprStmt", "Stmt", "x", "Expr")
addNode(
"Field",
"Node",
"names",
"[]Ident",
"type",
"Expr",
"tag",
"BasicLit")
addNode("FieldList", "Node", "list", "[]Field")
addNode(
"ForStmt",
"Stmt",
"init",
"Stmt",
"cond",
"Expr",
"post",
"Stmt",
"body",
"BlockStmt")
addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList")
addNode(
"FuncDecl",
"Decl",
"recv",
"FieldList",
"name",
"Ident",
"type",
"FuncType",
"body",
"BlockStmt")
addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt")
addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec")
addNode("GoStmt", "Stmt", "call", "CallExpr")
addNode(
"IfStmt",
"Stmt",
"init",
"Stmt",
"cond",
"Expr",
"body",
"BlockStmt",
"els",
"Stmt")
addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit")
addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType")
addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr")
addNode("InterfaceType", "Expr", "methods", "FieldList")
addNode("KeyValueExpr", "Expr", "key", "Expr", "value", "Expr")
addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt")
addNode("MapType", "Expr", "key", "Expr", "value", "Expr")
addNode("ParenExpr", "Expr", "x", "Expr")
addNode(
"RangeStmt",
"Stmt",
"key",
"Expr",
"value",
"Expr",
"define",
"bool",
"x",
"Expr",
"body",
"BlockStmt")
addNode("ReturnStmt", "Stmt", "results", "[]Expr")
addNode("SelectStmt", "Stmt", "body", "BlockStmt")
addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident")
addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr")
addNode(
"SliceExpr",
"Expr",
"x",
"Expr",
"low",
"Expr",
"high",
"Expr",
"max",
"Expr",
"slice3",
"bool")
addNode("StarExpr", "Expr", "x", "Expr")
addNode("StructType", "Expr", "fields", "FieldList")
addNode(
"SwitchStmt",
"Stmt",
"init",
"Stmt",
"tag",
"Expr",
"body",
"BlockStmt")
addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr")
addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr")
addNode(
"TypeSwitchStmt",
"Stmt",
"init",
"Stmt",
"assign",
"Stmt",
"body",
"BlockStmt")
addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr")
addNode(
"ValueSpec",
"Spec",
"names",
"[]Ident",
"type",
"Expr",
"values",
"[]Expr")
addParent("Decl", "Node")
addParent("Expr", "Node")
addParent("Spec", "Node")
addParent("Stmt", "Node")
class Member(object):
def __init__(self, name, typename):
self.title = name.title()
self.sname = name
self.mname = 'm_' + name
self.is_list = typename.startswith("[]")
self.is_value = isValueType(typename)
if self.is_value:
self.argtype = typename
self.mtype = typename
elif self.is_list:
self.argtype = 'GoAST' + typename[2:]
self.mtype = 'std::vector<std::unique_ptr<%s> >' % self.argtype
else:
self.argtype = 'GoAST' + typename
self.mtype = 'std::unique_ptr<%s>' % self.argtype
self.mname = self.mname + '_up'
kinds = {}
parentClasses = StringIO.StringIO()
childClasses = StringIO.StringIO()
walker = StringIO.StringIO()
def startClass(name, parent, out):
out.write("""
class GoAST%s : public GoAST%s
{
public:
""" % (name, parent))
def endClass(name, out):
out.write("""
%(name)s(const %(name)s &) = delete;
const %(name)s &operator=(const %(name)s &) = delete;
};
""" % {'name': 'GoAST' + name})
def addNode(name, parent, *children):
startClass(name, parent, childClasses)
l = kinds.setdefault(parent, [])
l.append(name)
children = createMembers(name, children)
addConstructor(name, parent, children)
childClasses.write("""
const char *
GetKindName() const override
{
return "%(name)s";
}
static bool
classof(const GoASTNode *n)
{
return n->GetKind() == e%(name)s;
}
""" % {'name': name})
addChildren(name, children)
endClass(name, childClasses)
def isValueType(typename):
if typename[0].islower():
return True
if typename[0].isupper():
return typename.startswith('Token') or typename == 'ChanDir'
return False
def createMembers(name, children):
l = len(children)
if (l % 2) != 0:
raise Exception("Invalid children for %s: %s" % (name, children))
return [Member(children[i], children[i + 1]) for i in xrange(0, l, 2)]
def addConstructor(name, parent, children):
for c in children:
if c.is_list:
children = [x for x in children if x.is_value]
break
childClasses.write(' ')
if len(children) == 1:
childClasses.write('explicit ')
childClasses.write('GoAST%s(' % name)
for i in xrange(len(children)):
if i > 0:
childClasses.write(', ')
c = children[i]
if c.is_value:
childClasses.write(c.argtype)
childClasses.write(' ')
else:
childClasses.write('%s *' % c.argtype)
childClasses.write(c.sname)
childClasses.write(') : GoAST%s(e%s)' % (parent, name))
for c in children:
childClasses.write(', ')
childClasses.write('%(mname)s(%(sname)s)' % c.__dict__)
childClasses.write(""" {}
~GoAST%s() override = default;
""" % name)
def addChildren(name, children):
if len(children) == 0:
return
walker.write("""
case e%(n)s:
{
GoAST%(n)s *n = llvm::cast<GoAST%(n)s>(this);
(void)n;""" % {'n': name})
for c in children:
if c.is_list:
childClasses.write("""
size_t
Num%(title)s() const
{
return %(mname)s.size();
}
const %(argtype)s *
Get%(title)s(int i) const
{
return %(mname)s[i].get();
}
void
Add%(title)s(%(argtype)s *%(sname)s)
{
%(mname)s.push_back(std::unique_ptr<%(argtype)s>(%(sname)s));
}
""" % c.__dict__)
walker.write("""
for (auto& e : n->%s) { v(e.get()); }""" % c.mname)
else:
const = ''
get = ''
set = ''
t = c.argtype
if isValueType(t):
set = '%(mname)s = %(sname)s' % c.__dict__
t = t + ' '
else:
t = t + ' *'
const = 'const '
get = '.get()'
set = '%(mname)s.reset(%(sname)s)' % c.__dict__
walker.write("""
v(n->%s.get());""" % c.mname)
childClasses.write("""
%(const)s%(type)s
Get%(title)s() const
{
return %(mname)s%(get)s;
}
void
Set%(title)s(%(type)s%(sname)s)
{
%(set)s;
}
""" % {'const': const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname})
childClasses.write('\n private:\n friend class GoASTNode;\n')
walker.write("""
return;
}""")
for c in children:
childClasses.write(' %s %s;\n' % (c.mtype, c.mname))
def addParent(name, parent):
startClass(name, parent, parentClasses)
l = kinds[name]
minName = l[0]
maxName = l[-1]
parentClasses.write(""" template <typename R, typename V> R Visit(V *v) const;
static bool
classof(const GoASTNode *n)
{
return n->GetKind() >= e%s && n->GetKind() <= e%s;
}
protected:
explicit GoAST%s(NodeKind kind) : GoASTNode(kind) { }
private:
""" % (minName, maxName, name))
endClass(name, parentClasses)
addNodes()
print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// DO NOT EDIT.
// Generated by gen_go_ast.py
#ifndef liblldb_GoAST_h
#define liblldb_GoAST_h
#include "lldb/lldb-forward.h"
#include "lldb/lldb-private.h"
#include "llvm/Support/Casting.h"
#include "Plugins/ExpressionParser/Go/GoLexer.h"
namespace lldb_private
{
class GoASTNode
{
public:
typedef GoLexer::TokenType TokenType;
typedef GoLexer::Token Token;
enum ChanDir
{
eChanBidir,
eChanSend,
eChanRecv,
};
enum NodeKind
{"""
for l in kinds.itervalues():
for x in l:
print " e%s," % x
print """ };
virtual ~GoASTNode() = default;
NodeKind
GetKind() const
{
return m_kind;
}
virtual const char *GetKindName() const = 0;
template <typename V> void WalkChildren(V &v);
protected:
explicit GoASTNode(NodeKind kind) : m_kind(kind) { }
private:
const NodeKind m_kind;
GoASTNode(const GoASTNode &) = delete;
const GoASTNode &operator=(const GoASTNode &) = delete;
};
"""
print parentClasses.getvalue()
print childClasses.getvalue()
for k, l in kinds.iteritems():
if k == 'Node':
continue
print """
template <typename R, typename V>
R GoAST%s::Visit(V* v) const
{
switch(GetKind())
{""" % k
for subtype in l:
print """ case e%(n)s:
return v->Visit%(n)s(llvm::cast<const GoAST%(n)s>(this));""" % {'n': subtype}
print """ default:
assert(false && "Invalid kind");
}
}"""
print """
template <typename V>
void GoASTNode::WalkChildren(V &v)
{
switch (m_kind)
{
"""
print walker.getvalue()
print"""
case eEmptyStmt:
case eBadDecl:
case eBadExpr:
case eBadStmt:
break;
}
}
} // namespace lldb_private
#endif
"""