1760c2415Smrg
2760c2415Smrg /* Compiler implementation of the D programming language
3760c2415Smrg * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4760c2415Smrg * written by Dave Fladebo
5760c2415Smrg * http://www.digitalmars.com
6760c2415Smrg * Distributed under the Boost Software License, Version 1.0.
7760c2415Smrg * http://www.boost.org/LICENSE_1_0.txt
8760c2415Smrg * https://github.com/D-Programming-Language/dmd/blob/master/src/hdrgen.c
9760c2415Smrg */
10760c2415Smrg
11760c2415Smrg // Routines to emit header files
12760c2415Smrg
13760c2415Smrg #include "root/dsystem.h"
14760c2415Smrg #include "root/rmem.h"
15760c2415Smrg
16760c2415Smrg #include "mars.h"
17760c2415Smrg #include "id.h"
18760c2415Smrg #include "init.h"
19760c2415Smrg
20760c2415Smrg #include "attrib.h"
21760c2415Smrg #include "cond.h"
22760c2415Smrg #include "doc.h"
23760c2415Smrg #include "enum.h"
24760c2415Smrg #include "import.h"
25760c2415Smrg #include "module.h"
26760c2415Smrg #include "mtype.h"
27760c2415Smrg #include "parse.h"
28760c2415Smrg #include "scope.h"
29760c2415Smrg #include "staticassert.h"
30760c2415Smrg #include "target.h"
31760c2415Smrg #include "template.h"
32760c2415Smrg #include "utf.h"
33760c2415Smrg #include "version.h"
34760c2415Smrg
35760c2415Smrg #include "declaration.h"
36760c2415Smrg #include "aggregate.h"
37760c2415Smrg #include "expression.h"
38760c2415Smrg #include "ctfe.h"
39760c2415Smrg #include "statement.h"
40760c2415Smrg #include "aliasthis.h"
41760c2415Smrg #include "nspace.h"
42760c2415Smrg #include "hdrgen.h"
43760c2415Smrg
44760c2415Smrg void linkageToBuffer(OutBuffer *buf, LINK linkage);
45760c2415Smrg void MODtoBuffer(OutBuffer *buf, MOD mod);
46760c2415Smrg
genhdrfile(Module * m)47760c2415Smrg void genhdrfile(Module *m)
48760c2415Smrg {
49760c2415Smrg OutBuffer buf;
50760c2415Smrg buf.doindent = 1;
51760c2415Smrg
52760c2415Smrg buf.printf("// D import file generated from '%s'", m->srcfile->toChars());
53760c2415Smrg buf.writenl();
54760c2415Smrg
55760c2415Smrg HdrGenState hgs;
56760c2415Smrg hgs.hdrgen = true;
57760c2415Smrg
58760c2415Smrg toCBuffer(m, &buf, &hgs);
59760c2415Smrg
60760c2415Smrg // Transfer image to file
61760c2415Smrg m->hdrfile->setbuffer(buf.data, buf.offset);
62760c2415Smrg buf.extractData();
63760c2415Smrg
64760c2415Smrg ensurePathToNameExists(Loc(), m->hdrfile->toChars());
65760c2415Smrg writeFile(m->loc, m->hdrfile);
66760c2415Smrg }
67760c2415Smrg
68760c2415Smrg /**
69760c2415Smrg * Dumps the full contents of module `m` to `buf`.
70760c2415Smrg * Params:
71760c2415Smrg * buf = buffer to write to.
72760c2415Smrg * m = module to visit all members of.
73760c2415Smrg */
moduleToBuffer(OutBuffer * buf,Module * m)74760c2415Smrg void moduleToBuffer(OutBuffer *buf, Module *m)
75760c2415Smrg {
76760c2415Smrg HdrGenState hgs;
77760c2415Smrg hgs.fullDump = true;
78760c2415Smrg toCBuffer(m, buf, &hgs);
79760c2415Smrg }
80760c2415Smrg
81760c2415Smrg class PrettyPrintVisitor : public Visitor
82760c2415Smrg {
83760c2415Smrg public:
84760c2415Smrg OutBuffer *buf;
85760c2415Smrg HdrGenState *hgs;
86760c2415Smrg bool declstring; // set while declaring alias for string,wstring or dstring
87760c2415Smrg EnumDeclaration *inEnumDecl;
88760c2415Smrg
PrettyPrintVisitor(OutBuffer * buf,HdrGenState * hgs)89760c2415Smrg PrettyPrintVisitor(OutBuffer *buf, HdrGenState *hgs)
90760c2415Smrg : buf(buf), hgs(hgs), declstring(false), inEnumDecl(NULL)
91760c2415Smrg {
92760c2415Smrg }
93760c2415Smrg
visit(Statement *)94760c2415Smrg void visit(Statement *)
95760c2415Smrg {
96760c2415Smrg buf->printf("Statement::toCBuffer()");
97760c2415Smrg buf->writenl();
98760c2415Smrg assert(0);
99760c2415Smrg }
100760c2415Smrg
visit(ErrorStatement *)101760c2415Smrg void visit(ErrorStatement *)
102760c2415Smrg {
103760c2415Smrg buf->printf("__error__");
104760c2415Smrg buf->writenl();
105760c2415Smrg }
106760c2415Smrg
visit(ExpStatement * s)107760c2415Smrg void visit(ExpStatement *s)
108760c2415Smrg {
109760c2415Smrg if (s->exp && s->exp->op == TOKdeclaration)
110760c2415Smrg {
111760c2415Smrg // bypass visit(DeclarationExp)
112760c2415Smrg ((DeclarationExp *)s->exp)->declaration->accept(this);
113760c2415Smrg return;
114760c2415Smrg }
115760c2415Smrg if (s->exp)
116760c2415Smrg s->exp->accept(this);
117760c2415Smrg buf->writeByte(';');
118760c2415Smrg if (!hgs->forStmtInit)
119760c2415Smrg buf->writenl();
120760c2415Smrg }
121760c2415Smrg
visit(CompileStatement * s)122760c2415Smrg void visit(CompileStatement *s)
123760c2415Smrg {
124760c2415Smrg buf->writestring("mixin(");
125760c2415Smrg s->exp->accept(this);
126760c2415Smrg buf->writestring(");");
127760c2415Smrg if (!hgs->forStmtInit)
128760c2415Smrg buf->writenl();
129760c2415Smrg }
130760c2415Smrg
visit(CompoundStatement * s)131760c2415Smrg void visit(CompoundStatement *s)
132760c2415Smrg {
133760c2415Smrg for (size_t i = 0; i < s->statements->dim; i++)
134760c2415Smrg {
135760c2415Smrg Statement *sx = (*s->statements)[i];
136760c2415Smrg if (sx)
137760c2415Smrg sx->accept(this);
138760c2415Smrg }
139760c2415Smrg }
140760c2415Smrg
visit(CompoundDeclarationStatement * s)141760c2415Smrg void visit(CompoundDeclarationStatement *s)
142760c2415Smrg {
143760c2415Smrg bool anywritten = false;
144760c2415Smrg for (size_t i = 0; i < s->statements->dim; i++)
145760c2415Smrg {
146760c2415Smrg Statement *sx = (*s->statements)[i];
147760c2415Smrg ExpStatement *ds = sx ? sx->isExpStatement() : NULL;
148760c2415Smrg if (ds && ds->exp->op == TOKdeclaration)
149760c2415Smrg {
150760c2415Smrg Dsymbol *d = ((DeclarationExp *)ds->exp)->declaration;
151760c2415Smrg assert(d->isDeclaration());
152760c2415Smrg if (VarDeclaration *v = d->isVarDeclaration())
153760c2415Smrg visitVarDecl(v, anywritten);
154760c2415Smrg else
155760c2415Smrg d->accept(this);
156760c2415Smrg anywritten = true;
157760c2415Smrg }
158760c2415Smrg }
159760c2415Smrg buf->writeByte(';');
160760c2415Smrg if (!hgs->forStmtInit)
161760c2415Smrg buf->writenl();
162760c2415Smrg }
163760c2415Smrg
visit(UnrolledLoopStatement * s)164760c2415Smrg void visit(UnrolledLoopStatement *s)
165760c2415Smrg {
166760c2415Smrg buf->writestring("unrolled {");
167760c2415Smrg buf->writenl();
168760c2415Smrg buf->level++;
169760c2415Smrg
170760c2415Smrg for (size_t i = 0; i < s->statements->dim; i++)
171760c2415Smrg {
172760c2415Smrg Statement *sx = (*s->statements)[i];
173760c2415Smrg if (sx)
174760c2415Smrg sx->accept(this);
175760c2415Smrg }
176760c2415Smrg
177760c2415Smrg buf->level--;
178760c2415Smrg buf->writeByte('}');
179760c2415Smrg buf->writenl();
180760c2415Smrg }
181760c2415Smrg
visit(ScopeStatement * s)182760c2415Smrg void visit(ScopeStatement *s)
183760c2415Smrg {
184760c2415Smrg buf->writeByte('{');
185760c2415Smrg buf->writenl();
186760c2415Smrg buf->level++;
187760c2415Smrg
188760c2415Smrg if (s->statement)
189760c2415Smrg s->statement->accept(this);
190760c2415Smrg
191760c2415Smrg buf->level--;
192760c2415Smrg buf->writeByte('}');
193760c2415Smrg buf->writenl();
194760c2415Smrg }
195760c2415Smrg
visit(WhileStatement * s)196760c2415Smrg void visit(WhileStatement *s)
197760c2415Smrg {
198760c2415Smrg buf->writestring("while (");
199760c2415Smrg s->condition->accept(this);
200760c2415Smrg buf->writeByte(')');
201760c2415Smrg buf->writenl();
202760c2415Smrg if (s->_body)
203760c2415Smrg s->_body->accept(this);
204760c2415Smrg }
205760c2415Smrg
visit(DoStatement * s)206760c2415Smrg void visit(DoStatement *s)
207760c2415Smrg {
208760c2415Smrg buf->writestring("do");
209760c2415Smrg buf->writenl();
210760c2415Smrg if (s->_body)
211760c2415Smrg s->_body->accept(this);
212760c2415Smrg buf->writestring("while (");
213760c2415Smrg s->condition->accept(this);
214760c2415Smrg buf->writestring(");");
215760c2415Smrg buf->writenl();
216760c2415Smrg }
217760c2415Smrg
visit(ForStatement * s)218760c2415Smrg void visit(ForStatement *s)
219760c2415Smrg {
220760c2415Smrg buf->writestring("for (");
221760c2415Smrg if (s->_init)
222760c2415Smrg {
223760c2415Smrg hgs->forStmtInit++;
224760c2415Smrg s->_init->accept(this);
225760c2415Smrg hgs->forStmtInit--;
226760c2415Smrg }
227760c2415Smrg else
228760c2415Smrg buf->writeByte(';');
229760c2415Smrg if (s->condition)
230760c2415Smrg {
231760c2415Smrg buf->writeByte(' ');
232760c2415Smrg s->condition->accept(this);
233760c2415Smrg }
234760c2415Smrg buf->writeByte(';');
235760c2415Smrg if (s->increment)
236760c2415Smrg {
237760c2415Smrg buf->writeByte(' ');
238760c2415Smrg s->increment->accept(this);
239760c2415Smrg }
240760c2415Smrg buf->writeByte(')');
241760c2415Smrg buf->writenl();
242760c2415Smrg buf->writeByte('{');
243760c2415Smrg buf->writenl();
244760c2415Smrg buf->level++;
245760c2415Smrg if (s->_body)
246760c2415Smrg s->_body->accept(this);
247760c2415Smrg buf->level--;
248760c2415Smrg buf->writeByte('}');
249760c2415Smrg buf->writenl();
250760c2415Smrg }
251760c2415Smrg
foreachWithoutBody(ForeachStatement * s)252*0bfacb9bSmrg void foreachWithoutBody(ForeachStatement *s)
253760c2415Smrg {
254760c2415Smrg buf->writestring(Token::toChars(s->op));
255760c2415Smrg buf->writestring(" (");
256760c2415Smrg for (size_t i = 0; i < s->parameters->dim; i++)
257760c2415Smrg {
258760c2415Smrg Parameter *p = (*s->parameters)[i];
259760c2415Smrg if (i)
260760c2415Smrg buf->writestring(", ");
261760c2415Smrg if (stcToBuffer(buf, p->storageClass))
262760c2415Smrg buf->writeByte(' ');
263760c2415Smrg if (p->type)
264760c2415Smrg typeToBuffer(p->type, p->ident);
265760c2415Smrg else
266760c2415Smrg buf->writestring(p->ident->toChars());
267760c2415Smrg }
268760c2415Smrg buf->writestring("; ");
269760c2415Smrg s->aggr->accept(this);
270760c2415Smrg buf->writeByte(')');
271760c2415Smrg buf->writenl();
272*0bfacb9bSmrg }
273*0bfacb9bSmrg
visit(ForeachStatement * s)274*0bfacb9bSmrg void visit(ForeachStatement *s)
275*0bfacb9bSmrg {
276*0bfacb9bSmrg foreachWithoutBody(s);
277760c2415Smrg buf->writeByte('{');
278760c2415Smrg buf->writenl();
279760c2415Smrg buf->level++;
280760c2415Smrg if (s->_body)
281760c2415Smrg s->_body->accept(this);
282760c2415Smrg buf->level--;
283760c2415Smrg buf->writeByte('}');
284760c2415Smrg buf->writenl();
285760c2415Smrg }
286760c2415Smrg
foreachRangeWithoutBody(ForeachRangeStatement * s)287*0bfacb9bSmrg void foreachRangeWithoutBody(ForeachRangeStatement *s)
288760c2415Smrg {
289760c2415Smrg buf->writestring(Token::toChars(s->op));
290760c2415Smrg buf->writestring(" (");
291760c2415Smrg
292760c2415Smrg if (s->prm->type)
293760c2415Smrg typeToBuffer(s->prm->type, s->prm->ident);
294760c2415Smrg else
295760c2415Smrg buf->writestring(s->prm->ident->toChars());
296760c2415Smrg
297760c2415Smrg buf->writestring("; ");
298760c2415Smrg s->lwr->accept(this);
299760c2415Smrg buf->writestring(" .. ");
300760c2415Smrg s->upr->accept(this);
301760c2415Smrg buf->writeByte(')');
302760c2415Smrg buf->writenl();
303760c2415Smrg buf->writeByte('{');
304760c2415Smrg buf->writenl();
305*0bfacb9bSmrg }
306*0bfacb9bSmrg
visit(ForeachRangeStatement * s)307*0bfacb9bSmrg void visit(ForeachRangeStatement *s)
308*0bfacb9bSmrg {
309*0bfacb9bSmrg foreachRangeWithoutBody(s);
310760c2415Smrg buf->level++;
311760c2415Smrg if (s->_body)
312760c2415Smrg s->_body->accept(this);
313760c2415Smrg buf->level--;
314760c2415Smrg buf->writeByte('}');
315760c2415Smrg buf->writenl();
316760c2415Smrg }
317760c2415Smrg
visit(StaticForeachStatement * s)318*0bfacb9bSmrg void visit(StaticForeachStatement *s)
319*0bfacb9bSmrg {
320*0bfacb9bSmrg buf->writestring("static ");
321*0bfacb9bSmrg if (s->sfe->aggrfe)
322*0bfacb9bSmrg {
323*0bfacb9bSmrg visit(s->sfe->aggrfe);
324*0bfacb9bSmrg }
325*0bfacb9bSmrg else
326*0bfacb9bSmrg {
327*0bfacb9bSmrg assert(s->sfe->rangefe);
328*0bfacb9bSmrg visit(s->sfe->rangefe);
329*0bfacb9bSmrg }
330*0bfacb9bSmrg }
331*0bfacb9bSmrg
visit(IfStatement * s)332760c2415Smrg void visit(IfStatement *s)
333760c2415Smrg {
334760c2415Smrg buf->writestring("if (");
335760c2415Smrg if (Parameter *p = s->prm)
336760c2415Smrg {
337760c2415Smrg StorageClass stc = p->storageClass;
338760c2415Smrg if (!p->type && !stc)
339760c2415Smrg stc = STCauto;
340760c2415Smrg if (stcToBuffer(buf, stc))
341760c2415Smrg buf->writeByte(' ');
342760c2415Smrg if (p->type)
343760c2415Smrg typeToBuffer(p->type, p->ident);
344760c2415Smrg else
345760c2415Smrg buf->writestring(p->ident->toChars());
346760c2415Smrg buf->writestring(" = ");
347760c2415Smrg }
348760c2415Smrg s->condition->accept(this);
349760c2415Smrg buf->writeByte(')');
350760c2415Smrg buf->writenl();
351760c2415Smrg if (s->ifbody->isScopeStatement())
352760c2415Smrg {
353760c2415Smrg s->ifbody->accept(this);
354760c2415Smrg }
355760c2415Smrg else
356760c2415Smrg {
357760c2415Smrg buf->level++;
358760c2415Smrg s->ifbody->accept(this);
359760c2415Smrg buf->level--;
360760c2415Smrg }
361760c2415Smrg if (s->elsebody)
362760c2415Smrg {
363760c2415Smrg buf->writestring("else");
364760c2415Smrg if (!s->elsebody->isIfStatement())
365760c2415Smrg {
366760c2415Smrg buf->writenl();
367760c2415Smrg }
368760c2415Smrg else
369760c2415Smrg {
370760c2415Smrg buf->writeByte(' ');
371760c2415Smrg }
372760c2415Smrg if (s->elsebody->isScopeStatement() || s->elsebody->isIfStatement())
373760c2415Smrg {
374760c2415Smrg s->elsebody->accept(this);
375760c2415Smrg }
376760c2415Smrg else
377760c2415Smrg {
378760c2415Smrg buf->level++;
379760c2415Smrg s->elsebody->accept(this);
380760c2415Smrg buf->level--;
381760c2415Smrg }
382760c2415Smrg }
383760c2415Smrg }
384760c2415Smrg
visit(ConditionalStatement * s)385760c2415Smrg void visit(ConditionalStatement *s)
386760c2415Smrg {
387760c2415Smrg s->condition->accept(this);
388760c2415Smrg buf->writenl();
389760c2415Smrg buf->writeByte('{');
390760c2415Smrg buf->writenl();
391760c2415Smrg buf->level++;
392760c2415Smrg if (s->ifbody)
393760c2415Smrg s->ifbody->accept(this);
394760c2415Smrg buf->level--;
395760c2415Smrg buf->writeByte('}');
396760c2415Smrg buf->writenl();
397760c2415Smrg if (s->elsebody)
398760c2415Smrg {
399760c2415Smrg buf->writestring("else");
400760c2415Smrg buf->writenl();
401760c2415Smrg buf->writeByte('{');
402760c2415Smrg buf->level++;
403760c2415Smrg buf->writenl();
404760c2415Smrg s->elsebody->accept(this);
405760c2415Smrg buf->level--;
406760c2415Smrg buf->writeByte('}');
407760c2415Smrg }
408760c2415Smrg buf->writenl();
409760c2415Smrg }
410760c2415Smrg
visit(PragmaStatement * s)411760c2415Smrg void visit(PragmaStatement *s)
412760c2415Smrg {
413760c2415Smrg buf->writestring("pragma (");
414760c2415Smrg buf->writestring(s->ident->toChars());
415760c2415Smrg if (s->args && s->args->dim)
416760c2415Smrg {
417760c2415Smrg buf->writestring(", ");
418760c2415Smrg argsToBuffer(s->args);
419760c2415Smrg }
420760c2415Smrg buf->writeByte(')');
421760c2415Smrg if (s->_body)
422760c2415Smrg {
423760c2415Smrg buf->writenl();
424760c2415Smrg buf->writeByte('{');
425760c2415Smrg buf->writenl();
426760c2415Smrg buf->level++;
427760c2415Smrg
428760c2415Smrg s->_body->accept(this);
429760c2415Smrg
430760c2415Smrg buf->level--;
431760c2415Smrg buf->writeByte('}');
432760c2415Smrg buf->writenl();
433760c2415Smrg }
434760c2415Smrg else
435760c2415Smrg {
436760c2415Smrg buf->writeByte(';');
437760c2415Smrg buf->writenl();
438760c2415Smrg }
439760c2415Smrg }
440760c2415Smrg
visit(StaticAssertStatement * s)441760c2415Smrg void visit(StaticAssertStatement *s)
442760c2415Smrg {
443760c2415Smrg s->sa->accept(this);
444760c2415Smrg }
445760c2415Smrg
visit(SwitchStatement * s)446760c2415Smrg void visit(SwitchStatement *s)
447760c2415Smrg {
448760c2415Smrg buf->writestring(s->isFinal ? "final switch (" : "switch (");
449760c2415Smrg s->condition->accept(this);
450760c2415Smrg buf->writeByte(')');
451760c2415Smrg buf->writenl();
452760c2415Smrg if (s->_body)
453760c2415Smrg {
454760c2415Smrg if (!s->_body->isScopeStatement())
455760c2415Smrg {
456760c2415Smrg buf->writeByte('{');
457760c2415Smrg buf->writenl();
458760c2415Smrg buf->level++;
459760c2415Smrg s->_body->accept(this);
460760c2415Smrg buf->level--;
461760c2415Smrg buf->writeByte('}');
462760c2415Smrg buf->writenl();
463760c2415Smrg }
464760c2415Smrg else
465760c2415Smrg {
466760c2415Smrg s->_body->accept(this);
467760c2415Smrg }
468760c2415Smrg }
469760c2415Smrg }
470760c2415Smrg
visit(CaseStatement * s)471760c2415Smrg void visit(CaseStatement *s)
472760c2415Smrg {
473760c2415Smrg buf->writestring("case ");
474760c2415Smrg s->exp->accept(this);
475760c2415Smrg buf->writeByte(':');
476760c2415Smrg buf->writenl();
477760c2415Smrg s->statement->accept(this);
478760c2415Smrg }
479760c2415Smrg
visit(CaseRangeStatement * s)480760c2415Smrg void visit(CaseRangeStatement *s)
481760c2415Smrg {
482760c2415Smrg buf->writestring("case ");
483760c2415Smrg s->first->accept(this);
484760c2415Smrg buf->writestring(": .. case ");
485760c2415Smrg s->last->accept(this);
486760c2415Smrg buf->writeByte(':');
487760c2415Smrg buf->writenl();
488760c2415Smrg s->statement->accept(this);
489760c2415Smrg }
490760c2415Smrg
visit(DefaultStatement * s)491760c2415Smrg void visit(DefaultStatement *s)
492760c2415Smrg {
493760c2415Smrg buf->writestring("default:");
494760c2415Smrg buf->writenl();
495760c2415Smrg s->statement->accept(this);
496760c2415Smrg }
497760c2415Smrg
visit(GotoDefaultStatement *)498760c2415Smrg void visit(GotoDefaultStatement *)
499760c2415Smrg {
500760c2415Smrg buf->writestring("goto default;");
501760c2415Smrg buf->writenl();
502760c2415Smrg }
503760c2415Smrg
visit(GotoCaseStatement * s)504760c2415Smrg void visit(GotoCaseStatement *s)
505760c2415Smrg {
506760c2415Smrg buf->writestring("goto case");
507760c2415Smrg if (s->exp)
508760c2415Smrg {
509760c2415Smrg buf->writeByte(' ');
510760c2415Smrg s->exp->accept(this);
511760c2415Smrg }
512760c2415Smrg buf->writeByte(';');
513760c2415Smrg buf->writenl();
514760c2415Smrg }
515760c2415Smrg
visit(SwitchErrorStatement *)516760c2415Smrg void visit(SwitchErrorStatement *)
517760c2415Smrg {
518760c2415Smrg buf->writestring("SwitchErrorStatement::toCBuffer()");
519760c2415Smrg buf->writenl();
520760c2415Smrg }
521760c2415Smrg
visit(ReturnStatement * s)522760c2415Smrg void visit(ReturnStatement *s)
523760c2415Smrg {
524760c2415Smrg buf->printf("return ");
525760c2415Smrg if (s->exp)
526760c2415Smrg s->exp->accept(this);
527760c2415Smrg buf->writeByte(';');
528760c2415Smrg buf->writenl();
529760c2415Smrg }
530760c2415Smrg
visit(BreakStatement * s)531760c2415Smrg void visit(BreakStatement *s)
532760c2415Smrg {
533760c2415Smrg buf->writestring("break");
534760c2415Smrg if (s->ident)
535760c2415Smrg {
536760c2415Smrg buf->writeByte(' ');
537760c2415Smrg buf->writestring(s->ident->toChars());
538760c2415Smrg }
539760c2415Smrg buf->writeByte(';');
540760c2415Smrg buf->writenl();
541760c2415Smrg }
542760c2415Smrg
visit(ContinueStatement * s)543760c2415Smrg void visit(ContinueStatement *s)
544760c2415Smrg {
545760c2415Smrg buf->writestring("continue");
546760c2415Smrg if (s->ident)
547760c2415Smrg {
548760c2415Smrg buf->writeByte(' ');
549760c2415Smrg buf->writestring(s->ident->toChars());
550760c2415Smrg }
551760c2415Smrg buf->writeByte(';');
552760c2415Smrg buf->writenl();
553760c2415Smrg }
554760c2415Smrg
visit(SynchronizedStatement * s)555760c2415Smrg void visit(SynchronizedStatement *s)
556760c2415Smrg {
557760c2415Smrg buf->writestring("synchronized");
558760c2415Smrg if (s->exp)
559760c2415Smrg {
560760c2415Smrg buf->writeByte('(');
561760c2415Smrg s->exp->accept(this);
562760c2415Smrg buf->writeByte(')');
563760c2415Smrg }
564760c2415Smrg if (s->_body)
565760c2415Smrg {
566760c2415Smrg buf->writeByte(' ');
567760c2415Smrg s->_body->accept(this);
568760c2415Smrg }
569760c2415Smrg }
570760c2415Smrg
visit(WithStatement * s)571760c2415Smrg void visit(WithStatement *s)
572760c2415Smrg {
573760c2415Smrg buf->writestring("with (");
574760c2415Smrg s->exp->accept(this);
575760c2415Smrg buf->writestring(")");
576760c2415Smrg buf->writenl();
577760c2415Smrg if (s->_body)
578760c2415Smrg s->_body->accept(this);
579760c2415Smrg }
580760c2415Smrg
visit(TryCatchStatement * s)581760c2415Smrg void visit(TryCatchStatement *s)
582760c2415Smrg {
583760c2415Smrg buf->writestring("try");
584760c2415Smrg buf->writenl();
585760c2415Smrg if (s->_body)
586760c2415Smrg s->_body->accept(this);
587760c2415Smrg for (size_t i = 0; i < s->catches->dim; i++)
588760c2415Smrg {
589760c2415Smrg Catch *c = (*s->catches)[i];
590760c2415Smrg visit(c);
591760c2415Smrg }
592760c2415Smrg }
593760c2415Smrg
visit(TryFinallyStatement * s)594760c2415Smrg void visit(TryFinallyStatement *s)
595760c2415Smrg {
596760c2415Smrg buf->writestring("try");
597760c2415Smrg buf->writenl();
598760c2415Smrg buf->writeByte('{');
599760c2415Smrg buf->writenl();
600760c2415Smrg buf->level++;
601760c2415Smrg s->_body->accept(this);
602760c2415Smrg buf->level--;
603760c2415Smrg buf->writeByte('}');
604760c2415Smrg buf->writenl();
605760c2415Smrg buf->writestring("finally");
606760c2415Smrg buf->writenl();
607760c2415Smrg if (s->finalbody->isScopeStatement())
608760c2415Smrg {
609760c2415Smrg s->finalbody->accept(this);
610760c2415Smrg }
611760c2415Smrg else
612760c2415Smrg {
613760c2415Smrg buf->level++;
614760c2415Smrg s->finalbody->accept(this);
615760c2415Smrg buf->level--;
616760c2415Smrg }
617760c2415Smrg buf->writeByte('}');
618760c2415Smrg buf->writenl();
619760c2415Smrg }
620760c2415Smrg
visit(OnScopeStatement * s)621760c2415Smrg void visit(OnScopeStatement *s)
622760c2415Smrg {
623760c2415Smrg buf->writestring(Token::toChars(s->tok));
624760c2415Smrg buf->writeByte(' ');
625760c2415Smrg s->statement->accept(this);
626760c2415Smrg }
627760c2415Smrg
visit(ThrowStatement * s)628760c2415Smrg void visit(ThrowStatement *s)
629760c2415Smrg {
630760c2415Smrg buf->printf("throw ");
631760c2415Smrg s->exp->accept(this);
632760c2415Smrg buf->writeByte(';');
633760c2415Smrg buf->writenl();
634760c2415Smrg }
635760c2415Smrg
visit(DebugStatement * s)636760c2415Smrg void visit(DebugStatement *s)
637760c2415Smrg {
638760c2415Smrg if (s->statement)
639760c2415Smrg {
640760c2415Smrg s->statement->accept(this);
641760c2415Smrg }
642760c2415Smrg }
643760c2415Smrg
visit(GotoStatement * s)644760c2415Smrg void visit(GotoStatement *s)
645760c2415Smrg {
646760c2415Smrg buf->writestring("goto ");
647760c2415Smrg buf->writestring(s->ident->toChars());
648760c2415Smrg buf->writeByte(';');
649760c2415Smrg buf->writenl();
650760c2415Smrg }
651760c2415Smrg
visit(LabelStatement * s)652760c2415Smrg void visit(LabelStatement *s)
653760c2415Smrg {
654760c2415Smrg buf->writestring(s->ident->toChars());
655760c2415Smrg buf->writeByte(':');
656760c2415Smrg buf->writenl();
657760c2415Smrg if (s->statement)
658760c2415Smrg s->statement->accept(this);
659760c2415Smrg }
660760c2415Smrg
visit(AsmStatement * s)661760c2415Smrg void visit(AsmStatement *s)
662760c2415Smrg {
663760c2415Smrg buf->writestring("asm { ");
664760c2415Smrg Token *t = s->tokens;
665760c2415Smrg buf->level++;
666760c2415Smrg while (t)
667760c2415Smrg {
668760c2415Smrg buf->writestring(t->toChars());
669760c2415Smrg if (t->next &&
670760c2415Smrg t->value != TOKmin &&
671760c2415Smrg t->value != TOKcomma && t->next->value != TOKcomma &&
672760c2415Smrg t->value != TOKlbracket && t->next->value != TOKlbracket &&
673760c2415Smrg t->next->value != TOKrbracket &&
674760c2415Smrg t->value != TOKlparen && t->next->value != TOKlparen &&
675760c2415Smrg t->next->value != TOKrparen &&
676760c2415Smrg t->value != TOKdot && t->next->value != TOKdot)
677760c2415Smrg {
678760c2415Smrg buf->writeByte(' ');
679760c2415Smrg }
680760c2415Smrg t = t->next;
681760c2415Smrg }
682760c2415Smrg buf->level--;
683760c2415Smrg buf->writestring("; }");
684760c2415Smrg buf->writenl();
685760c2415Smrg }
686760c2415Smrg
visit(ImportStatement * s)687760c2415Smrg void visit(ImportStatement *s)
688760c2415Smrg {
689760c2415Smrg for (size_t i = 0; i < s->imports->dim; i++)
690760c2415Smrg {
691760c2415Smrg Dsymbol *imp = (*s->imports)[i];
692760c2415Smrg imp->accept(this);
693760c2415Smrg }
694760c2415Smrg }
695760c2415Smrg
visit(Catch * c)696760c2415Smrg void visit(Catch *c)
697760c2415Smrg {
698760c2415Smrg buf->writestring("catch");
699760c2415Smrg if (c->type)
700760c2415Smrg {
701760c2415Smrg buf->writeByte('(');
702760c2415Smrg typeToBuffer(c->type, c->ident);
703760c2415Smrg buf->writeByte(')');
704760c2415Smrg }
705760c2415Smrg buf->writenl();
706760c2415Smrg buf->writeByte('{');
707760c2415Smrg buf->writenl();
708760c2415Smrg buf->level++;
709760c2415Smrg if (c->handler)
710760c2415Smrg c->handler->accept(this);
711760c2415Smrg buf->level--;
712760c2415Smrg buf->writeByte('}');
713760c2415Smrg buf->writenl();
714760c2415Smrg }
715760c2415Smrg
716760c2415Smrg ////////////////////////////////////////////////////////////////////////////
717760c2415Smrg
718760c2415Smrg /**************************************************
719760c2415Smrg * An entry point to pretty-print type.
720760c2415Smrg */
typeToBuffer(Type * t,Identifier * ident)721760c2415Smrg void typeToBuffer(Type *t, Identifier *ident)
722760c2415Smrg {
723760c2415Smrg if (t->ty == Tfunction)
724760c2415Smrg {
725760c2415Smrg visitFuncIdentWithPrefix((TypeFunction *)t, ident, NULL);
726760c2415Smrg return;
727760c2415Smrg }
728760c2415Smrg
729760c2415Smrg visitWithMask(t, 0);
730760c2415Smrg
731760c2415Smrg if (ident)
732760c2415Smrg {
733760c2415Smrg buf->writeByte(' ');
734760c2415Smrg buf->writestring(ident->toChars());
735760c2415Smrg }
736760c2415Smrg }
737760c2415Smrg
visitWithMask(Type * t,unsigned char modMask)738760c2415Smrg void visitWithMask(Type *t, unsigned char modMask)
739760c2415Smrg {
740760c2415Smrg // Tuples and functions don't use the type constructor syntax
741760c2415Smrg if (modMask == t->mod ||
742760c2415Smrg t->ty == Tfunction ||
743760c2415Smrg t->ty == Ttuple)
744760c2415Smrg {
745760c2415Smrg t->accept(this);
746760c2415Smrg }
747760c2415Smrg else
748760c2415Smrg {
749760c2415Smrg unsigned char m = t->mod & ~(t->mod & modMask);
750760c2415Smrg if (m & MODshared)
751760c2415Smrg {
752760c2415Smrg MODtoBuffer(buf, MODshared);
753760c2415Smrg buf->writeByte('(');
754760c2415Smrg }
755760c2415Smrg if (m & MODwild)
756760c2415Smrg {
757760c2415Smrg MODtoBuffer(buf, MODwild);
758760c2415Smrg buf->writeByte('(');
759760c2415Smrg }
760760c2415Smrg if (m & (MODconst | MODimmutable))
761760c2415Smrg {
762760c2415Smrg MODtoBuffer(buf, m & (MODconst | MODimmutable));
763760c2415Smrg buf->writeByte('(');
764760c2415Smrg }
765760c2415Smrg
766760c2415Smrg t->accept(this);
767760c2415Smrg
768760c2415Smrg if (m & (MODconst | MODimmutable))
769760c2415Smrg buf->writeByte(')');
770760c2415Smrg if (m & MODwild)
771760c2415Smrg buf->writeByte(')');
772760c2415Smrg if (m & MODshared)
773760c2415Smrg buf->writeByte(')');
774760c2415Smrg }
775760c2415Smrg }
776760c2415Smrg
visit(Type * t)777760c2415Smrg void visit(Type *t)
778760c2415Smrg {
779760c2415Smrg printf("t = %p, ty = %d\n", t, t->ty);
780760c2415Smrg assert(0);
781760c2415Smrg }
782760c2415Smrg
visit(TypeError *)783760c2415Smrg void visit(TypeError *)
784760c2415Smrg {
785760c2415Smrg buf->writestring("_error_");
786760c2415Smrg }
787760c2415Smrg
visit(TypeBasic * t)788760c2415Smrg void visit(TypeBasic *t)
789760c2415Smrg {
790760c2415Smrg //printf("TypeBasic::toCBuffer2(t->mod = %d)\n", t->mod);
791760c2415Smrg buf->writestring(t->dstring);
792760c2415Smrg }
793760c2415Smrg
visit(TypeTraits * t)794*0bfacb9bSmrg void visit(TypeTraits *t)
795*0bfacb9bSmrg {
796*0bfacb9bSmrg //printf("TypeBasic::toCBuffer2(t.mod = %d)\n", t.mod);
797*0bfacb9bSmrg t->exp->accept(this);
798*0bfacb9bSmrg }
799*0bfacb9bSmrg
visit(TypeVector * t)800760c2415Smrg void visit(TypeVector *t)
801760c2415Smrg {
802760c2415Smrg //printf("TypeVector::toCBuffer2(t->mod = %d)\n", t->mod);
803760c2415Smrg buf->writestring("__vector(");
804760c2415Smrg visitWithMask(t->basetype, t->mod);
805760c2415Smrg buf->writestring(")");
806760c2415Smrg }
807760c2415Smrg
visit(TypeSArray * t)808760c2415Smrg void visit(TypeSArray *t)
809760c2415Smrg {
810760c2415Smrg visitWithMask(t->next, t->mod);
811760c2415Smrg buf->writeByte('[');
812760c2415Smrg sizeToBuffer(t->dim);
813760c2415Smrg buf->writeByte(']');
814760c2415Smrg }
815760c2415Smrg
visit(TypeDArray * t)816760c2415Smrg void visit(TypeDArray *t)
817760c2415Smrg {
818760c2415Smrg Type *ut = t->castMod(0);
819760c2415Smrg if (declstring)
820760c2415Smrg goto L1;
821760c2415Smrg if (ut->equals(Type::tstring))
822760c2415Smrg buf->writestring("string");
823760c2415Smrg else if (ut->equals(Type::twstring))
824760c2415Smrg buf->writestring("wstring");
825760c2415Smrg else if (ut->equals(Type::tdstring))
826760c2415Smrg buf->writestring("dstring");
827760c2415Smrg else
828760c2415Smrg {
829760c2415Smrg L1:
830760c2415Smrg visitWithMask(t->next, t->mod);
831760c2415Smrg buf->writestring("[]");
832760c2415Smrg }
833760c2415Smrg }
834760c2415Smrg
visit(TypeAArray * t)835760c2415Smrg void visit(TypeAArray *t)
836760c2415Smrg {
837760c2415Smrg visitWithMask(t->next, t->mod);
838760c2415Smrg buf->writeByte('[');
839760c2415Smrg visitWithMask(t->index, 0);
840760c2415Smrg buf->writeByte(']');
841760c2415Smrg }
842760c2415Smrg
visit(TypePointer * t)843760c2415Smrg void visit(TypePointer *t)
844760c2415Smrg {
845760c2415Smrg //printf("TypePointer::toCBuffer2() next = %d\n", t->next->ty);
846760c2415Smrg if (t->next->ty == Tfunction)
847760c2415Smrg visitFuncIdentWithPostfix((TypeFunction *)t->next, "function");
848760c2415Smrg else
849760c2415Smrg {
850760c2415Smrg visitWithMask(t->next, t->mod);
851760c2415Smrg buf->writeByte('*');
852760c2415Smrg }
853760c2415Smrg }
854760c2415Smrg
visit(TypeReference * t)855760c2415Smrg void visit(TypeReference *t)
856760c2415Smrg {
857760c2415Smrg visitWithMask(t->next, t->mod);
858760c2415Smrg buf->writeByte('&');
859760c2415Smrg }
860760c2415Smrg
visit(TypeFunction * t)861760c2415Smrg void visit(TypeFunction *t)
862760c2415Smrg {
863760c2415Smrg //printf("TypeFunction::toCBuffer2() t = %p, ref = %d\n", t, t->isref);
864760c2415Smrg visitFuncIdentWithPostfix(t, NULL);
865760c2415Smrg }
866760c2415Smrg
867760c2415Smrg // callback for TypeFunction::attributesApply
868760c2415Smrg struct PrePostAppendStrings
869760c2415Smrg {
870760c2415Smrg OutBuffer *buf;
871760c2415Smrg bool isPostfixStyle;
872760c2415Smrg bool isCtor;
873760c2415Smrg
fpPrePostAppendStrings874760c2415Smrg static int fp(void *param, const char *str)
875760c2415Smrg {
876760c2415Smrg PrePostAppendStrings *p = (PrePostAppendStrings *)param;
877760c2415Smrg
878760c2415Smrg // don't write 'ref' for ctors
879760c2415Smrg if (p->isCtor && strcmp(str, "ref") == 0)
880760c2415Smrg return 0;
881760c2415Smrg
882760c2415Smrg if ( p->isPostfixStyle) p->buf->writeByte(' ');
883760c2415Smrg p->buf->writestring(str);
884760c2415Smrg if (!p->isPostfixStyle) p->buf->writeByte(' ');
885760c2415Smrg return 0;
886760c2415Smrg }
887760c2415Smrg };
888760c2415Smrg
visitFuncIdentWithPostfix(TypeFunction * t,const char * ident)889760c2415Smrg void visitFuncIdentWithPostfix(TypeFunction *t, const char *ident)
890760c2415Smrg {
891760c2415Smrg if (t->inuse)
892760c2415Smrg {
893760c2415Smrg t->inuse = 2; // flag error to caller
894760c2415Smrg return;
895760c2415Smrg }
896760c2415Smrg t->inuse++;
897760c2415Smrg
898760c2415Smrg PrePostAppendStrings pas;
899760c2415Smrg pas.buf = buf;
900760c2415Smrg pas.isCtor = false;
901760c2415Smrg pas.isPostfixStyle = true;
902760c2415Smrg
903760c2415Smrg if (t->linkage > LINKd && hgs->ddoc != 1 && !hgs->hdrgen)
904760c2415Smrg {
905760c2415Smrg linkageToBuffer(buf, t->linkage);
906760c2415Smrg buf->writeByte(' ');
907760c2415Smrg }
908760c2415Smrg
909760c2415Smrg if (t->next)
910760c2415Smrg {
911760c2415Smrg typeToBuffer(t->next, NULL);
912760c2415Smrg if (ident)
913760c2415Smrg buf->writeByte(' ');
914760c2415Smrg }
915760c2415Smrg else if (hgs->ddoc)
916760c2415Smrg buf->writestring("auto ");
917760c2415Smrg
918760c2415Smrg if (ident)
919760c2415Smrg buf->writestring(ident);
920760c2415Smrg
921760c2415Smrg parametersToBuffer(t->parameters, t->varargs);
922760c2415Smrg
923760c2415Smrg /* Use postfix style for attributes
924760c2415Smrg */
925760c2415Smrg if (t->mod)
926760c2415Smrg {
927760c2415Smrg buf->writeByte(' ');
928760c2415Smrg MODtoBuffer(buf, t->mod);
929760c2415Smrg }
930760c2415Smrg t->attributesApply(&pas, &PrePostAppendStrings::fp);
931760c2415Smrg
932760c2415Smrg t->inuse--;
933760c2415Smrg }
visitFuncIdentWithPrefix(TypeFunction * t,Identifier * ident,TemplateDeclaration * td)934760c2415Smrg void visitFuncIdentWithPrefix(TypeFunction *t, Identifier *ident, TemplateDeclaration *td)
935760c2415Smrg {
936760c2415Smrg if (t->inuse)
937760c2415Smrg {
938760c2415Smrg t->inuse = 2; // flag error to caller
939760c2415Smrg return;
940760c2415Smrg }
941760c2415Smrg t->inuse++;
942760c2415Smrg
943760c2415Smrg PrePostAppendStrings pas;
944760c2415Smrg pas.buf = buf;
945760c2415Smrg pas.isCtor = (ident == Id::ctor);
946760c2415Smrg pas.isPostfixStyle = false;
947760c2415Smrg
948760c2415Smrg /* Use 'storage class' (prefix) style for attributes
949760c2415Smrg */
950760c2415Smrg if (t->mod)
951760c2415Smrg {
952760c2415Smrg MODtoBuffer(buf, t->mod);
953760c2415Smrg buf->writeByte(' ');
954760c2415Smrg }
955760c2415Smrg t->attributesApply(&pas, &PrePostAppendStrings::fp);
956760c2415Smrg
957760c2415Smrg if (t->linkage > LINKd && hgs->ddoc != 1 && !hgs->hdrgen)
958760c2415Smrg {
959760c2415Smrg linkageToBuffer(buf, t->linkage);
960760c2415Smrg buf->writeByte(' ');
961760c2415Smrg }
962760c2415Smrg
963760c2415Smrg if (ident && ident->toHChars2() != ident->toChars())
964760c2415Smrg {
965760c2415Smrg // Don't print return type for ctor, dtor, unittest, etc
966760c2415Smrg }
967760c2415Smrg else if (t->next)
968760c2415Smrg {
969760c2415Smrg typeToBuffer(t->next, NULL);
970760c2415Smrg if (ident)
971760c2415Smrg buf->writeByte(' ');
972760c2415Smrg }
973760c2415Smrg else if (hgs->ddoc)
974760c2415Smrg buf->writestring("auto ");
975760c2415Smrg
976760c2415Smrg if (ident)
977760c2415Smrg buf->writestring(ident->toHChars2());
978760c2415Smrg
979760c2415Smrg if (td)
980760c2415Smrg {
981760c2415Smrg buf->writeByte('(');
982760c2415Smrg for (size_t i = 0; i < td->origParameters->dim; i++)
983760c2415Smrg {
984760c2415Smrg TemplateParameter *p = (*td->origParameters)[i];
985760c2415Smrg if (i)
986760c2415Smrg buf->writestring(", ");
987760c2415Smrg p->accept(this);
988760c2415Smrg }
989760c2415Smrg buf->writeByte(')');
990760c2415Smrg }
991760c2415Smrg parametersToBuffer(t->parameters, t->varargs);
992760c2415Smrg
993760c2415Smrg t->inuse--;
994760c2415Smrg }
995760c2415Smrg
visit(TypeDelegate * t)996760c2415Smrg void visit(TypeDelegate *t)
997760c2415Smrg {
998760c2415Smrg visitFuncIdentWithPostfix((TypeFunction *)t->next, "delegate");
999760c2415Smrg }
1000760c2415Smrg
visitTypeQualifiedHelper(TypeQualified * t)1001760c2415Smrg void visitTypeQualifiedHelper(TypeQualified *t)
1002760c2415Smrg {
1003760c2415Smrg for (size_t i = 0; i < t->idents.dim; i++)
1004760c2415Smrg {
1005760c2415Smrg RootObject *id = t->idents[i];
1006760c2415Smrg
1007760c2415Smrg if (id->dyncast() == DYNCAST_DSYMBOL)
1008760c2415Smrg {
1009760c2415Smrg buf->writeByte('.');
1010760c2415Smrg TemplateInstance *ti = (TemplateInstance *)id;
1011760c2415Smrg ti->accept(this);
1012760c2415Smrg }
1013760c2415Smrg else if (id->dyncast() == DYNCAST_EXPRESSION)
1014760c2415Smrg {
1015760c2415Smrg buf->writeByte('[');
1016760c2415Smrg ((Expression *)id)->accept(this);
1017760c2415Smrg buf->writeByte(']');
1018760c2415Smrg }
1019760c2415Smrg else if (id->dyncast() == DYNCAST_TYPE)
1020760c2415Smrg {
1021760c2415Smrg buf->writeByte('[');
1022760c2415Smrg ((Type *)id)->accept(this);
1023760c2415Smrg buf->writeByte(']');
1024760c2415Smrg }
1025760c2415Smrg else
1026760c2415Smrg {
1027760c2415Smrg buf->writeByte('.');
1028760c2415Smrg buf->writestring(id->toChars());
1029760c2415Smrg }
1030760c2415Smrg }
1031760c2415Smrg }
1032760c2415Smrg
visit(TypeIdentifier * t)1033760c2415Smrg void visit(TypeIdentifier *t)
1034760c2415Smrg {
1035760c2415Smrg buf->writestring(t->ident->toChars());
1036760c2415Smrg visitTypeQualifiedHelper(t);
1037760c2415Smrg }
1038760c2415Smrg
visit(TypeInstance * t)1039760c2415Smrg void visit(TypeInstance *t)
1040760c2415Smrg {
1041760c2415Smrg t->tempinst->accept(this);
1042760c2415Smrg visitTypeQualifiedHelper(t);
1043760c2415Smrg }
1044760c2415Smrg
visit(TypeTypeof * t)1045760c2415Smrg void visit(TypeTypeof *t)
1046760c2415Smrg {
1047760c2415Smrg buf->writestring("typeof(");
1048760c2415Smrg t->exp->accept(this);
1049760c2415Smrg buf->writeByte(')');
1050760c2415Smrg visitTypeQualifiedHelper(t);
1051760c2415Smrg }
1052760c2415Smrg
visit(TypeReturn * t)1053760c2415Smrg void visit(TypeReturn *t)
1054760c2415Smrg {
1055760c2415Smrg buf->writestring("typeof(return)");
1056760c2415Smrg visitTypeQualifiedHelper(t);
1057760c2415Smrg }
1058760c2415Smrg
visit(TypeEnum * t)1059760c2415Smrg void visit(TypeEnum *t)
1060760c2415Smrg {
1061760c2415Smrg buf->writestring(t->sym->toChars());
1062760c2415Smrg }
1063760c2415Smrg
visit(TypeStruct * t)1064760c2415Smrg void visit(TypeStruct *t)
1065760c2415Smrg {
1066760c2415Smrg // Bugzilla 13776: Don't use ti->toAlias() to avoid forward reference error
1067760c2415Smrg // while printing messages.
1068760c2415Smrg TemplateInstance *ti = t->sym->parent ? t->sym->parent->isTemplateInstance() : NULL;
1069760c2415Smrg if (ti && ti->aliasdecl == t->sym)
1070760c2415Smrg buf->writestring(hgs->fullQual ? ti->toPrettyChars() : ti->toChars());
1071760c2415Smrg else
1072760c2415Smrg buf->writestring(hgs->fullQual ? t->sym->toPrettyChars() : t->sym->toChars());
1073760c2415Smrg }
1074760c2415Smrg
visit(TypeClass * t)1075760c2415Smrg void visit(TypeClass *t)
1076760c2415Smrg {
1077760c2415Smrg // Bugzilla 13776: Don't use ti->toAlias() to avoid forward reference error
1078760c2415Smrg // while printing messages.
1079760c2415Smrg TemplateInstance *ti = t->sym->parent->isTemplateInstance();
1080760c2415Smrg if (ti && ti->aliasdecl == t->sym)
1081760c2415Smrg buf->writestring(hgs->fullQual ? ti->toPrettyChars() : ti->toChars());
1082760c2415Smrg else
1083760c2415Smrg buf->writestring(hgs->fullQual ? t->sym->toPrettyChars() : t->sym->toChars());
1084760c2415Smrg }
1085760c2415Smrg
visit(TypeTuple * t)1086760c2415Smrg void visit(TypeTuple *t)
1087760c2415Smrg {
1088760c2415Smrg parametersToBuffer(t->arguments, 0);
1089760c2415Smrg }
1090760c2415Smrg
visit(TypeSlice * t)1091760c2415Smrg void visit(TypeSlice *t)
1092760c2415Smrg {
1093760c2415Smrg visitWithMask(t->next, t->mod);
1094760c2415Smrg
1095760c2415Smrg buf->writeByte('[');
1096760c2415Smrg sizeToBuffer(t->lwr);
1097760c2415Smrg buf->writestring(" .. ");
1098760c2415Smrg sizeToBuffer(t->upr);
1099760c2415Smrg buf->writeByte(']');
1100760c2415Smrg }
1101760c2415Smrg
visit(TypeNull *)1102760c2415Smrg void visit(TypeNull *)
1103760c2415Smrg {
1104760c2415Smrg buf->writestring("typeof(null)");
1105760c2415Smrg }
1106760c2415Smrg
1107760c2415Smrg ////////////////////////////////////////////////////////////////////////////
1108760c2415Smrg
visit(Dsymbol * s)1109760c2415Smrg void visit(Dsymbol *s)
1110760c2415Smrg {
1111760c2415Smrg buf->writestring(s->toChars());
1112760c2415Smrg }
1113760c2415Smrg
visit(StaticAssert * s)1114760c2415Smrg void visit(StaticAssert *s)
1115760c2415Smrg {
1116760c2415Smrg buf->writestring(s->kind());
1117760c2415Smrg buf->writeByte('(');
1118760c2415Smrg s->exp->accept(this);
1119760c2415Smrg if (s->msg)
1120760c2415Smrg {
1121760c2415Smrg buf->writestring(", ");
1122760c2415Smrg s->msg->accept(this);
1123760c2415Smrg }
1124760c2415Smrg buf->writestring(");");
1125760c2415Smrg buf->writenl();
1126760c2415Smrg }
1127760c2415Smrg
visit(DebugSymbol * s)1128760c2415Smrg void visit(DebugSymbol *s)
1129760c2415Smrg {
1130760c2415Smrg buf->writestring("debug = ");
1131760c2415Smrg if (s->ident)
1132760c2415Smrg buf->writestring(s->ident->toChars());
1133760c2415Smrg else
1134760c2415Smrg buf->printf("%u", s->level);
1135760c2415Smrg buf->writestring(";");
1136760c2415Smrg buf->writenl();
1137760c2415Smrg }
1138760c2415Smrg
visit(VersionSymbol * s)1139760c2415Smrg void visit(VersionSymbol *s)
1140760c2415Smrg {
1141760c2415Smrg buf->writestring("version = ");
1142760c2415Smrg if (s->ident)
1143760c2415Smrg buf->writestring(s->ident->toChars());
1144760c2415Smrg else
1145760c2415Smrg buf->printf("%u", s->level);
1146760c2415Smrg buf->writestring(";");
1147760c2415Smrg buf->writenl();
1148760c2415Smrg }
1149760c2415Smrg
visit(EnumMember * em)1150760c2415Smrg void visit(EnumMember *em)
1151760c2415Smrg {
1152760c2415Smrg if (em->type)
1153760c2415Smrg typeToBuffer(em->type, em->ident);
1154760c2415Smrg else
1155760c2415Smrg buf->writestring(em->ident->toChars());
1156760c2415Smrg if (em->value())
1157760c2415Smrg {
1158760c2415Smrg buf->writestring(" = ");
1159760c2415Smrg em->value()->accept(this);
1160760c2415Smrg }
1161760c2415Smrg }
1162760c2415Smrg
visit(Import * imp)1163760c2415Smrg void visit(Import *imp)
1164760c2415Smrg {
1165760c2415Smrg if (hgs->hdrgen && imp->id == Id::object)
1166760c2415Smrg return; // object is imported by default
1167760c2415Smrg
1168760c2415Smrg if (imp->isstatic)
1169760c2415Smrg buf->writestring("static ");
1170760c2415Smrg buf->writestring("import ");
1171760c2415Smrg if (imp->aliasId)
1172760c2415Smrg {
1173760c2415Smrg buf->printf("%s = ", imp->aliasId->toChars());
1174760c2415Smrg }
1175760c2415Smrg if (imp->packages && imp->packages->dim)
1176760c2415Smrg {
1177760c2415Smrg for (size_t i = 0; i < imp->packages->dim; i++)
1178760c2415Smrg {
1179760c2415Smrg Identifier *pid = (*imp->packages)[i];
1180760c2415Smrg buf->printf("%s.", pid->toChars());
1181760c2415Smrg }
1182760c2415Smrg }
1183760c2415Smrg buf->printf("%s", imp->id->toChars());
1184760c2415Smrg if (imp->names.dim)
1185760c2415Smrg {
1186760c2415Smrg buf->writestring(" : ");
1187760c2415Smrg for (size_t i = 0; i < imp->names.dim; i++)
1188760c2415Smrg {
1189760c2415Smrg if (i)
1190760c2415Smrg buf->writestring(", ");
1191760c2415Smrg
1192760c2415Smrg Identifier *name = imp->names[i];
1193760c2415Smrg Identifier *alias = imp->aliases[i];
1194760c2415Smrg if (alias)
1195760c2415Smrg buf->printf("%s = %s", alias->toChars(), name->toChars());
1196760c2415Smrg else
1197760c2415Smrg buf->printf("%s", name->toChars());
1198760c2415Smrg }
1199760c2415Smrg }
1200760c2415Smrg buf->printf(";");
1201760c2415Smrg buf->writenl();
1202760c2415Smrg }
1203760c2415Smrg
visit(AliasThis * d)1204760c2415Smrg void visit(AliasThis *d)
1205760c2415Smrg {
1206760c2415Smrg buf->writestring("alias ");
1207760c2415Smrg buf->writestring(d->ident->toChars());
1208760c2415Smrg buf->writestring(" this;\n");
1209760c2415Smrg }
1210760c2415Smrg
visit(AttribDeclaration * d)1211760c2415Smrg void visit(AttribDeclaration *d)
1212760c2415Smrg {
1213760c2415Smrg if (!d->decl)
1214760c2415Smrg {
1215760c2415Smrg buf->writeByte(';');
1216760c2415Smrg buf->writenl();
1217760c2415Smrg return;
1218760c2415Smrg }
1219760c2415Smrg
1220760c2415Smrg if (d->decl->dim == 0)
1221760c2415Smrg buf->writestring("{}");
1222760c2415Smrg else if (hgs->hdrgen && d->decl->dim == 1 && (*d->decl)[0]->isUnitTestDeclaration())
1223760c2415Smrg {
1224760c2415Smrg // hack for bugzilla 8081
1225760c2415Smrg buf->writestring("{}");
1226760c2415Smrg }
1227760c2415Smrg else if (d->decl->dim == 1)
1228760c2415Smrg {
1229760c2415Smrg ((*d->decl)[0])->accept(this);
1230760c2415Smrg return;
1231760c2415Smrg }
1232760c2415Smrg else
1233760c2415Smrg {
1234760c2415Smrg buf->writenl();
1235760c2415Smrg buf->writeByte('{');
1236760c2415Smrg buf->writenl();
1237760c2415Smrg buf->level++;
1238760c2415Smrg for (size_t i = 0; i < d->decl->dim; i++)
1239760c2415Smrg {
1240760c2415Smrg Dsymbol *de = (*d->decl)[i];
1241760c2415Smrg de->accept(this);
1242760c2415Smrg }
1243760c2415Smrg buf->level--;
1244760c2415Smrg buf->writeByte('}');
1245760c2415Smrg }
1246760c2415Smrg buf->writenl();
1247760c2415Smrg }
1248760c2415Smrg
visit(StorageClassDeclaration * d)1249760c2415Smrg void visit(StorageClassDeclaration *d)
1250760c2415Smrg {
1251760c2415Smrg if (stcToBuffer(buf, d->stc))
1252760c2415Smrg buf->writeByte(' ');
1253760c2415Smrg visit((AttribDeclaration *)d);
1254760c2415Smrg }
1255760c2415Smrg
visit(DeprecatedDeclaration * d)1256760c2415Smrg void visit(DeprecatedDeclaration *d)
1257760c2415Smrg {
1258760c2415Smrg buf->writestring("deprecated(");
1259760c2415Smrg d->msg->accept(this);
1260760c2415Smrg buf->writestring(") ");
1261760c2415Smrg visit((AttribDeclaration *)d);
1262760c2415Smrg }
1263760c2415Smrg
visit(LinkDeclaration * d)1264760c2415Smrg void visit(LinkDeclaration *d)
1265760c2415Smrg {
1266760c2415Smrg const char *p;
1267760c2415Smrg
1268760c2415Smrg switch (d->linkage)
1269760c2415Smrg {
1270760c2415Smrg case LINKd: p = "D"; break;
1271760c2415Smrg case LINKc: p = "C"; break;
1272760c2415Smrg case LINKcpp: p = "C++"; break;
1273760c2415Smrg case LINKwindows: p = "Windows"; break;
1274760c2415Smrg case LINKpascal: p = "Pascal"; break;
1275760c2415Smrg case LINKobjc: p = "Objective-C"; break;
1276760c2415Smrg default:
1277760c2415Smrg assert(0);
1278760c2415Smrg break;
1279760c2415Smrg }
1280760c2415Smrg buf->writestring("extern (");
1281760c2415Smrg buf->writestring(p);
1282760c2415Smrg buf->writestring(") ");
1283760c2415Smrg visit((AttribDeclaration *)d);
1284760c2415Smrg }
1285760c2415Smrg
visit(CPPMangleDeclaration * d)1286760c2415Smrg void visit(CPPMangleDeclaration *d)
1287760c2415Smrg {
1288760c2415Smrg const char *p;
1289760c2415Smrg
1290760c2415Smrg switch (d->cppmangle)
1291760c2415Smrg {
1292760c2415Smrg case CPPMANGLEclass: p = "class"; break;
1293760c2415Smrg case CPPMANGLEstruct: p = "struct"; break;
1294760c2415Smrg default:
1295760c2415Smrg assert(0);
1296760c2415Smrg break;
1297760c2415Smrg }
1298760c2415Smrg buf->writestring("extern (C++, ");
1299760c2415Smrg buf->writestring(p);
1300760c2415Smrg buf->writestring(") ");
1301760c2415Smrg visit((AttribDeclaration *)d);
1302760c2415Smrg }
1303760c2415Smrg
visit(ProtDeclaration * d)1304760c2415Smrg void visit(ProtDeclaration *d)
1305760c2415Smrg {
1306760c2415Smrg protectionToBuffer(buf, d->protection);
1307760c2415Smrg buf->writeByte(' ');
1308760c2415Smrg visit((AttribDeclaration *)d);
1309760c2415Smrg }
1310760c2415Smrg
visit(AlignDeclaration * d)1311760c2415Smrg void visit(AlignDeclaration *d)
1312760c2415Smrg {
1313760c2415Smrg if (!d->ealign)
1314760c2415Smrg buf->printf("align ");
1315760c2415Smrg else
1316760c2415Smrg buf->printf("align (%s)", d->ealign->toChars());
1317760c2415Smrg visit((AttribDeclaration *)d);
1318760c2415Smrg }
1319760c2415Smrg
visit(AnonDeclaration * d)1320760c2415Smrg void visit(AnonDeclaration *d)
1321760c2415Smrg {
1322760c2415Smrg buf->printf(d->isunion ? "union" : "struct");
1323760c2415Smrg buf->writenl();
1324760c2415Smrg buf->writestring("{");
1325760c2415Smrg buf->writenl();
1326760c2415Smrg buf->level++;
1327760c2415Smrg if (d->decl)
1328760c2415Smrg {
1329760c2415Smrg for (size_t i = 0; i < d->decl->dim; i++)
1330760c2415Smrg {
1331760c2415Smrg Dsymbol *de = (*d->decl)[i];
1332760c2415Smrg de->accept(this);
1333760c2415Smrg }
1334760c2415Smrg }
1335760c2415Smrg buf->level--;
1336760c2415Smrg buf->writestring("}");
1337760c2415Smrg buf->writenl();
1338760c2415Smrg }
1339760c2415Smrg
visit(PragmaDeclaration * d)1340760c2415Smrg void visit(PragmaDeclaration *d)
1341760c2415Smrg {
1342760c2415Smrg buf->printf("pragma (%s", d->ident->toChars());
1343760c2415Smrg if (d->args && d->args->dim)
1344760c2415Smrg {
1345760c2415Smrg buf->writestring(", ");
1346760c2415Smrg argsToBuffer(d->args);
1347760c2415Smrg }
1348760c2415Smrg buf->writeByte(')');
1349760c2415Smrg visit((AttribDeclaration *)d);
1350760c2415Smrg }
1351760c2415Smrg
visit(ConditionalDeclaration * d)1352760c2415Smrg void visit(ConditionalDeclaration *d)
1353760c2415Smrg {
1354760c2415Smrg d->condition->accept(this);
1355760c2415Smrg if (d->decl || d->elsedecl)
1356760c2415Smrg {
1357760c2415Smrg buf->writenl();
1358760c2415Smrg buf->writeByte('{');
1359760c2415Smrg buf->writenl();
1360760c2415Smrg buf->level++;
1361760c2415Smrg if (d->decl)
1362760c2415Smrg {
1363760c2415Smrg for (size_t i = 0; i < d->decl->dim; i++)
1364760c2415Smrg {
1365760c2415Smrg Dsymbol *de = (*d->decl)[i];
1366760c2415Smrg de->accept(this);
1367760c2415Smrg }
1368760c2415Smrg }
1369760c2415Smrg buf->level--;
1370760c2415Smrg buf->writeByte('}');
1371760c2415Smrg if (d->elsedecl)
1372760c2415Smrg {
1373760c2415Smrg buf->writenl();
1374760c2415Smrg buf->writestring("else");
1375760c2415Smrg buf->writenl();
1376760c2415Smrg buf->writeByte('{');
1377760c2415Smrg buf->writenl();
1378760c2415Smrg buf->level++;
1379760c2415Smrg for (size_t i = 0; i < d->elsedecl->dim; i++)
1380760c2415Smrg {
1381760c2415Smrg Dsymbol *de = (*d->elsedecl)[i];
1382760c2415Smrg de->accept(this);
1383760c2415Smrg }
1384760c2415Smrg buf->level--;
1385760c2415Smrg buf->writeByte('}');
1386760c2415Smrg }
1387760c2415Smrg }
1388760c2415Smrg else
1389760c2415Smrg buf->writeByte(':');
1390760c2415Smrg buf->writenl();
1391760c2415Smrg }
1392760c2415Smrg
visit(ForwardingStatement * s)1393*0bfacb9bSmrg void visit(ForwardingStatement *s)
1394*0bfacb9bSmrg {
1395*0bfacb9bSmrg s->statement->accept(this);
1396*0bfacb9bSmrg }
1397*0bfacb9bSmrg
visit(StaticForeachDeclaration * s)1398*0bfacb9bSmrg void visit(StaticForeachDeclaration *s)
1399*0bfacb9bSmrg {
1400*0bfacb9bSmrg buf->writestring("static ");
1401*0bfacb9bSmrg if (s->sfe->aggrfe)
1402*0bfacb9bSmrg {
1403*0bfacb9bSmrg foreachWithoutBody(s->sfe->aggrfe);
1404*0bfacb9bSmrg }
1405*0bfacb9bSmrg else
1406*0bfacb9bSmrg {
1407*0bfacb9bSmrg assert(s->sfe->rangefe);
1408*0bfacb9bSmrg foreachRangeWithoutBody(s->sfe->rangefe);
1409*0bfacb9bSmrg }
1410*0bfacb9bSmrg buf->writeByte('{');
1411*0bfacb9bSmrg buf->writenl();
1412*0bfacb9bSmrg buf->level++;
1413*0bfacb9bSmrg visit((AttribDeclaration *)s);
1414*0bfacb9bSmrg buf->level--;
1415*0bfacb9bSmrg buf->writeByte('}');
1416*0bfacb9bSmrg buf->writenl();
1417*0bfacb9bSmrg }
1418*0bfacb9bSmrg
visit(CompileDeclaration * d)1419760c2415Smrg void visit(CompileDeclaration *d)
1420760c2415Smrg {
1421760c2415Smrg buf->writestring("mixin(");
1422760c2415Smrg d->exp->accept(this);
1423760c2415Smrg buf->writestring(");");
1424760c2415Smrg buf->writenl();
1425760c2415Smrg }
1426760c2415Smrg
visit(UserAttributeDeclaration * d)1427760c2415Smrg void visit(UserAttributeDeclaration *d)
1428760c2415Smrg {
1429760c2415Smrg buf->writestring("@(");
1430760c2415Smrg argsToBuffer(d->atts);
1431760c2415Smrg buf->writeByte(')');
1432760c2415Smrg visit((AttribDeclaration *)d);
1433760c2415Smrg }
1434760c2415Smrg
visit(TemplateDeclaration * d)1435760c2415Smrg void visit(TemplateDeclaration *d)
1436760c2415Smrg {
1437760c2415Smrg if ((hgs->hdrgen || hgs->fullDump) && visitEponymousMember(d))
1438760c2415Smrg return;
1439760c2415Smrg
1440760c2415Smrg if (hgs->ddoc)
1441760c2415Smrg buf->writestring(d->kind());
1442760c2415Smrg else
1443760c2415Smrg buf->writestring("template");
1444760c2415Smrg buf->writeByte(' ');
1445760c2415Smrg buf->writestring(d->ident->toChars());
1446760c2415Smrg buf->writeByte('(');
1447760c2415Smrg visitTemplateParameters(hgs->ddoc ? d->origParameters : d->parameters);
1448760c2415Smrg buf->writeByte(')');
1449760c2415Smrg visitTemplateConstraint(d->constraint);
1450760c2415Smrg
1451760c2415Smrg if (hgs->hdrgen || hgs->fullDump)
1452760c2415Smrg {
1453760c2415Smrg hgs->tpltMember++;
1454760c2415Smrg buf->writenl();
1455760c2415Smrg buf->writeByte('{');
1456760c2415Smrg buf->writenl();
1457760c2415Smrg buf->level++;
1458760c2415Smrg for (size_t i = 0; i < d->members->dim; i++)
1459760c2415Smrg {
1460760c2415Smrg Dsymbol *s = (*d->members)[i];
1461760c2415Smrg s->accept(this);
1462760c2415Smrg }
1463760c2415Smrg buf->level--;
1464760c2415Smrg buf->writeByte('}');
1465760c2415Smrg buf->writenl();
1466760c2415Smrg hgs->tpltMember--;
1467760c2415Smrg }
1468760c2415Smrg }
1469760c2415Smrg
visitEponymousMember(TemplateDeclaration * d)1470760c2415Smrg bool visitEponymousMember(TemplateDeclaration *d)
1471760c2415Smrg {
1472760c2415Smrg if (!d->members || d->members->dim != 1)
1473760c2415Smrg return false;
1474760c2415Smrg
1475760c2415Smrg Dsymbol *onemember = (*d->members)[0];
1476760c2415Smrg if (onemember->ident != d->ident)
1477760c2415Smrg return false;
1478760c2415Smrg
1479760c2415Smrg if (FuncDeclaration *fd = onemember->isFuncDeclaration())
1480760c2415Smrg {
1481760c2415Smrg assert(fd->type);
1482760c2415Smrg if (stcToBuffer(buf, fd->storage_class))
1483760c2415Smrg buf->writeByte(' ');
1484760c2415Smrg functionToBufferFull((TypeFunction *)fd->type, buf, d->ident, hgs, d);
1485760c2415Smrg visitTemplateConstraint(d->constraint);
1486760c2415Smrg
1487760c2415Smrg hgs->tpltMember++;
1488760c2415Smrg bodyToBuffer(fd);
1489760c2415Smrg hgs->tpltMember--;
1490760c2415Smrg return true;
1491760c2415Smrg }
1492760c2415Smrg if (AggregateDeclaration *ad = onemember->isAggregateDeclaration())
1493760c2415Smrg {
1494760c2415Smrg buf->writestring(ad->kind());
1495760c2415Smrg buf->writeByte(' ');
1496760c2415Smrg buf->writestring(ad->ident->toChars());
1497760c2415Smrg buf->writeByte('(');
1498760c2415Smrg visitTemplateParameters(hgs->ddoc ? d->origParameters : d->parameters);
1499760c2415Smrg buf->writeByte(')');
1500760c2415Smrg visitTemplateConstraint(d->constraint);
1501760c2415Smrg visitBaseClasses(ad->isClassDeclaration());
1502760c2415Smrg
1503760c2415Smrg hgs->tpltMember++;
1504760c2415Smrg if (ad->members)
1505760c2415Smrg {
1506760c2415Smrg buf->writenl();
1507760c2415Smrg buf->writeByte('{');
1508760c2415Smrg buf->writenl();
1509760c2415Smrg buf->level++;
1510760c2415Smrg for (size_t i = 0; i < ad->members->dim; i++)
1511760c2415Smrg {
1512760c2415Smrg Dsymbol *s = (*ad->members)[i];
1513760c2415Smrg s->accept(this);
1514760c2415Smrg }
1515760c2415Smrg buf->level--;
1516760c2415Smrg buf->writeByte('}');
1517760c2415Smrg }
1518760c2415Smrg else
1519760c2415Smrg buf->writeByte(';');
1520760c2415Smrg buf->writenl();
1521760c2415Smrg hgs->tpltMember--;
1522760c2415Smrg return true;
1523760c2415Smrg }
1524760c2415Smrg if (VarDeclaration *vd = onemember->isVarDeclaration())
1525760c2415Smrg {
1526760c2415Smrg if (d->constraint)
1527760c2415Smrg return false;
1528760c2415Smrg
1529760c2415Smrg if (stcToBuffer(buf, vd->storage_class))
1530760c2415Smrg buf->writeByte(' ');
1531760c2415Smrg if (vd->type)
1532760c2415Smrg typeToBuffer(vd->type, vd->ident);
1533760c2415Smrg else
1534760c2415Smrg buf->writestring(vd->ident->toChars());
1535760c2415Smrg
1536760c2415Smrg buf->writeByte('(');
1537760c2415Smrg visitTemplateParameters(hgs->ddoc ? d->origParameters : d->parameters);
1538760c2415Smrg buf->writeByte(')');
1539760c2415Smrg
1540760c2415Smrg if (vd->_init)
1541760c2415Smrg {
1542760c2415Smrg buf->writestring(" = ");
1543760c2415Smrg ExpInitializer *ie = vd->_init->isExpInitializer();
1544760c2415Smrg if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1545760c2415Smrg ((AssignExp *)ie->exp)->e2->accept(this);
1546760c2415Smrg else
1547760c2415Smrg vd->_init->accept(this);
1548760c2415Smrg }
1549760c2415Smrg buf->writeByte(';');
1550760c2415Smrg buf->writenl();
1551760c2415Smrg return true;
1552760c2415Smrg }
1553760c2415Smrg
1554760c2415Smrg return false;
1555760c2415Smrg }
visitTemplateParameters(TemplateParameters * parameters)1556760c2415Smrg void visitTemplateParameters(TemplateParameters *parameters)
1557760c2415Smrg {
1558760c2415Smrg if (!parameters || !parameters->dim)
1559760c2415Smrg return;
1560760c2415Smrg for (size_t i = 0; i < parameters->dim; i++)
1561760c2415Smrg {
1562760c2415Smrg TemplateParameter *p = (*parameters)[i];
1563760c2415Smrg if (i)
1564760c2415Smrg buf->writestring(", ");
1565760c2415Smrg p->accept(this);
1566760c2415Smrg }
1567760c2415Smrg }
visitTemplateConstraint(Expression * constraint)1568760c2415Smrg void visitTemplateConstraint(Expression *constraint)
1569760c2415Smrg {
1570760c2415Smrg if (!constraint)
1571760c2415Smrg return;
1572760c2415Smrg buf->writestring(" if (");
1573760c2415Smrg constraint->accept(this);
1574760c2415Smrg buf->writeByte(')');
1575760c2415Smrg }
1576760c2415Smrg
visit(TemplateInstance * ti)1577760c2415Smrg void visit(TemplateInstance *ti)
1578760c2415Smrg {
1579760c2415Smrg buf->writestring(ti->name->toChars());
1580760c2415Smrg tiargsToBuffer(ti);
1581760c2415Smrg
1582760c2415Smrg if (hgs->fullDump)
1583760c2415Smrg {
1584760c2415Smrg buf->writenl();
1585760c2415Smrg if (ti->aliasdecl)
1586760c2415Smrg {
1587760c2415Smrg // the ti.aliasDecl is the instantiated body
1588760c2415Smrg // if we have it, print it.
1589760c2415Smrg ti->aliasdecl->accept(this);
1590760c2415Smrg }
1591760c2415Smrg }
1592760c2415Smrg }
1593760c2415Smrg
visit(TemplateMixin * tm)1594760c2415Smrg void visit(TemplateMixin *tm)
1595760c2415Smrg {
1596760c2415Smrg buf->writestring("mixin ");
1597760c2415Smrg
1598760c2415Smrg typeToBuffer(tm->tqual, NULL);
1599760c2415Smrg tiargsToBuffer(tm);
1600760c2415Smrg
1601760c2415Smrg if (tm->ident && memcmp(tm->ident->toChars(), "__mixin", 7) != 0)
1602760c2415Smrg {
1603760c2415Smrg buf->writeByte(' ');
1604760c2415Smrg buf->writestring(tm->ident->toChars());
1605760c2415Smrg }
1606760c2415Smrg buf->writeByte(';');
1607760c2415Smrg buf->writenl();
1608760c2415Smrg }
1609760c2415Smrg
tiargsToBuffer(TemplateInstance * ti)1610760c2415Smrg void tiargsToBuffer(TemplateInstance *ti)
1611760c2415Smrg {
1612760c2415Smrg buf->writeByte('!');
1613760c2415Smrg if (ti->nest)
1614760c2415Smrg {
1615760c2415Smrg buf->writestring("(...)");
1616760c2415Smrg return;
1617760c2415Smrg }
1618760c2415Smrg if (!ti->tiargs)
1619760c2415Smrg {
1620760c2415Smrg buf->writestring("()");
1621760c2415Smrg return;
1622760c2415Smrg }
1623760c2415Smrg
1624760c2415Smrg if (ti->tiargs->dim == 1)
1625760c2415Smrg {
1626760c2415Smrg RootObject *oarg = (*ti->tiargs)[0];
1627760c2415Smrg if (Type *t = isType(oarg))
1628760c2415Smrg {
1629760c2415Smrg if (t->equals(Type::tstring) ||
1630760c2415Smrg t->equals(Type::twstring) ||
1631760c2415Smrg t->equals(Type::tdstring) ||
1632760c2415Smrg (t->mod == 0 &&
1633760c2415Smrg (t->isTypeBasic() ||
1634760c2415Smrg (t->ty == Tident && ((TypeIdentifier *)t)->idents.dim == 0))))
1635760c2415Smrg {
1636760c2415Smrg buf->writestring(t->toChars());
1637760c2415Smrg return;
1638760c2415Smrg }
1639760c2415Smrg }
1640760c2415Smrg else if (Expression *e = isExpression(oarg))
1641760c2415Smrg {
1642760c2415Smrg if (e->op == TOKint64 ||
1643760c2415Smrg e->op == TOKfloat64 ||
1644760c2415Smrg e->op == TOKnull ||
1645760c2415Smrg e->op == TOKstring ||
1646760c2415Smrg e->op == TOKthis)
1647760c2415Smrg {
1648760c2415Smrg buf->writestring(e->toChars());
1649760c2415Smrg return;
1650760c2415Smrg }
1651760c2415Smrg }
1652760c2415Smrg }
1653760c2415Smrg buf->writeByte('(');
1654760c2415Smrg ti->nest++;
1655760c2415Smrg for (size_t i = 0; i < ti->tiargs->dim; i++)
1656760c2415Smrg {
1657760c2415Smrg RootObject *arg = (*ti->tiargs)[i];
1658760c2415Smrg if (i)
1659760c2415Smrg buf->writestring(", ");
1660760c2415Smrg objectToBuffer(arg);
1661760c2415Smrg }
1662760c2415Smrg ti->nest--;
1663760c2415Smrg buf->writeByte(')');
1664760c2415Smrg }
1665760c2415Smrg
1666760c2415Smrg /****************************************
1667760c2415Smrg * This makes a 'pretty' version of the template arguments.
1668760c2415Smrg * It's analogous to genIdent() which makes a mangled version.
1669760c2415Smrg */
objectToBuffer(RootObject * oarg)1670760c2415Smrg void objectToBuffer(RootObject *oarg)
1671760c2415Smrg {
1672760c2415Smrg //printf("objectToBuffer()\n");
1673760c2415Smrg
1674760c2415Smrg /* The logic of this should match what genIdent() does. The _dynamic_cast()
1675760c2415Smrg * function relies on all the pretty strings to be unique for different classes
1676760c2415Smrg * (see Bugzilla 7375).
1677760c2415Smrg * Perhaps it would be better to demangle what genIdent() does.
1678760c2415Smrg */
1679760c2415Smrg if (Type *t = isType(oarg))
1680760c2415Smrg {
1681760c2415Smrg //printf("\tt: %s ty = %d\n", t->toChars(), t->ty);
1682760c2415Smrg typeToBuffer(t, NULL);
1683760c2415Smrg }
1684760c2415Smrg else if (Expression *e = isExpression(oarg))
1685760c2415Smrg {
1686760c2415Smrg if (e->op == TOKvar)
1687760c2415Smrg e = e->optimize(WANTvalue); // added to fix Bugzilla 7375
1688760c2415Smrg e->accept(this);
1689760c2415Smrg }
1690760c2415Smrg else if (Dsymbol *s = isDsymbol(oarg))
1691760c2415Smrg {
1692760c2415Smrg const char *p = s->ident ? s->ident->toChars() : s->toChars();
1693760c2415Smrg buf->writestring(p);
1694760c2415Smrg }
1695760c2415Smrg else if (Tuple *v = isTuple(oarg))
1696760c2415Smrg {
1697760c2415Smrg Objects *args = &v->objects;
1698760c2415Smrg for (size_t i = 0; i < args->dim; i++)
1699760c2415Smrg {
1700760c2415Smrg RootObject *arg = (*args)[i];
1701760c2415Smrg if (i)
1702760c2415Smrg buf->writestring(", ");
1703760c2415Smrg objectToBuffer(arg);
1704760c2415Smrg }
1705760c2415Smrg }
1706760c2415Smrg else if (!oarg)
1707760c2415Smrg {
1708760c2415Smrg buf->writestring("NULL");
1709760c2415Smrg }
1710760c2415Smrg else
1711760c2415Smrg {
1712760c2415Smrg assert(0);
1713760c2415Smrg }
1714760c2415Smrg }
1715760c2415Smrg
visit(EnumDeclaration * d)1716760c2415Smrg void visit(EnumDeclaration *d)
1717760c2415Smrg {
1718760c2415Smrg EnumDeclaration *oldInEnumDecl = inEnumDecl;
1719760c2415Smrg inEnumDecl = d;
1720760c2415Smrg buf->writestring("enum ");
1721760c2415Smrg if (d->ident)
1722760c2415Smrg {
1723760c2415Smrg buf->writestring(d->ident->toChars());
1724760c2415Smrg buf->writeByte(' ');
1725760c2415Smrg }
1726760c2415Smrg if (d->memtype)
1727760c2415Smrg {
1728760c2415Smrg buf->writestring(": ");
1729760c2415Smrg typeToBuffer(d->memtype, NULL);
1730760c2415Smrg }
1731760c2415Smrg if (!d->members)
1732760c2415Smrg {
1733760c2415Smrg buf->writeByte(';');
1734760c2415Smrg buf->writenl();
1735760c2415Smrg inEnumDecl = oldInEnumDecl;
1736760c2415Smrg return;
1737760c2415Smrg }
1738760c2415Smrg buf->writenl();
1739760c2415Smrg buf->writeByte('{');
1740760c2415Smrg buf->writenl();
1741760c2415Smrg buf->level++;
1742760c2415Smrg for (size_t i = 0; i < d->members->dim; i++)
1743760c2415Smrg {
1744760c2415Smrg EnumMember *em = (*d->members)[i]->isEnumMember();
1745760c2415Smrg if (!em)
1746760c2415Smrg continue;
1747760c2415Smrg em->accept(this);
1748760c2415Smrg buf->writeByte(',');
1749760c2415Smrg buf->writenl();
1750760c2415Smrg }
1751760c2415Smrg buf->level--;
1752760c2415Smrg buf->writeByte('}');
1753760c2415Smrg buf->writenl();
1754760c2415Smrg inEnumDecl = oldInEnumDecl;
1755760c2415Smrg }
1756760c2415Smrg
visit(Nspace * d)1757760c2415Smrg void visit(Nspace *d)
1758760c2415Smrg {
1759760c2415Smrg buf->writestring("extern (C++, ");
1760760c2415Smrg buf->writestring(d->ident->toChars());
1761760c2415Smrg buf->writeByte(')');
1762760c2415Smrg buf->writenl();
1763760c2415Smrg buf->writeByte('{');
1764760c2415Smrg buf->writenl();
1765760c2415Smrg buf->level++;
1766760c2415Smrg for (size_t i = 0; i < d->members->dim; i++)
1767760c2415Smrg {
1768760c2415Smrg Dsymbol *s = (*d->members)[i];
1769760c2415Smrg s->accept(this);
1770760c2415Smrg }
1771760c2415Smrg buf->level--;
1772760c2415Smrg buf->writeByte('}');
1773760c2415Smrg buf->writenl();
1774760c2415Smrg }
1775760c2415Smrg
visit(StructDeclaration * d)1776760c2415Smrg void visit(StructDeclaration *d)
1777760c2415Smrg {
1778760c2415Smrg buf->printf("%s ", d->kind());
1779760c2415Smrg if (!d->isAnonymous())
1780760c2415Smrg buf->writestring(d->toChars());
1781760c2415Smrg if (!d->members)
1782760c2415Smrg {
1783760c2415Smrg buf->writeByte(';');
1784760c2415Smrg buf->writenl();
1785760c2415Smrg return;
1786760c2415Smrg }
1787760c2415Smrg buf->writenl();
1788760c2415Smrg buf->writeByte('{');
1789760c2415Smrg buf->writenl();
1790760c2415Smrg buf->level++;
1791760c2415Smrg for (size_t i = 0; i < d->members->dim; i++)
1792760c2415Smrg {
1793760c2415Smrg Dsymbol *s = (*d->members)[i];
1794760c2415Smrg s->accept(this);
1795760c2415Smrg }
1796760c2415Smrg buf->level--;
1797760c2415Smrg buf->writeByte('}');
1798760c2415Smrg buf->writenl();
1799760c2415Smrg }
1800760c2415Smrg
visit(ClassDeclaration * d)1801760c2415Smrg void visit(ClassDeclaration *d)
1802760c2415Smrg {
1803760c2415Smrg if (!d->isAnonymous())
1804760c2415Smrg {
1805760c2415Smrg buf->writestring(d->kind());
1806760c2415Smrg buf->writeByte(' ');
1807760c2415Smrg buf->writestring(d->ident->toChars());
1808760c2415Smrg }
1809760c2415Smrg visitBaseClasses(d);
1810760c2415Smrg if (d->members)
1811760c2415Smrg {
1812760c2415Smrg buf->writenl();
1813760c2415Smrg buf->writeByte('{');
1814760c2415Smrg buf->writenl();
1815760c2415Smrg buf->level++;
1816760c2415Smrg for (size_t i = 0; i < d->members->dim; i++)
1817760c2415Smrg {
1818760c2415Smrg Dsymbol *s = (*d->members)[i];
1819760c2415Smrg s->accept(this);
1820760c2415Smrg }
1821760c2415Smrg buf->level--;
1822760c2415Smrg buf->writeByte('}');
1823760c2415Smrg }
1824760c2415Smrg else
1825760c2415Smrg buf->writeByte(';');
1826760c2415Smrg buf->writenl();
1827760c2415Smrg }
1828760c2415Smrg
visitBaseClasses(ClassDeclaration * d)1829760c2415Smrg void visitBaseClasses(ClassDeclaration *d)
1830760c2415Smrg {
1831760c2415Smrg if (!d || !d->baseclasses->dim)
1832760c2415Smrg return;
1833760c2415Smrg
1834760c2415Smrg buf->writestring(" : ");
1835760c2415Smrg for (size_t i = 0; i < d->baseclasses->dim; i++)
1836760c2415Smrg {
1837760c2415Smrg if (i)
1838760c2415Smrg buf->writestring(", ");
1839760c2415Smrg BaseClass *b = (*d->baseclasses)[i];
1840760c2415Smrg typeToBuffer(b->type, NULL);
1841760c2415Smrg }
1842760c2415Smrg }
1843760c2415Smrg
visit(AliasDeclaration * d)1844760c2415Smrg void visit(AliasDeclaration *d)
1845760c2415Smrg {
1846*0bfacb9bSmrg if (d->storage_class & STClocal)
1847*0bfacb9bSmrg return;
1848760c2415Smrg buf->writestring("alias ");
1849760c2415Smrg if (d->aliassym)
1850760c2415Smrg {
1851760c2415Smrg buf->writestring(d->ident->toChars());
1852760c2415Smrg buf->writestring(" = ");
1853760c2415Smrg if (stcToBuffer(buf, d->storage_class))
1854760c2415Smrg buf->writeByte(' ');
1855760c2415Smrg d->aliassym->accept(this);
1856760c2415Smrg }
1857760c2415Smrg else if (d->type->ty == Tfunction)
1858760c2415Smrg {
1859760c2415Smrg if (stcToBuffer(buf, d->storage_class))
1860760c2415Smrg buf->writeByte(' ');
1861760c2415Smrg typeToBuffer(d->type, d->ident);
1862760c2415Smrg }
1863760c2415Smrg else
1864760c2415Smrg {
1865760c2415Smrg declstring = (d->ident == Id::string || d->ident == Id::wstring || d->ident == Id::dstring);
1866760c2415Smrg buf->writestring(d->ident->toChars());
1867760c2415Smrg buf->writestring(" = ");
1868760c2415Smrg if (stcToBuffer(buf, d->storage_class))
1869760c2415Smrg buf->writeByte(' ');
1870760c2415Smrg typeToBuffer(d->type, NULL);
1871760c2415Smrg declstring = false;
1872760c2415Smrg }
1873760c2415Smrg buf->writeByte(';');
1874760c2415Smrg buf->writenl();
1875760c2415Smrg }
1876760c2415Smrg
visit(VarDeclaration * d)1877760c2415Smrg void visit(VarDeclaration *d)
1878760c2415Smrg {
1879*0bfacb9bSmrg if (d->storage_class & STClocal)
1880*0bfacb9bSmrg return;
1881760c2415Smrg visitVarDecl(d, false);
1882760c2415Smrg buf->writeByte(';');
1883760c2415Smrg buf->writenl();
1884760c2415Smrg }
visitVarDecl(VarDeclaration * v,bool anywritten)1885760c2415Smrg void visitVarDecl(VarDeclaration *v, bool anywritten)
1886760c2415Smrg {
1887760c2415Smrg if (anywritten)
1888760c2415Smrg {
1889760c2415Smrg buf->writestring(", ");
1890760c2415Smrg buf->writestring(v->ident->toChars());
1891760c2415Smrg }
1892760c2415Smrg else
1893760c2415Smrg {
1894760c2415Smrg if (stcToBuffer(buf, v->storage_class))
1895760c2415Smrg buf->writeByte(' ');
1896760c2415Smrg if (v->type)
1897760c2415Smrg typeToBuffer(v->type, v->ident);
1898760c2415Smrg else
1899760c2415Smrg buf->writestring(v->ident->toChars());
1900760c2415Smrg }
1901760c2415Smrg if (v->_init)
1902760c2415Smrg {
1903760c2415Smrg buf->writestring(" = ");
1904760c2415Smrg ExpInitializer *ie = v->_init->isExpInitializer();
1905760c2415Smrg if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
1906760c2415Smrg ((AssignExp *)ie->exp)->e2->accept(this);
1907760c2415Smrg else
1908760c2415Smrg v->_init->accept(this);
1909760c2415Smrg }
1910760c2415Smrg }
1911760c2415Smrg
visit(FuncDeclaration * f)1912760c2415Smrg void visit(FuncDeclaration *f)
1913760c2415Smrg {
1914760c2415Smrg //printf("FuncDeclaration::toCBuffer() '%s'\n", f->toChars());
1915760c2415Smrg
1916760c2415Smrg if (stcToBuffer(buf, f->storage_class))
1917760c2415Smrg buf->writeByte(' ');
1918760c2415Smrg TypeFunction *tf = (TypeFunction *)f->type;
1919760c2415Smrg typeToBuffer(tf, f->ident);
1920760c2415Smrg if (hgs->hdrgen)
1921760c2415Smrg {
1922760c2415Smrg // if the return type is missing (e.g. ref functions or auto)
1923760c2415Smrg if (!tf->next || f->storage_class & STCauto)
1924760c2415Smrg {
1925760c2415Smrg hgs->autoMember++;
1926760c2415Smrg bodyToBuffer(f);
1927760c2415Smrg hgs->autoMember--;
1928760c2415Smrg }
1929760c2415Smrg else if (hgs->tpltMember == 0 && global.params.hdrStripPlainFunctions)
1930760c2415Smrg {
1931760c2415Smrg buf->writeByte(';');
1932760c2415Smrg buf->writenl();
1933760c2415Smrg }
1934760c2415Smrg else
1935760c2415Smrg bodyToBuffer(f);
1936760c2415Smrg }
1937760c2415Smrg else
1938760c2415Smrg bodyToBuffer(f);
1939760c2415Smrg }
1940760c2415Smrg
bodyToBuffer(FuncDeclaration * f)1941760c2415Smrg void bodyToBuffer(FuncDeclaration *f)
1942760c2415Smrg {
1943760c2415Smrg if (!f->fbody || (hgs->hdrgen && global.params.hdrStripPlainFunctions && !hgs->autoMember && !hgs->tpltMember))
1944760c2415Smrg {
1945760c2415Smrg buf->writeByte(';');
1946760c2415Smrg buf->writenl();
1947760c2415Smrg return;
1948760c2415Smrg }
1949760c2415Smrg
1950760c2415Smrg int savetlpt = hgs->tpltMember;
1951760c2415Smrg int saveauto = hgs->autoMember;
1952760c2415Smrg hgs->tpltMember = 0;
1953760c2415Smrg hgs->autoMember = 0;
1954760c2415Smrg
1955760c2415Smrg buf->writenl();
1956760c2415Smrg
1957760c2415Smrg // in{}
1958760c2415Smrg if (f->frequire)
1959760c2415Smrg {
1960760c2415Smrg buf->writestring("in");
1961760c2415Smrg buf->writenl();
1962760c2415Smrg f->frequire->accept(this);
1963760c2415Smrg }
1964760c2415Smrg
1965760c2415Smrg // out{}
1966760c2415Smrg if (f->fensure)
1967760c2415Smrg {
1968760c2415Smrg buf->writestring("out");
1969760c2415Smrg if (f->outId)
1970760c2415Smrg {
1971760c2415Smrg buf->writeByte('(');
1972760c2415Smrg buf->writestring(f->outId->toChars());
1973760c2415Smrg buf->writeByte(')');
1974760c2415Smrg }
1975760c2415Smrg buf->writenl();
1976760c2415Smrg f->fensure->accept(this);
1977760c2415Smrg }
1978760c2415Smrg
1979760c2415Smrg if (f->frequire || f->fensure)
1980760c2415Smrg {
1981760c2415Smrg buf->writestring("body");
1982760c2415Smrg buf->writenl();
1983760c2415Smrg }
1984760c2415Smrg
1985760c2415Smrg buf->writeByte('{');
1986760c2415Smrg buf->writenl();
1987760c2415Smrg buf->level++;
1988760c2415Smrg f->fbody->accept(this);
1989760c2415Smrg buf->level--;
1990760c2415Smrg buf->writeByte('}');
1991760c2415Smrg buf->writenl();
1992760c2415Smrg
1993760c2415Smrg hgs->tpltMember = savetlpt;
1994760c2415Smrg hgs->autoMember = saveauto;
1995760c2415Smrg }
1996760c2415Smrg
visit(FuncLiteralDeclaration * f)1997760c2415Smrg void visit(FuncLiteralDeclaration *f)
1998760c2415Smrg {
1999760c2415Smrg if (f->type->ty == Terror)
2000760c2415Smrg {
2001760c2415Smrg buf->writestring("__error");
2002760c2415Smrg return;
2003760c2415Smrg }
2004760c2415Smrg
2005760c2415Smrg if (f->tok != TOKreserved)
2006760c2415Smrg {
2007760c2415Smrg buf->writestring(f->kind());
2008760c2415Smrg buf->writeByte(' ');
2009760c2415Smrg }
2010760c2415Smrg
2011760c2415Smrg TypeFunction *tf = (TypeFunction *)f->type;
2012760c2415Smrg // Don't print tf->mod, tf->trust, and tf->linkage
2013760c2415Smrg if (!f->inferRetType && tf->next)
2014760c2415Smrg typeToBuffer(tf->next, NULL);
2015760c2415Smrg parametersToBuffer(tf->parameters, tf->varargs);
2016760c2415Smrg
2017760c2415Smrg CompoundStatement *cs = f->fbody->isCompoundStatement();
2018760c2415Smrg Statement *s1;
2019760c2415Smrg if (f->semanticRun >= PASSsemantic3done && cs)
2020760c2415Smrg {
2021760c2415Smrg s1 = (*cs->statements)[cs->statements->dim - 1];
2022760c2415Smrg }
2023760c2415Smrg else
2024760c2415Smrg s1 = !cs ? f->fbody : NULL;
2025760c2415Smrg ReturnStatement *rs = s1 ? s1->isReturnStatement() : NULL;
2026760c2415Smrg if (rs && rs->exp)
2027760c2415Smrg {
2028760c2415Smrg buf->writestring(" => ");
2029760c2415Smrg rs->exp->accept(this);
2030760c2415Smrg }
2031760c2415Smrg else
2032760c2415Smrg {
2033760c2415Smrg hgs->tpltMember++;
2034760c2415Smrg bodyToBuffer(f);
2035760c2415Smrg hgs->tpltMember--;
2036760c2415Smrg }
2037760c2415Smrg }
2038760c2415Smrg
visit(PostBlitDeclaration * d)2039760c2415Smrg void visit(PostBlitDeclaration *d)
2040760c2415Smrg {
2041760c2415Smrg if (stcToBuffer(buf, d->storage_class))
2042760c2415Smrg buf->writeByte(' ');
2043760c2415Smrg buf->writestring("this(this)");
2044760c2415Smrg bodyToBuffer(d);
2045760c2415Smrg }
2046760c2415Smrg
visit(DtorDeclaration * d)2047760c2415Smrg void visit(DtorDeclaration *d)
2048760c2415Smrg {
2049760c2415Smrg if (d->storage_class & STCtrusted)
2050760c2415Smrg buf->writestring("@trusted ");
2051760c2415Smrg if (d->storage_class & STCsafe)
2052760c2415Smrg buf->writestring("@safe ");
2053760c2415Smrg if (d->storage_class & STCnogc)
2054760c2415Smrg buf->writestring("@nogc ");
2055760c2415Smrg if (d->storage_class & STCdisable)
2056760c2415Smrg buf->writestring("@disable ");
2057760c2415Smrg
2058760c2415Smrg buf->writestring("~this()");
2059760c2415Smrg bodyToBuffer(d);
2060760c2415Smrg }
2061760c2415Smrg
visit(StaticCtorDeclaration * d)2062760c2415Smrg void visit(StaticCtorDeclaration *d)
2063760c2415Smrg {
2064760c2415Smrg if (stcToBuffer(buf, d->storage_class & ~STCstatic))
2065760c2415Smrg buf->writeByte(' ');
2066760c2415Smrg if (d->isSharedStaticCtorDeclaration())
2067760c2415Smrg buf->writestring("shared ");
2068760c2415Smrg buf->writestring("static this()");
2069760c2415Smrg if (hgs->hdrgen && !hgs->tpltMember)
2070760c2415Smrg {
2071760c2415Smrg buf->writeByte(';');
2072760c2415Smrg buf->writenl();
2073760c2415Smrg }
2074760c2415Smrg else
2075760c2415Smrg bodyToBuffer(d);
2076760c2415Smrg }
2077760c2415Smrg
visit(StaticDtorDeclaration * d)2078760c2415Smrg void visit(StaticDtorDeclaration *d)
2079760c2415Smrg {
2080760c2415Smrg if (hgs->hdrgen)
2081760c2415Smrg return;
2082760c2415Smrg if (stcToBuffer(buf, d->storage_class & ~STCstatic))
2083760c2415Smrg buf->writeByte(' ');
2084760c2415Smrg if (d->isSharedStaticDtorDeclaration())
2085760c2415Smrg buf->writestring("shared ");
2086760c2415Smrg buf->writestring("static ~this()");
2087760c2415Smrg bodyToBuffer(d);
2088760c2415Smrg }
2089760c2415Smrg
visit(InvariantDeclaration * d)2090760c2415Smrg void visit(InvariantDeclaration *d)
2091760c2415Smrg {
2092760c2415Smrg if (hgs->hdrgen)
2093760c2415Smrg return;
2094760c2415Smrg if (stcToBuffer(buf, d->storage_class))
2095760c2415Smrg buf->writeByte(' ');
2096760c2415Smrg buf->writestring("invariant");
2097760c2415Smrg bodyToBuffer(d);
2098760c2415Smrg }
2099760c2415Smrg
visit(UnitTestDeclaration * d)2100760c2415Smrg void visit(UnitTestDeclaration *d)
2101760c2415Smrg {
2102760c2415Smrg if (hgs->hdrgen)
2103760c2415Smrg return;
2104760c2415Smrg if (stcToBuffer(buf, d->storage_class))
2105760c2415Smrg buf->writeByte(' ');
2106760c2415Smrg buf->writestring("unittest");
2107760c2415Smrg bodyToBuffer(d);
2108760c2415Smrg }
2109760c2415Smrg
visit(NewDeclaration * d)2110760c2415Smrg void visit(NewDeclaration *d)
2111760c2415Smrg {
2112760c2415Smrg if (stcToBuffer(buf, d->storage_class & ~STCstatic))
2113760c2415Smrg buf->writeByte(' ');
2114760c2415Smrg buf->writestring("new");
2115760c2415Smrg parametersToBuffer(d->parameters, d->varargs);
2116760c2415Smrg bodyToBuffer(d);
2117760c2415Smrg }
2118760c2415Smrg
visit(DeleteDeclaration * d)2119760c2415Smrg void visit(DeleteDeclaration *d)
2120760c2415Smrg {
2121760c2415Smrg if (stcToBuffer(buf, d->storage_class & ~STCstatic))
2122760c2415Smrg buf->writeByte(' ');
2123760c2415Smrg buf->writestring("delete");
2124760c2415Smrg parametersToBuffer(d->parameters, 0);
2125760c2415Smrg bodyToBuffer(d);
2126760c2415Smrg }
2127760c2415Smrg
2128760c2415Smrg ////////////////////////////////////////////////////////////////////////////
2129760c2415Smrg
visit(ErrorInitializer *)2130760c2415Smrg void visit(ErrorInitializer *)
2131760c2415Smrg {
2132760c2415Smrg buf->writestring("__error__");
2133760c2415Smrg }
2134760c2415Smrg
visit(VoidInitializer *)2135760c2415Smrg void visit(VoidInitializer *)
2136760c2415Smrg {
2137760c2415Smrg buf->writestring("void");
2138760c2415Smrg }
2139760c2415Smrg
visit(StructInitializer * si)2140760c2415Smrg void visit(StructInitializer *si)
2141760c2415Smrg {
2142760c2415Smrg //printf("StructInitializer::toCBuffer()\n");
2143760c2415Smrg buf->writeByte('{');
2144760c2415Smrg for (size_t i = 0; i < si->field.dim; i++)
2145760c2415Smrg {
2146760c2415Smrg if (i)
2147760c2415Smrg buf->writestring(", ");
2148760c2415Smrg if (Identifier *id = si->field[i])
2149760c2415Smrg {
2150760c2415Smrg buf->writestring(id->toChars());
2151760c2415Smrg buf->writeByte(':');
2152760c2415Smrg }
2153760c2415Smrg if (Initializer *iz = si->value[i])
2154760c2415Smrg iz->accept(this);
2155760c2415Smrg }
2156760c2415Smrg buf->writeByte('}');
2157760c2415Smrg }
2158760c2415Smrg
visit(ArrayInitializer * ai)2159760c2415Smrg void visit(ArrayInitializer *ai)
2160760c2415Smrg {
2161760c2415Smrg buf->writeByte('[');
2162760c2415Smrg for (size_t i = 0; i < ai->index.dim; i++)
2163760c2415Smrg {
2164760c2415Smrg if (i)
2165760c2415Smrg buf->writestring(", ");
2166760c2415Smrg if (Expression *ex = ai->index[i])
2167760c2415Smrg {
2168760c2415Smrg ex->accept(this);
2169760c2415Smrg buf->writeByte(':');
2170760c2415Smrg }
2171760c2415Smrg if (Initializer *iz = ai->value[i])
2172760c2415Smrg iz->accept(this);
2173760c2415Smrg }
2174760c2415Smrg buf->writeByte(']');
2175760c2415Smrg }
2176760c2415Smrg
visit(ExpInitializer * ei)2177760c2415Smrg void visit(ExpInitializer *ei)
2178760c2415Smrg {
2179760c2415Smrg ei->exp->accept(this);
2180760c2415Smrg }
2181760c2415Smrg
2182760c2415Smrg ////////////////////////////////////////////////////////////////////////////
2183760c2415Smrg
2184760c2415Smrg /**************************************************
2185760c2415Smrg * Write out argument list to buf.
2186760c2415Smrg */
2187760c2415Smrg void argsToBuffer(Expressions *expressions, Expression *basis = NULL)
2188760c2415Smrg {
2189760c2415Smrg if (!expressions || !expressions->dim)
2190760c2415Smrg return;
2191760c2415Smrg
2192760c2415Smrg for (size_t i = 0; i < expressions->dim; i++)
2193760c2415Smrg {
2194760c2415Smrg Expression *el = (*expressions)[i];
2195760c2415Smrg if (i)
2196760c2415Smrg buf->writestring(", ");
2197760c2415Smrg if (!el)
2198760c2415Smrg el = basis;
2199760c2415Smrg if (el)
2200760c2415Smrg expToBuffer(el, PREC_assign);
2201760c2415Smrg }
2202760c2415Smrg }
2203760c2415Smrg
sizeToBuffer(Expression * e)2204760c2415Smrg void sizeToBuffer(Expression *e)
2205760c2415Smrg {
2206760c2415Smrg if (e->type == Type::tsize_t)
2207760c2415Smrg {
2208760c2415Smrg Expression *ex = (e->op == TOKcast ? ((CastExp *)e)->e1 : e);
2209760c2415Smrg ex = ex->optimize(WANTvalue);
2210760c2415Smrg
2211760c2415Smrg dinteger_t uval = ex->op == TOKint64 ? ex->toInteger() : (dinteger_t)-1;
2212760c2415Smrg if ((sinteger_t)uval >= 0)
2213760c2415Smrg {
2214760c2415Smrg dinteger_t sizemax;
2215*0bfacb9bSmrg if (Target::ptrsize == 8)
2216760c2415Smrg sizemax = 0xFFFFFFFFFFFFFFFFULL;
2217*0bfacb9bSmrg else if (Target::ptrsize == 4)
2218*0bfacb9bSmrg sizemax = 0xFFFFFFFFUL;
2219*0bfacb9bSmrg else if (Target::ptrsize == 2)
2220*0bfacb9bSmrg sizemax = 0xFFFFUL;
2221760c2415Smrg else
2222760c2415Smrg assert(0);
2223760c2415Smrg if (uval <= sizemax && uval <= 0x7FFFFFFFFFFFFFFFULL)
2224760c2415Smrg {
2225760c2415Smrg buf->printf("%llu", uval);
2226760c2415Smrg return;
2227760c2415Smrg }
2228760c2415Smrg }
2229760c2415Smrg }
2230760c2415Smrg expToBuffer(e, PREC_assign);
2231760c2415Smrg }
2232760c2415Smrg
2233760c2415Smrg /**************************************************
2234760c2415Smrg * Write expression out to buf, but wrap it
2235760c2415Smrg * in ( ) if its precedence is less than pr.
2236760c2415Smrg */
expToBuffer(Expression * e,PREC pr)2237760c2415Smrg void expToBuffer(Expression *e, PREC pr)
2238760c2415Smrg {
2239760c2415Smrg assert(precedence[e->op] != PREC_zero);
2240760c2415Smrg assert(pr != PREC_zero);
2241760c2415Smrg
2242760c2415Smrg //if (precedence[e->op] == 0) e->print();
2243760c2415Smrg /* Despite precedence, we don't allow a<b<c expressions.
2244760c2415Smrg * They must be parenthesized.
2245760c2415Smrg */
2246760c2415Smrg if (precedence[e->op] < pr ||
2247760c2415Smrg (pr == PREC_rel && precedence[e->op] == pr))
2248760c2415Smrg {
2249760c2415Smrg buf->writeByte('(');
2250760c2415Smrg e->accept(this);
2251760c2415Smrg buf->writeByte(')');
2252760c2415Smrg }
2253760c2415Smrg else
2254760c2415Smrg e->accept(this);
2255760c2415Smrg }
2256760c2415Smrg
visit(Expression * e)2257760c2415Smrg void visit(Expression *e)
2258760c2415Smrg {
2259760c2415Smrg buf->writestring(Token::toChars(e->op));
2260760c2415Smrg }
2261760c2415Smrg
visit(IntegerExp * e)2262760c2415Smrg void visit(IntegerExp *e)
2263760c2415Smrg {
2264760c2415Smrg dinteger_t v = e->toInteger();
2265760c2415Smrg
2266760c2415Smrg if (e->type)
2267760c2415Smrg {
2268760c2415Smrg Type *t = e->type;
2269760c2415Smrg L1:
2270760c2415Smrg switch (t->ty)
2271760c2415Smrg {
2272760c2415Smrg case Tenum:
2273760c2415Smrg {
2274760c2415Smrg TypeEnum *te = (TypeEnum *)t;
2275760c2415Smrg if (hgs->fullDump)
2276760c2415Smrg {
2277760c2415Smrg EnumDeclaration *sym = te->sym;
2278760c2415Smrg if (inEnumDecl != sym)
2279760c2415Smrg {
2280760c2415Smrg for (size_t i = 0; i < sym->members->dim; i++)
2281760c2415Smrg {
2282760c2415Smrg EnumMember *em = (EnumMember *)(*sym->members)[i];
2283760c2415Smrg if (em->value()->toInteger() == v)
2284760c2415Smrg {
2285760c2415Smrg buf->printf("%s.%s", sym->toChars(), em->ident->toChars());
2286760c2415Smrg return;
2287760c2415Smrg }
2288760c2415Smrg }
2289760c2415Smrg }
2290760c2415Smrg }
2291760c2415Smrg buf->printf("cast(%s)", te->sym->toChars());
2292760c2415Smrg t = te->sym->memtype;
2293760c2415Smrg goto L1;
2294760c2415Smrg }
2295760c2415Smrg
2296760c2415Smrg case Twchar: // BUG: need to cast(wchar)
2297760c2415Smrg case Tdchar: // BUG: need to cast(dchar)
2298760c2415Smrg if ((uinteger_t)v > 0xFF)
2299760c2415Smrg {
2300760c2415Smrg buf->printf("'\\U%08x'", v);
2301760c2415Smrg break;
2302760c2415Smrg }
2303760c2415Smrg /* fall through */
2304760c2415Smrg case Tchar:
2305760c2415Smrg {
2306760c2415Smrg size_t o = buf->offset;
2307760c2415Smrg if (v == '\'')
2308760c2415Smrg buf->writestring("'\\''");
2309760c2415Smrg else if (isprint((int)v) && v != '\\')
2310760c2415Smrg buf->printf("'%c'", (int)v);
2311760c2415Smrg else
2312760c2415Smrg buf->printf("'\\x%02x'", (int)v);
2313760c2415Smrg if (hgs->ddoc)
2314760c2415Smrg escapeDdocString(buf, o);
2315760c2415Smrg break;
2316760c2415Smrg }
2317760c2415Smrg
2318760c2415Smrg case Tint8:
2319760c2415Smrg buf->writestring("cast(byte)");
2320760c2415Smrg goto L2;
2321760c2415Smrg
2322760c2415Smrg case Tint16:
2323760c2415Smrg buf->writestring("cast(short)");
2324760c2415Smrg goto L2;
2325760c2415Smrg
2326760c2415Smrg case Tint32:
2327760c2415Smrg L2:
2328760c2415Smrg buf->printf("%d", (int)v);
2329760c2415Smrg break;
2330760c2415Smrg
2331760c2415Smrg case Tuns8:
2332760c2415Smrg buf->writestring("cast(ubyte)");
2333760c2415Smrg goto L3;
2334760c2415Smrg
2335760c2415Smrg case Tuns16:
2336760c2415Smrg buf->writestring("cast(ushort)");
2337760c2415Smrg goto L3;
2338760c2415Smrg
2339760c2415Smrg case Tuns32:
2340760c2415Smrg L3:
2341760c2415Smrg buf->printf("%uu", (unsigned)v);
2342760c2415Smrg break;
2343760c2415Smrg
2344760c2415Smrg case Tint64:
2345760c2415Smrg buf->printf("%lldL", v);
2346760c2415Smrg break;
2347760c2415Smrg
2348760c2415Smrg case Tuns64:
2349760c2415Smrg L4:
2350760c2415Smrg buf->printf("%lluLU", v);
2351760c2415Smrg break;
2352760c2415Smrg
2353760c2415Smrg case Tbool:
2354760c2415Smrg buf->writestring(v ? "true" : "false");
2355760c2415Smrg break;
2356760c2415Smrg
2357760c2415Smrg case Tpointer:
2358760c2415Smrg buf->writestring("cast(");
2359760c2415Smrg buf->writestring(t->toChars());
2360760c2415Smrg buf->writeByte(')');
2361*0bfacb9bSmrg if (Target::ptrsize == 8)
2362760c2415Smrg goto L4;
2363760c2415Smrg else
2364*0bfacb9bSmrg goto L3;
2365760c2415Smrg
2366760c2415Smrg default:
2367760c2415Smrg /* This can happen if errors, such as
2368760c2415Smrg * the type is painted on like in fromConstInitializer().
2369760c2415Smrg */
2370760c2415Smrg if (!global.errors)
2371760c2415Smrg {
2372760c2415Smrg assert(0);
2373760c2415Smrg }
2374760c2415Smrg break;
2375760c2415Smrg }
2376760c2415Smrg }
2377760c2415Smrg else if (v & 0x8000000000000000LL)
2378760c2415Smrg buf->printf("0x%llx", v);
2379760c2415Smrg else
2380760c2415Smrg buf->printf("%lld", v);
2381760c2415Smrg }
2382760c2415Smrg
visit(ErrorExp *)2383760c2415Smrg void visit(ErrorExp *)
2384760c2415Smrg {
2385760c2415Smrg buf->writestring("__error");
2386760c2415Smrg }
2387760c2415Smrg
floatToBuffer(Type * type,real_t value)2388760c2415Smrg void floatToBuffer(Type *type, real_t value)
2389760c2415Smrg {
2390760c2415Smrg /** sizeof(value)*3 is because each byte of mantissa is max
2391760c2415Smrg of 256 (3 characters). The string will be "-M.MMMMe-4932".
2392760c2415Smrg (ie, 8 chars more than mantissa). Plus one for trailing \0.
2393760c2415Smrg Plus one for rounding. */
2394760c2415Smrg const size_t BUFFER_LEN = sizeof(value) * 3 + 8 + 1 + 1;
2395760c2415Smrg char buffer[BUFFER_LEN];
2396760c2415Smrg memset(buffer, 0, BUFFER_LEN);
2397760c2415Smrg CTFloat::sprint(buffer, 'g', value);
2398760c2415Smrg assert(strlen(buffer) < BUFFER_LEN);
2399760c2415Smrg
2400760c2415Smrg if (hgs->hdrgen)
2401760c2415Smrg {
2402760c2415Smrg real_t r = CTFloat::parse(buffer);
2403760c2415Smrg if (r != value) // if exact duplication
2404760c2415Smrg CTFloat::sprint(buffer, 'a', value);
2405760c2415Smrg }
2406760c2415Smrg buf->writestring(buffer);
2407760c2415Smrg
2408760c2415Smrg if (type)
2409760c2415Smrg {
2410760c2415Smrg Type *t = type->toBasetype();
2411760c2415Smrg switch (t->ty)
2412760c2415Smrg {
2413760c2415Smrg case Tfloat32:
2414760c2415Smrg case Timaginary32:
2415760c2415Smrg case Tcomplex32:
2416760c2415Smrg buf->writeByte('F');
2417760c2415Smrg break;
2418760c2415Smrg
2419760c2415Smrg case Tfloat80:
2420760c2415Smrg case Timaginary80:
2421760c2415Smrg case Tcomplex80:
2422760c2415Smrg buf->writeByte('L');
2423760c2415Smrg break;
2424760c2415Smrg
2425760c2415Smrg default:
2426760c2415Smrg break;
2427760c2415Smrg }
2428760c2415Smrg if (t->isimaginary())
2429760c2415Smrg buf->writeByte('i');
2430760c2415Smrg }
2431760c2415Smrg }
2432760c2415Smrg
visit(RealExp * e)2433760c2415Smrg void visit(RealExp *e)
2434760c2415Smrg {
2435760c2415Smrg floatToBuffer(e->type, e->value);
2436760c2415Smrg }
2437760c2415Smrg
visit(ComplexExp * e)2438760c2415Smrg void visit(ComplexExp *e)
2439760c2415Smrg {
2440760c2415Smrg /* Print as:
2441760c2415Smrg * (re+imi)
2442760c2415Smrg */
2443760c2415Smrg buf->writeByte('(');
2444760c2415Smrg floatToBuffer(e->type, creall(e->value));
2445760c2415Smrg buf->writeByte('+');
2446760c2415Smrg floatToBuffer(e->type, cimagl(e->value));
2447760c2415Smrg buf->writestring("i)");
2448760c2415Smrg }
2449760c2415Smrg
visit(IdentifierExp * e)2450760c2415Smrg void visit(IdentifierExp *e)
2451760c2415Smrg {
2452760c2415Smrg if (hgs->hdrgen || hgs->ddoc)
2453760c2415Smrg buf->writestring(e->ident->toHChars2());
2454760c2415Smrg else
2455760c2415Smrg buf->writestring(e->ident->toChars());
2456760c2415Smrg }
2457760c2415Smrg
visit(DsymbolExp * e)2458760c2415Smrg void visit(DsymbolExp *e)
2459760c2415Smrg {
2460760c2415Smrg buf->writestring(e->s->toChars());
2461760c2415Smrg }
2462760c2415Smrg
visit(ThisExp *)2463760c2415Smrg void visit(ThisExp *)
2464760c2415Smrg {
2465760c2415Smrg buf->writestring("this");
2466760c2415Smrg }
2467760c2415Smrg
visit(SuperExp *)2468760c2415Smrg void visit(SuperExp *)
2469760c2415Smrg {
2470760c2415Smrg buf->writestring("super");
2471760c2415Smrg }
2472760c2415Smrg
visit(NullExp *)2473760c2415Smrg void visit(NullExp *)
2474760c2415Smrg {
2475760c2415Smrg buf->writestring("null");
2476760c2415Smrg }
2477760c2415Smrg
visit(StringExp * e)2478760c2415Smrg void visit(StringExp *e)
2479760c2415Smrg {
2480760c2415Smrg buf->writeByte('"');
2481760c2415Smrg size_t o = buf->offset;
2482760c2415Smrg for (size_t i = 0; i < e->len; i++)
2483760c2415Smrg {
2484760c2415Smrg unsigned c = e->charAt(i);
2485760c2415Smrg switch (c)
2486760c2415Smrg {
2487760c2415Smrg case '"':
2488760c2415Smrg case '\\':
2489760c2415Smrg buf->writeByte('\\');
2490760c2415Smrg /* fall through */
2491760c2415Smrg default:
2492760c2415Smrg if (c <= 0xFF)
2493760c2415Smrg {
2494760c2415Smrg if (c <= 0x7F && isprint(c))
2495760c2415Smrg buf->writeByte(c);
2496760c2415Smrg else
2497760c2415Smrg buf->printf("\\x%02x", c);
2498760c2415Smrg }
2499760c2415Smrg else if (c <= 0xFFFF)
2500760c2415Smrg buf->printf("\\x%02x\\x%02x", c & 0xFF, c >> 8);
2501760c2415Smrg else
2502760c2415Smrg buf->printf("\\x%02x\\x%02x\\x%02x\\x%02x",
2503760c2415Smrg c & 0xFF, (c >> 8) & 0xFF, (c >> 16) & 0xFF, c >> 24);
2504760c2415Smrg break;
2505760c2415Smrg }
2506760c2415Smrg }
2507760c2415Smrg if (hgs->ddoc)
2508760c2415Smrg escapeDdocString(buf, o);
2509760c2415Smrg buf->writeByte('"');
2510760c2415Smrg if (e->postfix)
2511760c2415Smrg buf->writeByte(e->postfix);
2512760c2415Smrg }
2513760c2415Smrg
visit(ArrayLiteralExp * e)2514760c2415Smrg void visit(ArrayLiteralExp *e)
2515760c2415Smrg {
2516760c2415Smrg buf->writeByte('[');
2517760c2415Smrg argsToBuffer(e->elements, e->basis);
2518760c2415Smrg buf->writeByte(']');
2519760c2415Smrg }
2520760c2415Smrg
visit(AssocArrayLiteralExp * e)2521760c2415Smrg void visit(AssocArrayLiteralExp *e)
2522760c2415Smrg {
2523760c2415Smrg buf->writeByte('[');
2524760c2415Smrg for (size_t i = 0; i < e->keys->dim; i++)
2525760c2415Smrg {
2526760c2415Smrg Expression *key = (*e->keys)[i];
2527760c2415Smrg Expression *value = (*e->values)[i];
2528760c2415Smrg
2529760c2415Smrg if (i)
2530760c2415Smrg buf->writestring(", ");
2531760c2415Smrg expToBuffer(key, PREC_assign);
2532760c2415Smrg buf->writeByte(':');
2533760c2415Smrg expToBuffer(value, PREC_assign);
2534760c2415Smrg }
2535760c2415Smrg buf->writeByte(']');
2536760c2415Smrg }
2537760c2415Smrg
visit(StructLiteralExp * e)2538760c2415Smrg void visit(StructLiteralExp *e)
2539760c2415Smrg {
2540760c2415Smrg buf->writestring(e->sd->toChars());
2541760c2415Smrg buf->writeByte('(');
2542760c2415Smrg
2543760c2415Smrg // CTFE can generate struct literals that contain an AddrExp pointing
2544760c2415Smrg // to themselves, need to avoid infinite recursion:
2545760c2415Smrg // struct S { this(int){ this.s = &this; } S* s; }
2546760c2415Smrg // const foo = new S(0);
2547760c2415Smrg if (e->stageflags & stageToCBuffer)
2548760c2415Smrg buf->writestring("<recursion>");
2549760c2415Smrg else
2550760c2415Smrg {
2551760c2415Smrg int old = e->stageflags;
2552760c2415Smrg e->stageflags |= stageToCBuffer;
2553760c2415Smrg argsToBuffer(e->elements);
2554760c2415Smrg e->stageflags = old;
2555760c2415Smrg }
2556760c2415Smrg
2557760c2415Smrg buf->writeByte(')');
2558760c2415Smrg }
2559760c2415Smrg
visit(TypeExp * e)2560760c2415Smrg void visit(TypeExp *e)
2561760c2415Smrg {
2562760c2415Smrg typeToBuffer(e->type, NULL);
2563760c2415Smrg }
2564760c2415Smrg
visit(ScopeExp * e)2565760c2415Smrg void visit(ScopeExp *e)
2566760c2415Smrg {
2567760c2415Smrg if (e->sds->isTemplateInstance())
2568760c2415Smrg {
2569760c2415Smrg e->sds->accept(this);
2570760c2415Smrg }
2571760c2415Smrg else if (hgs != NULL && hgs->ddoc)
2572760c2415Smrg {
2573760c2415Smrg // fixes bug 6491
2574760c2415Smrg Module *m = e->sds->isModule();
2575760c2415Smrg if (m)
2576760c2415Smrg buf->writestring(m->md->toChars());
2577760c2415Smrg else
2578760c2415Smrg buf->writestring(e->sds->toChars());
2579760c2415Smrg }
2580760c2415Smrg else
2581760c2415Smrg {
2582760c2415Smrg buf->writestring(e->sds->kind());
2583760c2415Smrg buf->writeByte(' ');
2584760c2415Smrg buf->writestring(e->sds->toChars());
2585760c2415Smrg }
2586760c2415Smrg }
2587760c2415Smrg
visit(TemplateExp * e)2588760c2415Smrg void visit(TemplateExp *e)
2589760c2415Smrg {
2590760c2415Smrg buf->writestring(e->td->toChars());
2591760c2415Smrg }
2592760c2415Smrg
visit(NewExp * e)2593760c2415Smrg void visit(NewExp *e)
2594760c2415Smrg {
2595760c2415Smrg if (e->thisexp)
2596760c2415Smrg {
2597760c2415Smrg expToBuffer(e->thisexp, PREC_primary);
2598760c2415Smrg buf->writeByte('.');
2599760c2415Smrg }
2600760c2415Smrg buf->writestring("new ");
2601760c2415Smrg if (e->newargs && e->newargs->dim)
2602760c2415Smrg {
2603760c2415Smrg buf->writeByte('(');
2604760c2415Smrg argsToBuffer(e->newargs);
2605760c2415Smrg buf->writeByte(')');
2606760c2415Smrg }
2607760c2415Smrg typeToBuffer(e->newtype, NULL);
2608760c2415Smrg if (e->arguments && e->arguments->dim)
2609760c2415Smrg {
2610760c2415Smrg buf->writeByte('(');
2611760c2415Smrg argsToBuffer(e->arguments);
2612760c2415Smrg buf->writeByte(')');
2613760c2415Smrg }
2614760c2415Smrg }
2615760c2415Smrg
visit(NewAnonClassExp * e)2616760c2415Smrg void visit(NewAnonClassExp *e)
2617760c2415Smrg {
2618760c2415Smrg if (e->thisexp)
2619760c2415Smrg {
2620760c2415Smrg expToBuffer(e->thisexp, PREC_primary);
2621760c2415Smrg buf->writeByte('.');
2622760c2415Smrg }
2623760c2415Smrg buf->writestring("new");
2624760c2415Smrg if (e->newargs && e->newargs->dim)
2625760c2415Smrg {
2626760c2415Smrg buf->writeByte('(');
2627760c2415Smrg argsToBuffer(e->newargs);
2628760c2415Smrg buf->writeByte(')');
2629760c2415Smrg }
2630760c2415Smrg buf->writestring(" class ");
2631760c2415Smrg if (e->arguments && e->arguments->dim)
2632760c2415Smrg {
2633760c2415Smrg buf->writeByte('(');
2634760c2415Smrg argsToBuffer(e->arguments);
2635760c2415Smrg buf->writeByte(')');
2636760c2415Smrg }
2637760c2415Smrg if (e->cd)
2638760c2415Smrg e->cd->accept(this);
2639760c2415Smrg }
2640760c2415Smrg
visit(SymOffExp * e)2641760c2415Smrg void visit(SymOffExp *e)
2642760c2415Smrg {
2643760c2415Smrg if (e->offset)
2644760c2415Smrg buf->printf("(& %s+%u)", e->var->toChars(), e->offset);
2645760c2415Smrg else if (e->var->isTypeInfoDeclaration())
2646760c2415Smrg buf->printf("%s", e->var->toChars());
2647760c2415Smrg else
2648760c2415Smrg buf->printf("& %s", e->var->toChars());
2649760c2415Smrg }
2650760c2415Smrg
visit(VarExp * e)2651760c2415Smrg void visit(VarExp *e)
2652760c2415Smrg {
2653760c2415Smrg buf->writestring(e->var->toChars());
2654760c2415Smrg }
2655760c2415Smrg
visit(OverExp * e)2656760c2415Smrg void visit(OverExp *e)
2657760c2415Smrg {
2658760c2415Smrg buf->writestring(e->vars->ident->toChars());
2659760c2415Smrg }
2660760c2415Smrg
visit(TupleExp * e)2661760c2415Smrg void visit(TupleExp *e)
2662760c2415Smrg {
2663760c2415Smrg if (e->e0)
2664760c2415Smrg {
2665760c2415Smrg buf->writeByte('(');
2666760c2415Smrg e->e0->accept(this);
2667760c2415Smrg buf->writestring(", tuple(");
2668760c2415Smrg argsToBuffer(e->exps);
2669760c2415Smrg buf->writestring("))");
2670760c2415Smrg }
2671760c2415Smrg else
2672760c2415Smrg {
2673760c2415Smrg buf->writestring("tuple(");
2674760c2415Smrg argsToBuffer(e->exps);
2675760c2415Smrg buf->writeByte(')');
2676760c2415Smrg }
2677760c2415Smrg }
2678760c2415Smrg
visit(FuncExp * e)2679760c2415Smrg void visit(FuncExp *e)
2680760c2415Smrg {
2681760c2415Smrg e->fd->accept(this);
2682760c2415Smrg //buf->writestring(e->fd->toChars());
2683760c2415Smrg }
2684760c2415Smrg
visit(DeclarationExp * e)2685760c2415Smrg void visit(DeclarationExp *e)
2686760c2415Smrg {
2687760c2415Smrg /* Normal dmd execution won't reach here - regular variable declarations
2688760c2415Smrg * are handled in visit(ExpStatement), so here would be used only when
2689760c2415Smrg * we'll directly call Expression::toChars() for debugging.
2690760c2415Smrg */
2691760c2415Smrg if (VarDeclaration *v = e->declaration->isVarDeclaration())
2692760c2415Smrg {
2693760c2415Smrg // For debugging use:
2694760c2415Smrg // - Avoid printing newline.
2695760c2415Smrg // - Intentionally use the format (Type var;)
2696760c2415Smrg // which isn't correct as regular D code.
2697760c2415Smrg buf->writeByte('(');
2698760c2415Smrg visitVarDecl(v, false);
2699760c2415Smrg buf->writeByte(';');
2700760c2415Smrg buf->writeByte(')');
2701760c2415Smrg }
2702760c2415Smrg else
2703760c2415Smrg e->declaration->accept(this);
2704760c2415Smrg }
2705760c2415Smrg
visit(TypeidExp * e)2706760c2415Smrg void visit(TypeidExp *e)
2707760c2415Smrg {
2708760c2415Smrg buf->writestring("typeid(");
2709760c2415Smrg objectToBuffer(e->obj);
2710760c2415Smrg buf->writeByte(')');
2711760c2415Smrg }
2712760c2415Smrg
visit(TraitsExp * e)2713760c2415Smrg void visit(TraitsExp *e)
2714760c2415Smrg {
2715760c2415Smrg buf->writestring("__traits(");
2716*0bfacb9bSmrg if (e->ident)
2717760c2415Smrg buf->writestring(e->ident->toChars());
2718760c2415Smrg if (e->args)
2719760c2415Smrg {
2720760c2415Smrg for (size_t i = 0; i < e->args->dim; i++)
2721760c2415Smrg {
2722760c2415Smrg RootObject *arg = (*e->args)[i];
2723760c2415Smrg buf->writestring(", ");
2724760c2415Smrg objectToBuffer(arg);
2725760c2415Smrg }
2726760c2415Smrg }
2727760c2415Smrg buf->writeByte(')');
2728760c2415Smrg }
2729760c2415Smrg
visit(HaltExp *)2730760c2415Smrg void visit(HaltExp *)
2731760c2415Smrg {
2732760c2415Smrg buf->writestring("halt");
2733760c2415Smrg }
2734760c2415Smrg
visit(IsExp * e)2735760c2415Smrg void visit(IsExp *e)
2736760c2415Smrg {
2737760c2415Smrg buf->writestring("is(");
2738760c2415Smrg typeToBuffer(e->targ, e->id);
2739760c2415Smrg if (e->tok2 != TOKreserved)
2740760c2415Smrg {
2741760c2415Smrg buf->printf(" %s %s", Token::toChars(e->tok), Token::toChars(e->tok2));
2742760c2415Smrg }
2743760c2415Smrg else if (e->tspec)
2744760c2415Smrg {
2745760c2415Smrg if (e->tok == TOKcolon)
2746760c2415Smrg buf->writestring(" : ");
2747760c2415Smrg else
2748760c2415Smrg buf->writestring(" == ");
2749760c2415Smrg typeToBuffer(e->tspec, NULL);
2750760c2415Smrg }
2751760c2415Smrg if (e->parameters && e->parameters->dim)
2752760c2415Smrg {
2753760c2415Smrg buf->writestring(", ");
2754760c2415Smrg visitTemplateParameters(e->parameters);
2755760c2415Smrg }
2756760c2415Smrg buf->writeByte(')');
2757760c2415Smrg }
2758760c2415Smrg
visit(UnaExp * e)2759760c2415Smrg void visit(UnaExp *e)
2760760c2415Smrg {
2761760c2415Smrg buf->writestring(Token::toChars(e->op));
2762760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2763760c2415Smrg }
2764760c2415Smrg
visit(BinExp * e)2765760c2415Smrg void visit(BinExp *e)
2766760c2415Smrg {
2767760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2768760c2415Smrg buf->writeByte(' ');
2769760c2415Smrg buf->writestring(Token::toChars(e->op));
2770760c2415Smrg buf->writeByte(' ');
2771760c2415Smrg expToBuffer(e->e2, (PREC)(precedence[e->op] + 1));
2772760c2415Smrg }
2773760c2415Smrg
visit(CompileExp * e)2774760c2415Smrg void visit(CompileExp *e)
2775760c2415Smrg {
2776760c2415Smrg buf->writestring("mixin(");
2777760c2415Smrg expToBuffer(e->e1, PREC_assign);
2778760c2415Smrg buf->writeByte(')');
2779760c2415Smrg }
2780760c2415Smrg
visit(ImportExp * e)2781760c2415Smrg void visit(ImportExp *e)
2782760c2415Smrg {
2783760c2415Smrg buf->writestring("import(");
2784760c2415Smrg expToBuffer(e->e1, PREC_assign);
2785760c2415Smrg buf->writeByte(')');
2786760c2415Smrg }
2787760c2415Smrg
visit(AssertExp * e)2788760c2415Smrg void visit(AssertExp *e)
2789760c2415Smrg {
2790760c2415Smrg buf->writestring("assert(");
2791760c2415Smrg expToBuffer(e->e1, PREC_assign);
2792760c2415Smrg if (e->msg)
2793760c2415Smrg {
2794760c2415Smrg buf->writestring(", ");
2795760c2415Smrg expToBuffer(e->msg, PREC_assign);
2796760c2415Smrg }
2797760c2415Smrg buf->writeByte(')');
2798760c2415Smrg }
2799760c2415Smrg
visit(DotIdExp * e)2800760c2415Smrg void visit(DotIdExp *e)
2801760c2415Smrg {
2802760c2415Smrg expToBuffer(e->e1, PREC_primary);
2803760c2415Smrg buf->writeByte('.');
2804760c2415Smrg buf->writestring(e->ident->toChars());
2805760c2415Smrg }
2806760c2415Smrg
visit(DotTemplateExp * e)2807760c2415Smrg void visit(DotTemplateExp *e)
2808760c2415Smrg {
2809760c2415Smrg expToBuffer(e->e1, PREC_primary);
2810760c2415Smrg buf->writeByte('.');
2811760c2415Smrg buf->writestring(e->td->toChars());
2812760c2415Smrg }
2813760c2415Smrg
visit(DotVarExp * e)2814760c2415Smrg void visit(DotVarExp *e)
2815760c2415Smrg {
2816760c2415Smrg expToBuffer(e->e1, PREC_primary);
2817760c2415Smrg buf->writeByte('.');
2818760c2415Smrg buf->writestring(e->var->toChars());
2819760c2415Smrg }
2820760c2415Smrg
visit(DotTemplateInstanceExp * e)2821760c2415Smrg void visit(DotTemplateInstanceExp *e)
2822760c2415Smrg {
2823760c2415Smrg expToBuffer(e->e1, PREC_primary);
2824760c2415Smrg buf->writeByte('.');
2825760c2415Smrg e->ti->accept(this);
2826760c2415Smrg }
2827760c2415Smrg
visit(DelegateExp * e)2828760c2415Smrg void visit(DelegateExp *e)
2829760c2415Smrg {
2830760c2415Smrg buf->writeByte('&');
2831760c2415Smrg if (!e->func->isNested())
2832760c2415Smrg {
2833760c2415Smrg expToBuffer(e->e1, PREC_primary);
2834760c2415Smrg buf->writeByte('.');
2835760c2415Smrg }
2836760c2415Smrg buf->writestring(e->func->toChars());
2837760c2415Smrg }
2838760c2415Smrg
visit(DotTypeExp * e)2839760c2415Smrg void visit(DotTypeExp *e)
2840760c2415Smrg {
2841760c2415Smrg expToBuffer(e->e1, PREC_primary);
2842760c2415Smrg buf->writeByte('.');
2843760c2415Smrg buf->writestring(e->sym->toChars());
2844760c2415Smrg }
2845760c2415Smrg
visit(CallExp * e)2846760c2415Smrg void visit(CallExp *e)
2847760c2415Smrg {
2848760c2415Smrg if (e->e1->op == TOKtype)
2849760c2415Smrg {
2850760c2415Smrg /* Avoid parens around type to prevent forbidden cast syntax:
2851760c2415Smrg * (sometype)(arg1)
2852760c2415Smrg * This is ok since types in constructor calls
2853760c2415Smrg * can never depend on parens anyway
2854760c2415Smrg */
2855760c2415Smrg e->e1->accept(this);
2856760c2415Smrg }
2857760c2415Smrg else
2858760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2859760c2415Smrg buf->writeByte('(');
2860760c2415Smrg argsToBuffer(e->arguments);
2861760c2415Smrg buf->writeByte(')');
2862760c2415Smrg }
2863760c2415Smrg
visit(PtrExp * e)2864760c2415Smrg void visit(PtrExp *e)
2865760c2415Smrg {
2866760c2415Smrg buf->writeByte('*');
2867760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2868760c2415Smrg }
2869760c2415Smrg
visit(DeleteExp * e)2870760c2415Smrg void visit(DeleteExp *e)
2871760c2415Smrg {
2872760c2415Smrg buf->writestring("delete ");
2873760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2874760c2415Smrg }
2875760c2415Smrg
visit(CastExp * e)2876760c2415Smrg void visit(CastExp *e)
2877760c2415Smrg {
2878760c2415Smrg buf->writestring("cast(");
2879760c2415Smrg if (e->to)
2880760c2415Smrg typeToBuffer(e->to, NULL);
2881760c2415Smrg else
2882760c2415Smrg {
2883760c2415Smrg MODtoBuffer(buf, e->mod);
2884760c2415Smrg }
2885760c2415Smrg buf->writeByte(')');
2886760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2887760c2415Smrg }
2888760c2415Smrg
visit(VectorExp * e)2889760c2415Smrg void visit(VectorExp *e)
2890760c2415Smrg {
2891760c2415Smrg buf->writestring("cast(");
2892760c2415Smrg typeToBuffer(e->to, NULL);
2893760c2415Smrg buf->writeByte(')');
2894760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2895760c2415Smrg }
2896760c2415Smrg
visit(VectorArrayExp * e)2897760c2415Smrg void visit(VectorArrayExp *e)
2898760c2415Smrg {
2899760c2415Smrg expToBuffer(e->e1, PREC_primary);
2900760c2415Smrg buf->writestring(".array");
2901760c2415Smrg }
2902760c2415Smrg
visit(SliceExp * e)2903760c2415Smrg void visit(SliceExp *e)
2904760c2415Smrg {
2905760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2906760c2415Smrg buf->writeByte('[');
2907760c2415Smrg if (e->upr || e->lwr)
2908760c2415Smrg {
2909760c2415Smrg if (e->lwr)
2910760c2415Smrg sizeToBuffer(e->lwr);
2911760c2415Smrg else
2912760c2415Smrg buf->writeByte('0');
2913760c2415Smrg buf->writestring("..");
2914760c2415Smrg if (e->upr)
2915760c2415Smrg sizeToBuffer(e->upr);
2916760c2415Smrg else
2917760c2415Smrg buf->writeByte('$');
2918760c2415Smrg }
2919760c2415Smrg buf->writeByte(']');
2920760c2415Smrg }
2921760c2415Smrg
visit(ArrayLengthExp * e)2922760c2415Smrg void visit(ArrayLengthExp *e)
2923760c2415Smrg {
2924760c2415Smrg expToBuffer(e->e1, PREC_primary);
2925760c2415Smrg buf->writestring(".length");
2926760c2415Smrg }
2927760c2415Smrg
visit(IntervalExp * e)2928760c2415Smrg void visit(IntervalExp *e)
2929760c2415Smrg {
2930760c2415Smrg expToBuffer(e->lwr, PREC_assign);
2931760c2415Smrg buf->writestring("..");
2932760c2415Smrg expToBuffer(e->upr, PREC_assign);
2933760c2415Smrg }
2934760c2415Smrg
visit(DelegatePtrExp * e)2935760c2415Smrg void visit(DelegatePtrExp *e)
2936760c2415Smrg {
2937760c2415Smrg expToBuffer(e->e1, PREC_primary);
2938760c2415Smrg buf->writestring(".ptr");
2939760c2415Smrg }
2940760c2415Smrg
visit(DelegateFuncptrExp * e)2941760c2415Smrg void visit(DelegateFuncptrExp *e)
2942760c2415Smrg {
2943760c2415Smrg expToBuffer(e->e1, PREC_primary);
2944760c2415Smrg buf->writestring(".funcptr");
2945760c2415Smrg }
2946760c2415Smrg
visit(ArrayExp * e)2947760c2415Smrg void visit(ArrayExp *e)
2948760c2415Smrg {
2949760c2415Smrg expToBuffer(e->e1, PREC_primary);
2950760c2415Smrg buf->writeByte('[');
2951760c2415Smrg argsToBuffer(e->arguments);
2952760c2415Smrg buf->writeByte(']');
2953760c2415Smrg }
2954760c2415Smrg
visit(DotExp * e)2955760c2415Smrg void visit(DotExp *e)
2956760c2415Smrg {
2957760c2415Smrg expToBuffer(e->e1, PREC_primary);
2958760c2415Smrg buf->writeByte('.');
2959760c2415Smrg expToBuffer(e->e2, PREC_primary);
2960760c2415Smrg }
2961760c2415Smrg
visit(IndexExp * e)2962760c2415Smrg void visit(IndexExp *e)
2963760c2415Smrg {
2964760c2415Smrg expToBuffer(e->e1, PREC_primary);
2965760c2415Smrg buf->writeByte('[');
2966760c2415Smrg sizeToBuffer(e->e2);
2967760c2415Smrg buf->writeByte(']');
2968760c2415Smrg }
2969760c2415Smrg
visit(PostExp * e)2970760c2415Smrg void visit(PostExp *e)
2971760c2415Smrg {
2972760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2973760c2415Smrg buf->writestring(Token::toChars(e->op));
2974760c2415Smrg }
2975760c2415Smrg
visit(PreExp * e)2976760c2415Smrg void visit(PreExp *e)
2977760c2415Smrg {
2978760c2415Smrg buf->writestring(Token::toChars(e->op));
2979760c2415Smrg expToBuffer(e->e1, precedence[e->op]);
2980760c2415Smrg }
2981760c2415Smrg
visit(RemoveExp * e)2982760c2415Smrg void visit(RemoveExp *e)
2983760c2415Smrg {
2984760c2415Smrg expToBuffer(e->e1, PREC_primary);
2985760c2415Smrg buf->writestring(".remove(");
2986760c2415Smrg expToBuffer(e->e2, PREC_assign);
2987760c2415Smrg buf->writeByte(')');
2988760c2415Smrg }
2989760c2415Smrg
visit(CondExp * e)2990760c2415Smrg void visit(CondExp *e)
2991760c2415Smrg {
2992760c2415Smrg expToBuffer(e->econd, PREC_oror);
2993760c2415Smrg buf->writestring(" ? ");
2994760c2415Smrg expToBuffer(e->e1, PREC_expr);
2995760c2415Smrg buf->writestring(" : ");
2996760c2415Smrg expToBuffer(e->e2, PREC_cond);
2997760c2415Smrg }
2998760c2415Smrg
visit(DefaultInitExp * e)2999760c2415Smrg void visit(DefaultInitExp *e)
3000760c2415Smrg {
3001760c2415Smrg buf->writestring(Token::toChars(e->subop));
3002760c2415Smrg }
3003760c2415Smrg
visit(ClassReferenceExp * e)3004760c2415Smrg void visit(ClassReferenceExp *e)
3005760c2415Smrg {
3006760c2415Smrg buf->writestring(e->value->toChars());
3007760c2415Smrg }
3008760c2415Smrg
3009760c2415Smrg ////////////////////////////////////////////////////////////////////////////
3010760c2415Smrg
visit(TemplateTypeParameter * tp)3011760c2415Smrg void visit(TemplateTypeParameter *tp)
3012760c2415Smrg {
3013760c2415Smrg buf->writestring(tp->ident->toChars());
3014760c2415Smrg if (tp->specType)
3015760c2415Smrg {
3016760c2415Smrg buf->writestring(" : ");
3017760c2415Smrg typeToBuffer(tp->specType, NULL);
3018760c2415Smrg }
3019760c2415Smrg if (tp->defaultType)
3020760c2415Smrg {
3021760c2415Smrg buf->writestring(" = ");
3022760c2415Smrg typeToBuffer(tp->defaultType, NULL);
3023760c2415Smrg }
3024760c2415Smrg }
3025760c2415Smrg
visit(TemplateThisParameter * tp)3026760c2415Smrg void visit(TemplateThisParameter *tp)
3027760c2415Smrg {
3028760c2415Smrg buf->writestring("this ");
3029760c2415Smrg visit((TemplateTypeParameter *)tp);
3030760c2415Smrg }
3031760c2415Smrg
visit(TemplateAliasParameter * tp)3032760c2415Smrg void visit(TemplateAliasParameter *tp)
3033760c2415Smrg {
3034760c2415Smrg buf->writestring("alias ");
3035760c2415Smrg if (tp->specType)
3036760c2415Smrg typeToBuffer(tp->specType, tp->ident);
3037760c2415Smrg else
3038760c2415Smrg buf->writestring(tp->ident->toChars());
3039760c2415Smrg if (tp->specAlias)
3040760c2415Smrg {
3041760c2415Smrg buf->writestring(" : ");
3042760c2415Smrg objectToBuffer(tp->specAlias);
3043760c2415Smrg }
3044760c2415Smrg if (tp->defaultAlias)
3045760c2415Smrg {
3046760c2415Smrg buf->writestring(" = ");
3047760c2415Smrg objectToBuffer(tp->defaultAlias);
3048760c2415Smrg }
3049760c2415Smrg }
3050760c2415Smrg
visit(TemplateValueParameter * tp)3051760c2415Smrg void visit(TemplateValueParameter *tp)
3052760c2415Smrg {
3053760c2415Smrg typeToBuffer(tp->valType, tp->ident);
3054760c2415Smrg if (tp->specValue)
3055760c2415Smrg {
3056760c2415Smrg buf->writestring(" : ");
3057760c2415Smrg tp->specValue->accept(this);
3058760c2415Smrg }
3059760c2415Smrg if (tp->defaultValue)
3060760c2415Smrg {
3061760c2415Smrg buf->writestring(" = ");
3062760c2415Smrg tp->defaultValue->accept(this);
3063760c2415Smrg }
3064760c2415Smrg }
3065760c2415Smrg
visit(TemplateTupleParameter * tp)3066760c2415Smrg void visit(TemplateTupleParameter *tp)
3067760c2415Smrg {
3068760c2415Smrg buf->writestring(tp->ident->toChars());
3069760c2415Smrg buf->writestring("...");
3070760c2415Smrg }
3071760c2415Smrg
3072760c2415Smrg ////////////////////////////////////////////////////////////////////////////
3073760c2415Smrg
visit(DebugCondition * c)3074760c2415Smrg void visit(DebugCondition *c)
3075760c2415Smrg {
3076760c2415Smrg if (c->ident)
3077760c2415Smrg buf->printf("debug (%s)", c->ident->toChars());
3078760c2415Smrg else
3079760c2415Smrg buf->printf("debug (%u)", c->level);
3080760c2415Smrg }
3081760c2415Smrg
visit(VersionCondition * c)3082760c2415Smrg void visit(VersionCondition *c)
3083760c2415Smrg {
3084760c2415Smrg if (c->ident)
3085760c2415Smrg buf->printf("version (%s)", c->ident->toChars());
3086760c2415Smrg else
3087760c2415Smrg buf->printf("version (%u)", c->level);
3088760c2415Smrg }
3089760c2415Smrg
visit(StaticIfCondition * c)3090760c2415Smrg void visit(StaticIfCondition *c)
3091760c2415Smrg {
3092760c2415Smrg buf->writestring("static if (");
3093760c2415Smrg c->exp->accept(this);
3094760c2415Smrg buf->writeByte(')');
3095760c2415Smrg }
3096760c2415Smrg
3097760c2415Smrg ////////////////////////////////////////////////////////////////////////////
3098760c2415Smrg
visit(Parameter * p)3099760c2415Smrg void visit(Parameter *p)
3100760c2415Smrg {
3101760c2415Smrg if (p->storageClass & STCauto)
3102760c2415Smrg buf->writestring("auto ");
3103760c2415Smrg
3104760c2415Smrg if (p->storageClass & STCreturn)
3105760c2415Smrg buf->writestring("return ");
3106760c2415Smrg
3107760c2415Smrg if (p->storageClass & STCout)
3108760c2415Smrg buf->writestring("out ");
3109760c2415Smrg else if (p->storageClass & STCref)
3110760c2415Smrg buf->writestring("ref ");
3111760c2415Smrg else if (p->storageClass & STCin)
3112760c2415Smrg buf->writestring("in ");
3113760c2415Smrg else if (p->storageClass & STClazy)
3114760c2415Smrg buf->writestring("lazy ");
3115760c2415Smrg else if (p->storageClass & STCalias)
3116760c2415Smrg buf->writestring("alias ");
3117760c2415Smrg
3118760c2415Smrg StorageClass stc = p->storageClass;
3119760c2415Smrg if (p->type && p->type->mod & MODshared)
3120760c2415Smrg stc &= ~STCshared;
3121760c2415Smrg
3122760c2415Smrg if (stcToBuffer(buf, stc & (STCconst | STCimmutable | STCwild | STCshared | STCscope | STCscopeinferred)))
3123760c2415Smrg buf->writeByte(' ');
3124760c2415Smrg
3125760c2415Smrg if (p->storageClass & STCalias)
3126760c2415Smrg {
3127760c2415Smrg if (p->ident)
3128760c2415Smrg buf->writestring(p->ident->toChars());
3129760c2415Smrg }
3130760c2415Smrg else if (p->type->ty == Tident &&
3131760c2415Smrg strlen(((TypeIdentifier *)p->type)->ident->toChars()) > 3 &&
3132760c2415Smrg strncmp(((TypeIdentifier *)p->type)->ident->toChars(), "__T", 3) == 0)
3133760c2415Smrg {
3134760c2415Smrg // print parameter name, instead of undetermined type parameter
3135760c2415Smrg buf->writestring(p->ident->toChars());
3136760c2415Smrg }
3137760c2415Smrg else
3138760c2415Smrg typeToBuffer(p->type, p->ident);
3139760c2415Smrg if (p->defaultArg)
3140760c2415Smrg {
3141760c2415Smrg buf->writestring(" = ");
3142760c2415Smrg p->defaultArg->accept(this);
3143760c2415Smrg }
3144760c2415Smrg }
3145760c2415Smrg
parametersToBuffer(Parameters * parameters,int varargs)3146760c2415Smrg void parametersToBuffer(Parameters *parameters, int varargs)
3147760c2415Smrg {
3148760c2415Smrg buf->writeByte('(');
3149760c2415Smrg if (parameters)
3150760c2415Smrg {
3151760c2415Smrg size_t dim = Parameter::dim(parameters);
3152760c2415Smrg for (size_t i = 0; i < dim; i++)
3153760c2415Smrg {
3154760c2415Smrg if (i)
3155760c2415Smrg buf->writestring(", ");
3156760c2415Smrg Parameter *fparam = Parameter::getNth(parameters, i);
3157760c2415Smrg fparam->accept(this);
3158760c2415Smrg }
3159760c2415Smrg if (varargs)
3160760c2415Smrg {
3161760c2415Smrg if (parameters->dim && varargs == 1)
3162760c2415Smrg buf->writestring(", ");
3163760c2415Smrg buf->writestring("...");
3164760c2415Smrg }
3165760c2415Smrg }
3166760c2415Smrg buf->writeByte(')');
3167760c2415Smrg }
3168760c2415Smrg
visit(Module * m)3169760c2415Smrg void visit(Module *m)
3170760c2415Smrg {
3171760c2415Smrg if (m->md)
3172760c2415Smrg {
3173760c2415Smrg if (m->userAttribDecl)
3174760c2415Smrg {
3175760c2415Smrg buf->writestring("@(");
3176760c2415Smrg argsToBuffer(m->userAttribDecl->atts);
3177760c2415Smrg buf->writeByte(')');
3178760c2415Smrg buf->writenl();
3179760c2415Smrg }
3180760c2415Smrg if (m->md->isdeprecated)
3181760c2415Smrg {
3182760c2415Smrg if (m->md->msg)
3183760c2415Smrg {
3184760c2415Smrg buf->writestring("deprecated(");
3185760c2415Smrg m->md->msg->accept(this);
3186760c2415Smrg buf->writestring(") ");
3187760c2415Smrg }
3188760c2415Smrg else
3189760c2415Smrg buf->writestring("deprecated ");
3190760c2415Smrg }
3191760c2415Smrg
3192760c2415Smrg buf->writestring("module ");
3193760c2415Smrg buf->writestring(m->md->toChars());
3194760c2415Smrg buf->writeByte(';');
3195760c2415Smrg buf->writenl();
3196760c2415Smrg }
3197760c2415Smrg for (size_t i = 0; i < m->members->dim; i++)
3198760c2415Smrg {
3199760c2415Smrg Dsymbol *s = (*m->members)[i];
3200760c2415Smrg s->accept(this);
3201760c2415Smrg }
3202760c2415Smrg }
3203760c2415Smrg };
3204760c2415Smrg
toCBuffer(Statement * s,OutBuffer * buf,HdrGenState * hgs)3205760c2415Smrg void toCBuffer(Statement *s, OutBuffer *buf, HdrGenState *hgs)
3206760c2415Smrg {
3207760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3208760c2415Smrg s->accept(&v);
3209760c2415Smrg }
3210760c2415Smrg
toCBuffer(Type * t,OutBuffer * buf,Identifier * ident,HdrGenState * hgs)3211760c2415Smrg void toCBuffer(Type *t, OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
3212760c2415Smrg {
3213760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3214760c2415Smrg v.typeToBuffer(t, ident);
3215760c2415Smrg }
3216760c2415Smrg
toCBuffer(Dsymbol * s,OutBuffer * buf,HdrGenState * hgs)3217760c2415Smrg void toCBuffer(Dsymbol *s, OutBuffer *buf, HdrGenState *hgs)
3218760c2415Smrg {
3219760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3220760c2415Smrg s->accept(&v);
3221760c2415Smrg }
3222760c2415Smrg
3223760c2415Smrg // used from TemplateInstance::toChars() and TemplateMixin::toChars()
toCBufferInstance(TemplateInstance * ti,OutBuffer * buf,bool qualifyTypes)3224760c2415Smrg void toCBufferInstance(TemplateInstance *ti, OutBuffer *buf, bool qualifyTypes)
3225760c2415Smrg {
3226760c2415Smrg HdrGenState hgs;
3227760c2415Smrg hgs.fullQual = qualifyTypes;
3228760c2415Smrg PrettyPrintVisitor v(buf, &hgs);
3229760c2415Smrg v.visit(ti);
3230760c2415Smrg }
3231760c2415Smrg
toCBuffer(Initializer * iz,OutBuffer * buf,HdrGenState * hgs)3232760c2415Smrg void toCBuffer(Initializer *iz, OutBuffer *buf, HdrGenState *hgs)
3233760c2415Smrg {
3234760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3235760c2415Smrg iz->accept(&v);
3236760c2415Smrg }
3237760c2415Smrg
stcToBuffer(OutBuffer * buf,StorageClass stc)3238760c2415Smrg bool stcToBuffer(OutBuffer *buf, StorageClass stc)
3239760c2415Smrg {
3240760c2415Smrg bool result = false;
3241760c2415Smrg if ((stc & (STCreturn | STCscope)) == (STCreturn | STCscope))
3242760c2415Smrg stc &= ~STCscope;
3243760c2415Smrg if (stc & STCscopeinferred)
3244760c2415Smrg stc &= ~(STCscope | STCscopeinferred);
3245760c2415Smrg while (stc)
3246760c2415Smrg {
3247760c2415Smrg const char *p = stcToChars(stc);
3248760c2415Smrg if (!p)
3249760c2415Smrg break;
3250760c2415Smrg if (!result)
3251760c2415Smrg result = true;
3252760c2415Smrg else
3253760c2415Smrg buf->writeByte(' ');
3254760c2415Smrg buf->writestring(p);
3255760c2415Smrg }
3256760c2415Smrg return result;
3257760c2415Smrg }
3258760c2415Smrg
3259760c2415Smrg /*************************************************
3260760c2415Smrg * Pick off one of the storage classes from stc,
3261760c2415Smrg * and return a pointer to a string representation of it.
3262760c2415Smrg * stc is reduced by the one picked.
3263760c2415Smrg */
stcToChars(StorageClass & stc)3264760c2415Smrg const char *stcToChars(StorageClass& stc)
3265760c2415Smrg {
3266760c2415Smrg struct SCstring
3267760c2415Smrg {
3268760c2415Smrg StorageClass stc;
3269760c2415Smrg TOK tok;
3270760c2415Smrg const char *id;
3271760c2415Smrg };
3272760c2415Smrg
3273760c2415Smrg static SCstring table[] =
3274760c2415Smrg {
3275760c2415Smrg { STCauto, TOKauto, NULL },
3276760c2415Smrg { STCscope, TOKscope, NULL },
3277760c2415Smrg { STCstatic, TOKstatic, NULL },
3278760c2415Smrg { STCextern, TOKextern, NULL },
3279760c2415Smrg { STCconst, TOKconst, NULL },
3280760c2415Smrg { STCfinal, TOKfinal, NULL },
3281760c2415Smrg { STCabstract, TOKabstract, NULL },
3282760c2415Smrg { STCsynchronized, TOKsynchronized, NULL },
3283760c2415Smrg { STCdeprecated, TOKdeprecated, NULL },
3284760c2415Smrg { STCoverride, TOKoverride, NULL },
3285760c2415Smrg { STClazy, TOKlazy, NULL },
3286760c2415Smrg { STCalias, TOKalias, NULL },
3287760c2415Smrg { STCout, TOKout, NULL },
3288760c2415Smrg { STCin, TOKin, NULL },
3289760c2415Smrg { STCmanifest, TOKenum, NULL },
3290760c2415Smrg { STCimmutable, TOKimmutable, NULL },
3291760c2415Smrg { STCshared, TOKshared, NULL },
3292760c2415Smrg { STCnothrow, TOKnothrow, NULL },
3293760c2415Smrg { STCwild, TOKwild, NULL },
3294760c2415Smrg { STCpure, TOKpure, NULL },
3295760c2415Smrg { STCref, TOKref, NULL },
3296760c2415Smrg { STCtls, TOKreserved, NULL },
3297760c2415Smrg { STCgshared, TOKgshared, NULL },
3298760c2415Smrg { STCnogc, TOKat, "@nogc" },
3299760c2415Smrg { STCproperty, TOKat, "@property" },
3300760c2415Smrg { STCsafe, TOKat, "@safe" },
3301760c2415Smrg { STCtrusted, TOKat, "@trusted" },
3302760c2415Smrg { STCsystem, TOKat, "@system" },
3303760c2415Smrg { STCdisable, TOKat, "@disable" },
3304760c2415Smrg { STCfuture, TOKat, "@__future" },
3305*0bfacb9bSmrg { STClocal, TOKat, "__local" },
3306760c2415Smrg { 0, TOKreserved, NULL }
3307760c2415Smrg };
3308760c2415Smrg
3309760c2415Smrg for (int i = 0; table[i].stc; i++)
3310760c2415Smrg {
3311760c2415Smrg StorageClass tbl = table[i].stc;
3312760c2415Smrg assert(tbl & STCStorageClass);
3313760c2415Smrg if (stc & tbl)
3314760c2415Smrg {
3315760c2415Smrg stc &= ~tbl;
3316760c2415Smrg if (tbl == STCtls) // TOKtls was removed
3317760c2415Smrg return "__thread";
3318760c2415Smrg
3319760c2415Smrg TOK tok = table[i].tok;
3320760c2415Smrg if (tok == TOKat)
3321760c2415Smrg return table[i].id;
3322760c2415Smrg else
3323760c2415Smrg return Token::toChars(tok);
3324760c2415Smrg }
3325760c2415Smrg }
3326760c2415Smrg //printf("stc = %llx\n", stc);
3327760c2415Smrg return NULL;
3328760c2415Smrg }
3329760c2415Smrg
trustToBuffer(OutBuffer * buf,TRUST trust)3330760c2415Smrg void trustToBuffer(OutBuffer *buf, TRUST trust)
3331760c2415Smrg {
3332760c2415Smrg const char *p = trustToChars(trust);
3333760c2415Smrg if (p)
3334760c2415Smrg buf->writestring(p);
3335760c2415Smrg }
3336760c2415Smrg
trustToChars(TRUST trust)3337760c2415Smrg const char *trustToChars(TRUST trust)
3338760c2415Smrg {
3339760c2415Smrg switch (trust)
3340760c2415Smrg {
3341760c2415Smrg case TRUSTdefault: return NULL;
3342760c2415Smrg case TRUSTsystem: return "@system";
3343760c2415Smrg case TRUSTtrusted: return "@trusted";
3344760c2415Smrg case TRUSTsafe: return "@safe";
3345760c2415Smrg default: assert(0);
3346760c2415Smrg }
3347760c2415Smrg return NULL; // never reached
3348760c2415Smrg }
3349760c2415Smrg
linkageToBuffer(OutBuffer * buf,LINK linkage)3350760c2415Smrg void linkageToBuffer(OutBuffer *buf, LINK linkage)
3351760c2415Smrg {
3352760c2415Smrg const char *p = linkageToChars(linkage);
3353760c2415Smrg if (p)
3354760c2415Smrg {
3355760c2415Smrg buf->writestring("extern (");
3356760c2415Smrg buf->writestring(p);
3357760c2415Smrg buf->writeByte(')');
3358760c2415Smrg }
3359760c2415Smrg }
3360760c2415Smrg
linkageToChars(LINK linkage)3361760c2415Smrg const char *linkageToChars(LINK linkage)
3362760c2415Smrg {
3363760c2415Smrg switch (linkage)
3364760c2415Smrg {
3365760c2415Smrg case LINKdefault: return NULL;
3366760c2415Smrg case LINKd: return "D";
3367760c2415Smrg case LINKc: return "C";
3368760c2415Smrg case LINKcpp: return "C++";
3369760c2415Smrg case LINKwindows: return "Windows";
3370760c2415Smrg case LINKpascal: return "Pascal";
3371760c2415Smrg case LINKobjc: return "Objective-C";
3372760c2415Smrg case LINKsystem: return "System";
3373760c2415Smrg default: assert(0);
3374760c2415Smrg }
3375760c2415Smrg return NULL; // never reached
3376760c2415Smrg }
3377760c2415Smrg
protectionToBuffer(OutBuffer * buf,Prot prot)3378760c2415Smrg void protectionToBuffer(OutBuffer *buf, Prot prot)
3379760c2415Smrg {
3380760c2415Smrg const char *p = protectionToChars(prot.kind);
3381760c2415Smrg if (p)
3382760c2415Smrg buf->writestring(p);
3383760c2415Smrg
3384760c2415Smrg if (prot.kind == PROTpackage && prot.pkg)
3385760c2415Smrg {
3386760c2415Smrg buf->writeByte('(');
3387760c2415Smrg buf->writestring(prot.pkg->toPrettyChars(true));
3388760c2415Smrg buf->writeByte(')');
3389760c2415Smrg }
3390760c2415Smrg }
3391760c2415Smrg
protectionToChars(PROTKIND kind)3392760c2415Smrg const char *protectionToChars(PROTKIND kind)
3393760c2415Smrg {
3394760c2415Smrg switch (kind)
3395760c2415Smrg {
3396760c2415Smrg case PROTundefined: return NULL;
3397760c2415Smrg case PROTnone: return "none";
3398760c2415Smrg case PROTprivate: return "private";
3399760c2415Smrg case PROTpackage: return "package";
3400760c2415Smrg case PROTprotected: return "protected";
3401760c2415Smrg case PROTpublic: return "public";
3402760c2415Smrg case PROTexport: return "export";
3403760c2415Smrg default: assert(0);
3404760c2415Smrg }
3405760c2415Smrg return NULL; // never reached
3406760c2415Smrg }
3407760c2415Smrg
3408760c2415Smrg // Print the full function signature with correct ident, attributes and template args
functionToBufferFull(TypeFunction * tf,OutBuffer * buf,Identifier * ident,HdrGenState * hgs,TemplateDeclaration * td)3409760c2415Smrg void functionToBufferFull(TypeFunction *tf, OutBuffer *buf, Identifier *ident,
3410760c2415Smrg HdrGenState* hgs, TemplateDeclaration *td)
3411760c2415Smrg {
3412760c2415Smrg //printf("TypeFunction::toCBuffer() this = %p\n", this);
3413760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3414760c2415Smrg v.visitFuncIdentWithPrefix(tf, ident, td);
3415760c2415Smrg }
3416760c2415Smrg
3417760c2415Smrg // ident is inserted before the argument list and will be "function" or "delegate" for a type
functionToBufferWithIdent(TypeFunction * tf,OutBuffer * buf,const char * ident)3418760c2415Smrg void functionToBufferWithIdent(TypeFunction *tf, OutBuffer *buf, const char *ident)
3419760c2415Smrg {
3420760c2415Smrg HdrGenState hgs;
3421760c2415Smrg PrettyPrintVisitor v(buf, &hgs);
3422760c2415Smrg v.visitFuncIdentWithPostfix(tf, ident);
3423760c2415Smrg }
3424760c2415Smrg
toCBuffer(Expression * e,OutBuffer * buf,HdrGenState * hgs)3425760c2415Smrg void toCBuffer(Expression *e, OutBuffer *buf, HdrGenState *hgs)
3426760c2415Smrg {
3427760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3428760c2415Smrg e->accept(&v);
3429760c2415Smrg }
3430760c2415Smrg
3431760c2415Smrg /**************************************************
3432760c2415Smrg * Write out argument types to buf.
3433760c2415Smrg */
argExpTypesToCBuffer(OutBuffer * buf,Expressions * arguments)3434760c2415Smrg void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments)
3435760c2415Smrg {
3436760c2415Smrg if (!arguments || !arguments->dim)
3437760c2415Smrg return;
3438760c2415Smrg
3439760c2415Smrg HdrGenState hgs;
3440760c2415Smrg PrettyPrintVisitor v(buf, &hgs);
3441760c2415Smrg for (size_t i = 0; i < arguments->dim; i++)
3442760c2415Smrg {
3443760c2415Smrg Expression *arg = (*arguments)[i];
3444760c2415Smrg if (i)
3445760c2415Smrg buf->writestring(", ");
3446760c2415Smrg v.typeToBuffer(arg->type, NULL);
3447760c2415Smrg }
3448760c2415Smrg }
3449760c2415Smrg
toCBuffer(TemplateParameter * tp,OutBuffer * buf,HdrGenState * hgs)3450760c2415Smrg void toCBuffer(TemplateParameter *tp, OutBuffer *buf, HdrGenState *hgs)
3451760c2415Smrg {
3452760c2415Smrg PrettyPrintVisitor v(buf, hgs);
3453760c2415Smrg tp->accept(&v);
3454760c2415Smrg }
3455760c2415Smrg
arrayObjectsToBuffer(OutBuffer * buf,Objects * objects)3456760c2415Smrg void arrayObjectsToBuffer(OutBuffer *buf, Objects *objects)
3457760c2415Smrg {
3458760c2415Smrg if (!objects || !objects->dim)
3459760c2415Smrg return;
3460760c2415Smrg
3461760c2415Smrg HdrGenState hgs;
3462760c2415Smrg PrettyPrintVisitor v(buf, &hgs);
3463760c2415Smrg for (size_t i = 0; i < objects->dim; i++)
3464760c2415Smrg {
3465760c2415Smrg RootObject *o = (*objects)[i];
3466760c2415Smrg if (i)
3467760c2415Smrg buf->writestring(", ");
3468760c2415Smrg v.objectToBuffer(o);
3469760c2415Smrg }
3470760c2415Smrg }
3471760c2415Smrg
parametersTypeToChars(Parameters * parameters,int varargs)3472760c2415Smrg const char *parametersTypeToChars(Parameters *parameters, int varargs)
3473760c2415Smrg {
3474760c2415Smrg OutBuffer buf;
3475760c2415Smrg HdrGenState hgs;
3476760c2415Smrg PrettyPrintVisitor v(&buf, &hgs);
3477760c2415Smrg v.parametersToBuffer(parameters, varargs);
3478760c2415Smrg return buf.extractString();
3479760c2415Smrg }
3480