xref: /netbsd/external/gpl3/gcc.old/dist/gcc/d/dmd/hdrgen.c (revision 0bfacb9b)
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