blob: 5844911bc6aeb63619750e5f0cadbcce6df0c6e4 [file] [log] [blame]
/**
* Documentation: https://dlang.org/phobos/dmd_transitivevisitor.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/transitivevisitor.d
*/
module dmd.transitivevisitor;
import dmd.astenums;
import dmd.permissivevisitor;
import dmd.tokens;
import dmd.root.rootobject;
import core.stdc.stdio;
/** Visitor that implements the AST traversal logic. The nodes just accept their children.
*/
extern(C++) class ParseTimeTransitiveVisitor(AST) : PermissiveVisitor!AST
{
alias visit = PermissiveVisitor!AST.visit;
mixin ParseVisitMethods!AST __methods;
alias visit = __methods.visit;
}
/* This mixin implements the AST traversal logic for parse time AST nodes. The same code
* is used for semantic time AST node traversal, so in order to not duplicate the code,
* the template mixin is used.
*/
package mixin template ParseVisitMethods(AST)
{
import dmd.root.array;
// Statement Nodes
//===========================================================
override void visit(AST.ExpStatement s)
{
//printf("Visiting ExpStatement\n");
if (s.exp)
{
if (auto de = s.exp.isDeclarationExp())
de.declaration.accept(this);
else
s.exp.accept(this);
}
}
override void visit(AST.CompileStatement s)
{
//printf("Visiting CompileStatement\n");
visitArgs(s.exps.peekSlice());
}
override void visit(AST.CompoundStatement s)
{
//printf("Visiting CompoundStatement\n");
foreach (sx; *s.statements)
{
if (sx)
sx.accept(this);
}
}
void visitVarDecl(AST.VarDeclaration v)
{
//printf("Visiting VarDeclaration\n");
if (v.type)
visitType(v.type);
if (v._init)
{
if (auto ie = v._init.isExpInitializer())
{
if (auto ce = ie.exp.isConstructExp())
ce.e2.accept(this);
else if (auto be = ie.exp.isBlitExp())
be.e2.accept(this);
else
v._init.accept(this);
}
else
v._init.accept(this);
}
}
override void visit(AST.CompoundDeclarationStatement s)
{
//printf("Visiting CompoundDeclarationStatement\n");
foreach (sx; *s.statements)
{
if (!sx)
continue;
if (auto ds = sx.isExpStatement())
{
if (auto de = ds.exp.isDeclarationExp())
{
auto d = de.declaration;
assert(d.isDeclaration());
if (auto v = d.isVarDeclaration())
visitVarDecl(v);
else
d.accept(this);
}
}
}
}
override void visit(AST.ScopeStatement s)
{
//printf("Visiting ScopeStatement\n");
if (s.statement)
s.statement.accept(this);
}
override void visit(AST.WhileStatement s)
{
//printf("Visiting WhileStatement\n");
s.condition.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.DoStatement s)
{
//printf("Visiting DoStatement\n");
if (s._body)
s._body.accept(this);
s.condition.accept(this);
}
override void visit(AST.ForStatement s)
{
//printf("Visiting ForStatement\n");
if (s._init)
s._init.accept(this);
if (s.condition)
s.condition.accept(this);
if (s.increment)
s.increment.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.ForeachStatement s)
{
//printf("Visiting ForeachStatement\n");
foreach (p; *s.parameters)
if (p.type)
visitType(p.type);
s.aggr.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.ForeachRangeStatement s)
{
//printf("Visiting ForeachRangeStatement\n");
if (s.prm.type)
visitType(s.prm.type);
s.lwr.accept(this);
s.upr.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.IfStatement s)
{
//printf("Visiting IfStatement\n");
if (s.prm && s.prm.type)
visitType(s.prm.type);
s.condition.accept(this);
s.ifbody.accept(this);
if (s.elsebody)
s.elsebody.accept(this);
}
override void visit(AST.ConditionalStatement s)
{
//printf("Visiting ConditionalStatement\n");
s.condition.accept(this);
if (s.ifbody)
s.ifbody.accept(this);
if (s.elsebody)
s.elsebody.accept(this);
}
private extern(D) void visitArgs(AST.Expression[] expressions, AST.Expression basis = null)
{
foreach (el; expressions)
{
if (!el)
el = basis;
if (el)
el.accept(this);
}
}
override void visit(AST.PragmaStatement s)
{
//printf("Visiting PragmaStatement\n");
visitArgs(s.args.peekSlice());
if (s._body)
s._body.accept(this);
}
override void visit(AST.StaticAssertStatement s)
{
//printf("Visiting StaticAssertStatement\n");
s.sa.accept(this);
}
override void visit(AST.SwitchStatement s)
{
//printf("Visiting SwitchStatement\n");
s.condition.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.CaseStatement s)
{
//printf("Visiting CaseStatement\n");
s.exp.accept(this);
s.statement.accept(this);
}
override void visit(AST.CaseRangeStatement s)
{
//printf("Visiting CaseRangeStatement\n");
s.first.accept(this);
s.last.accept(this);
s.statement.accept(this);
}
override void visit(AST.DefaultStatement s)
{
//printf("Visiting DefaultStatement\n");
s.statement.accept(this);
}
override void visit(AST.GotoCaseStatement s)
{
//printf("Visiting GotoCaseStatement\n");
if (s.exp)
s.exp.accept(this);
}
override void visit(AST.ReturnStatement s)
{
//printf("Visiting ReturnStatement\n");
if (s.exp)
s.exp.accept(this);
}
override void visit(AST.SynchronizedStatement s)
{
//printf("Visiting SynchronizedStatement\n");
if (s.exp)
s.exp.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.WithStatement s)
{
//printf("Visiting WithStatement\n");
s.exp.accept(this);
if (s._body)
s._body.accept(this);
}
override void visit(AST.TryCatchStatement s)
{
//printf("Visiting TryCatchStatement\n");
if (s._body)
s._body.accept(this);
foreach (c; *s.catches)
visit(c);
}
override void visit(AST.TryFinallyStatement s)
{
//printf("Visiting TryFinallyStatement\n");
s._body.accept(this);
s.finalbody.accept(this);
}
override void visit(AST.ScopeGuardStatement s)
{
//printf("Visiting ScopeGuardStatement\n");
s.statement.accept(this);
}
override void visit(AST.ThrowStatement s)
{
//printf("Visiting ThrowStatement\n");
s.exp.accept(this);
}
override void visit(AST.LabelStatement s)
{
//printf("Visiting LabelStatement\n");
if (s.statement)
s.statement.accept(this);
}
override void visit(AST.ImportStatement s)
{
//printf("Visiting ImportStatement\n");
foreach (imp; *s.imports)
imp.accept(this);
}
void visit(AST.Catch c)
{
//printf("Visiting Catch\n");
if (c.type)
visitType(c.type);
if (c.handler)
c.handler.accept(this);
}
// Type Nodes
//============================================================
void visitType(AST.Type t)
{
//printf("Visiting Type\n");
if (!t)
return;
if (auto tf = t.isTypeFunction())
{
visitFunctionType(tf, null);
return;
}
else
t.accept(this);
}
void visitFunctionType(AST.TypeFunction t, AST.TemplateDeclaration td)
{
if (t.next)
visitType(t.next);
if (td)
{
foreach (p; *td.origParameters)
p.accept(this);
}
visitParameters(t.parameterList.parameters.peekSlice());
}
private extern(D) final void visitParameters(AST.Parameter[] parameters)
{
foreach (i; 0 .. parameters.length)
{
parameters[i].accept(this);
}
}
override void visit(AST.TypeVector t)
{
//printf("Visiting TypeVector\n");
if (!t.basetype)
return;
t.basetype.accept(this);
}
override void visit(AST.TypeSArray t)
{
//printf("Visiting TypeSArray\n");
t.next.accept(this);
}
override void visit(AST.TypeDArray t)
{
//printf("Visiting TypeDArray\n");
t.next.accept(this);
}
override void visit(AST.TypeAArray t)
{
//printf("Visiting TypeAArray\n");
t.next.accept(this);
t.index.accept(this);
}
override void visit(AST.TypePointer t)
{
//printf("Visiting TypePointer\n");
if (auto tf = t.next.isTypeFunction())
{
visitFunctionType(tf, null);
}
else
t.next.accept(this);
}
override void visit(AST.TypeReference t)
{
//printf("Visiting TypeReference\n");
t.next.accept(this);
}
override void visit(AST.TypeFunction t)
{
//printf("Visiting TypeFunction\n");
visitFunctionType(t, null);
}
override void visit(AST.TypeDelegate t)
{
//printf("Visiting TypeDelegate\n");
visitFunctionType(t.next.isTypeFunction(), null);
}
void visitTypeQualified(AST.TypeQualified t)
{
//printf("Visiting TypeQualified\n");
foreach (id; t.idents)
{
switch(id.dyncast()) with(DYNCAST)
{
case dsymbol:
(cast(AST.TemplateInstance)id).accept(this);
break;
case expression:
(cast(AST.Expression)id).accept(this);
break;
case type:
(cast(AST.Type)id).accept(this);
break;
default:
break;
}
}
}
override void visit(AST.TypeIdentifier t)
{
//printf("Visiting TypeIdentifier\n");
visitTypeQualified(t);
}
override void visit(AST.TypeInstance t)
{
//printf("Visiting TypeInstance\n");
t.tempinst.accept(this);
visitTypeQualified(t);
}
override void visit(AST.TypeTypeof t)
{
//printf("Visiting TypeTypeof\n");
t.exp.accept(this);
visitTypeQualified(t);
}
override void visit(AST.TypeReturn t)
{
//printf("Visiting TypeReturn\n");
visitTypeQualified(t);
}
override void visit(AST.TypeTuple t)
{
//printf("Visiting TypeTuple\n");
visitParameters(t.arguments.peekSlice());
}
override void visit(AST.TypeSlice t)
{
//printf("Visiting TypeSlice\n");
t.next.accept(this);
t.lwr.accept(this);
t.upr.accept(this);
}
override void visit(AST.TypeTraits t)
{
t.exp.accept(this);
}
override void visit(AST.TypeMixin t)
{
visitArgs(t.exps.peekSlice());
}
// Miscellaneous
//========================================================
override void visit(AST.StaticAssert s)
{
//printf("Visiting StaticAssert\n");
s.exp.accept(this);
if (s.msgs)
foreach (m; (*s.msgs)[])
m.accept(this);
}
override void visit(AST.EnumMember em)
{
//printf("Visiting EnumMember\n");
if (em.type)
visitType(em.type);
if (em.value)
em.value.accept(this);
}
// Declarations
//=========================================================
void visitAttribDeclaration(AST.AttribDeclaration d)
{
if (d.decl)
foreach (de; *d.decl)
de.accept(this);
}
override void visit(AST.AttribDeclaration d)
{
//printf("Visiting AttribDeclaration\n");
visitAttribDeclaration(d);
}
override void visit(AST.StorageClassDeclaration d)
{
//printf("Visiting StorageClassDeclaration\n");
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.DeprecatedDeclaration d)
{
//printf("Visiting DeprecatedDeclaration\n");
d.msg.accept(this);
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.LinkDeclaration d)
{
//printf("Visiting LinkDeclaration\n");
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.CPPMangleDeclaration d)
{
//printf("Visiting CPPMangleDeclaration\n");
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.VisibilityDeclaration d)
{
//printf("Visiting VisibilityDeclaration\n");
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.AlignDeclaration d)
{
//printf("Visiting AlignDeclaration\n");
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.AnonDeclaration d)
{
//printf("Visiting AnonDeclaration\n");
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.PragmaDeclaration d)
{
//printf("Visiting PragmaDeclaration\n");
visitArgs(d.args.peekSlice());
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
override void visit(AST.ConditionalDeclaration d)
{
//printf("Visiting ConditionalDeclaration\n");
d.condition.accept(this);
foreach (de; d.decl.peekSlice())
de.accept(this);
foreach (de; d.elsedecl.peekSlice())
de.accept(this);
}
override void visit(AST.CompileDeclaration d)
{
//printf("Visiting compileDeclaration\n");
visitArgs(d.exps.peekSlice());
}
override void visit(AST.UserAttributeDeclaration d)
{
//printf("Visiting UserAttributeDeclaration\n");
visitArgs(d.atts.peekSlice());
visitAttribDeclaration(cast(AST.AttribDeclaration)d);
}
void visitFuncBody(AST.FuncDeclaration f)
{
//printf("Visiting funcBody\n");
if (f.frequires)
{
foreach (frequire; *f.frequires)
{
frequire.accept(this);
}
}
if (f.fensures)
{
foreach (fensure; *f.fensures)
{
fensure.ensure.accept(this);
}
}
if (f.fbody)
{
f.fbody.accept(this);
}
}
void visitBaseClasses(AST.ClassDeclaration d)
{
//printf("Visiting ClassDeclaration\n");
if (!d || !d.baseclasses.length)
return;
foreach (b; *d.baseclasses)
visitType(b.type);
}
bool visitEponymousMember(AST.TemplateDeclaration d)
{
//printf("Visiting EponymousMember\n");
if (!d.members || d.members.length != 1)
return false;
AST.Dsymbol onemember = (*d.members)[0];
if (onemember.ident != d.ident)
return false;
if (AST.FuncDeclaration fd = onemember.isFuncDeclaration())
{
assert(fd.type);
visitFunctionType(fd.type.isTypeFunction(), d);
if (d.constraint)
d.constraint.accept(this);
visitFuncBody(fd);
return true;
}
if (AST.AggregateDeclaration ad = onemember.isAggregateDeclaration())
{
visitTemplateParameters(d.parameters);
if (d.constraint)
d.constraint.accept(this);
visitBaseClasses(ad.isClassDeclaration());
if (ad.members)
foreach (s; *ad.members)
s.accept(this);
return true;
}
if (AST.VarDeclaration vd = onemember.isVarDeclaration())
{
if (d.constraint)
return false;
if (vd.type)
visitType(vd.type);
visitTemplateParameters(d.parameters);
if (vd._init)
{
// note similarity of this code with visitVarDecl()
if (auto ie = vd._init.isExpInitializer())
{
if (auto ce = ie.exp.isConstructExp())
ce.e2.accept(this);
else if (auto be = ie.exp.isBlitExp())
be.e2.accept(this);
else
vd._init.accept(this);
}
else
vd._init.accept(this);
return true;
}
}
return false;
}
void visitTemplateParameters(AST.TemplateParameters* parameters)
{
if (!parameters || !parameters.length)
return;
foreach (p; *parameters)
p.accept(this);
}
override void visit(AST.TemplateDeclaration d)
{
//printf("Visiting TemplateDeclaration\n");
if (visitEponymousMember(d))
return;
visitTemplateParameters(d.parameters);
if (d.constraint)
d.constraint.accept(this);
foreach (s; *d.members)
s.accept(this);
}
void visitObject(RootObject oarg)
{
if (auto t = AST.isType(oarg))
{
visitType(t);
}
else if (auto e = AST.isExpression(oarg))
{
e.accept(this);
}
else if (auto v = AST.isTuple(oarg))
{
auto args = &v.objects;
foreach (arg; *args)
visitObject(arg);
}
}
void visitTiargs(AST.TemplateInstance ti)
{
//printf("Visiting tiargs\n");
if (!ti.tiargs)
return;
foreach (arg; *ti.tiargs)
{
visitObject(arg);
}
}
override void visit(AST.TemplateInstance ti)
{
//printf("Visiting TemplateInstance\n");
visitTiargs(ti);
}
override void visit(AST.TemplateMixin tm)
{
//printf("Visiting TemplateMixin\n");
visitType(tm.tqual);
visitTiargs(tm);
}
override void visit(AST.EnumDeclaration d)
{
//printf("Visiting EnumDeclaration\n");
if (d.memtype)
visitType(d.memtype);
if (!d.members)
return;
foreach (em; *d.members)
{
if (!em)
continue;
em.accept(this);
}
}
override void visit(AST.Nspace d)
{
//printf("Visiting Nspace\n");
foreach(s; *d.members)
s.accept(this);
}
override void visit(AST.StructDeclaration d)
{
//printf("Visiting StructDeclaration\n");
if (!d.members)
return;
foreach (s; *d.members)
s.accept(this);
}
override void visit(AST.UnionDeclaration d)
{
//printf("Visiting UnionDeclaration\n");
if (!d.members)
return;
foreach (s; *d.members)
s.accept(this);
}
override void visit(AST.ClassDeclaration d)
{
//printf("Visiting ClassDeclaration\n");
visitBaseClasses(d);
if (d.members)
foreach (s; *d.members)
s.accept(this);
}
override void visit(AST.InterfaceDeclaration d)
{
//printf("Visiting InterfaceDeclaration\n");
visitBaseClasses(d);
if (d.members)
foreach (s; *d.members)
s.accept(this);
}
override void visit(AST.AliasDeclaration d)
{
//printf("Visting AliasDeclaration\n");
if (d.aliassym)
d.aliassym.accept(this);
else
visitType(d.type);
}
override void visit(AST.AliasAssign d)
{
//printf("Visting AliasAssign\n");
if (d.aliassym)
d.aliassym.accept(this);
else
visitType(d.type);
}
override void visit(AST.VarDeclaration d)
{
//printf("Visiting VarDeclaration\n");
visitVarDecl(d);
}
override void visit(AST.FuncDeclaration f)
{
//printf("Visiting FuncDeclaration\n");
auto tf = f.type.isTypeFunction();
visitType(tf);
visitFuncBody(f);
}
override void visit(AST.FuncLiteralDeclaration f)
{
//printf("Visiting FuncLiteralDeclaration\n");
if (f.type.ty == Terror)
return;
auto tf = f.type.isTypeFunction();
if (!f.inferRetType && tf.next)
visitType(tf.next);
visitParameters(tf.parameterList.parameters.peekSlice());
AST.CompoundStatement cs = f.fbody.isCompoundStatement();
AST.Statement s = !cs ? f.fbody : null;
AST.ReturnStatement rs = s ? s.isReturnStatement() : null;
if (rs && rs.exp)
rs.exp.accept(this);
else
visitFuncBody(f);
}
override void visit(AST.PostBlitDeclaration d)
{
//printf("Visiting PostBlitDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.DtorDeclaration d)
{
//printf("Visiting DtorDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.CtorDeclaration d)
{
//printf("Visiting CtorDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.StaticCtorDeclaration d)
{
//printf("Visiting StaticCtorDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.StaticDtorDeclaration d)
{
//printf("Visiting StaticDtorDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.InvariantDeclaration d)
{
//printf("Visiting InvariantDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.UnitTestDeclaration d)
{
//printf("Visiting UnitTestDeclaration\n");
visitFuncBody(d);
}
override void visit(AST.NewDeclaration d)
{
//printf("Visiting NewDeclaration\n");
}
// Initializers
//============================================================
override void visit(AST.StructInitializer si)
{
//printf("Visiting StructInitializer\n");
foreach (i, const id; si.field)
if (auto iz = si.value[i])
iz.accept(this);
}
override void visit(AST.ArrayInitializer ai)
{
//printf("Visiting ArrayInitializer\n");
foreach (i, ex; ai.index)
{
if (ex)
ex.accept(this);
if (auto iz = ai.value[i])
iz.accept(this);
}
}
override void visit(AST.ExpInitializer ei)
{
//printf("Visiting ExpInitializer\n");
ei.exp.accept(this);
}
override void visit(AST.CInitializer ci)
{
//printf("Visiting CInitializer\n");
foreach (di; ci.initializerList)
{
foreach (des; (*di.designatorList)[])
{
if (des.exp)
des.exp.accept(this);
}
di.initializer.accept(this);
}
}
// Expressions
//===================================================
override void visit(AST.ArrayLiteralExp e)
{
//printf("Visiting ArrayLiteralExp\n");
visitArgs(e.elements.peekSlice(), e.basis);
}
override void visit(AST.AssocArrayLiteralExp e)
{
//printf("Visiting AssocArrayLiteralExp\n");
foreach (i, key; *e.keys)
{
key.accept(this);
((*e.values)[i]).accept(this);
}
}
override void visit(AST.TypeExp e)
{
//printf("Visiting TypeExp\n");
visitType(e.type);
}
override void visit(AST.ScopeExp e)
{
//printf("Visiting ScopeExp\n");
if (e.sds.isTemplateInstance())
e.sds.accept(this);
}
override void visit(AST.NewExp e)
{
//printf("Visiting NewExp\n");
if (e.thisexp)
e.thisexp.accept(this);
visitType(e.newtype);
visitArgs(e.arguments.peekSlice());
}
override void visit(AST.NewAnonClassExp e)
{
//printf("Visiting NewAnonClassExp\n");
if (e.thisexp)
e.thisexp.accept(this);
visitArgs(e.arguments.peekSlice());
if (e.cd)
e.cd.accept(this);
}
override void visit(AST.TupleExp e)
{
//printf("Visiting TupleExp\n");
if (e.e0)
e.e0.accept(this);
visitArgs(e.exps.peekSlice());
}
override void visit(AST.FuncExp e)
{
//printf("Visiting FuncExp\n");
e.fd.accept(this);
}
override void visit(AST.DeclarationExp e)
{
//printf("Visiting DeclarationExp\n");
if (auto v = e.declaration.isVarDeclaration())
visitVarDecl(v);
else
e.declaration.accept(this);
}
override void visit(AST.TypeidExp e)
{
//printf("Visiting TypeidExp\n");
visitObject(e.obj);
}
override void visit(AST.TraitsExp e)
{
//printf("Visiting TraitExp\n");
if (e.args)
foreach (arg; *e.args)
visitObject(arg);
}
override void visit(AST.IsExp e)
{
//printf("Visiting IsExp\n");
visitType(e.targ);
if (e.tspec)
visitType(e.tspec);
if (e.parameters && e.parameters.length)
visitTemplateParameters(e.parameters);
}
override void visit(AST.UnaExp e)
{
//printf("Visiting UnaExp\n");
e.e1.accept(this);
}
override void visit(AST.BinExp e)
{
//printf("Visiting BinExp\n");
e.e1.accept(this);
e.e2.accept(this);
}
override void visit(AST.MixinExp e)
{
//printf("Visiting MixinExp\n");
visitArgs(e.exps.peekSlice());
}
override void visit(AST.ImportExp e)
{
//printf("Visiting ImportExp\n");
e.e1.accept(this);
}
override void visit(AST.AssertExp e)
{
//printf("Visiting AssertExp\n");
e.e1.accept(this);
if (e.msg)
e.msg.accept(this);
}
override void visit(AST.DotIdExp e)
{
//printf("Visiting DotIdExp\n");
e.e1.accept(this);
}
override void visit(AST.DotTemplateInstanceExp e)
{
//printf("Visiting DotTemplateInstanceExp\n");
e.e1.accept(this);
e.ti.accept(this);
}
override void visit(AST.CallExp e)
{
//printf("Visiting CallExp\n");
e.e1.accept(this);
visitArgs(e.arguments.peekSlice());
}
override void visit(AST.PtrExp e)
{
//printf("Visiting PtrExp\n");
e.e1.accept(this);
}
override void visit(AST.DeleteExp e)
{
//printf("Visiting DeleteExp\n");
e.e1.accept(this);
}
override void visit(AST.CastExp e)
{
//printf("Visiting CastExp\n");
if (e.to)
visitType(e.to);
e.e1.accept(this);
}
override void visit(AST.IntervalExp e)
{
//printf("Visiting IntervalExp\n");
e.lwr.accept(this);
e.upr.accept(this);
}
override void visit(AST.ArrayExp e)
{
//printf("Visiting ArrayExp\n");
e.e1.accept(this);
visitArgs(e.arguments.peekSlice());
}
override void visit(AST.PostExp e)
{
//printf("Visiting PostExp\n");
e.e1.accept(this);
}
override void visit(AST.CondExp e)
{
//printf("Visiting CondExp\n");
e.econd.accept(this);
e.e1.accept(this);
e.e2.accept(this);
}
override void visit(AST.GenericExp e)
{
//printf("Visiting GenericExp\n");
e.cntlExp.accept(this);
foreach (i; 0 .. (*e.types).length)
{
if (auto t = (*e.types)[i]) // null means default case
t.accept(this);
(*e.exps )[i].accept(this);
}
}
override void visit(AST.ThrowExp e)
{
//printf("Visiting ThrowExp\n");
e.e1.accept(this);
}
// Template Parameter
//===========================================================
override void visit(AST.TemplateTypeParameter tp)
{
//printf("Visiting TemplateTypeParameter\n");
if (tp.specType)
visitType(tp.specType);
if (tp.defaultType)
visitType(tp.defaultType);
}
override void visit(AST.TemplateThisParameter tp)
{
//printf("Visiting TemplateThisParameter\n");
visit(cast(AST.TemplateTypeParameter)tp);
}
override void visit(AST.TemplateAliasParameter tp)
{
//printf("Visiting TemplateAliasParameter\n");
if (tp.specType)
visitType(tp.specType);
if (tp.specAlias)
visitObject(tp.specAlias);
if (tp.defaultAlias)
visitObject(tp.defaultAlias);
}
override void visit(AST.TemplateValueParameter tp)
{
//printf("Visiting TemplateValueParameter\n");
visitType(tp.valType);
if (tp.specValue)
tp.specValue.accept(this);
if (tp.defaultValue)
tp.defaultValue.accept(this);
}
//===========================================================
override void visit(AST.StaticIfCondition c)
{
//printf("Visiting StaticIfCondition\n");
c.exp.accept(this);
}
override void visit(AST.Parameter p)
{
//printf("Visiting Parameter\n");
visitType(p.type);
if (p.defaultArg)
p.defaultArg.accept(this);
}
override void visit(AST.Module m)
{
//printf("Visiting Module\n");
foreach (s; *m.members)
{
s.accept(this);
}
}
}