2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
4 * written by Dave Fladebo
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/hdrgen.c
11 // Routines to emit header files
13 #include "root/dsystem.h"
14 #include "root/rmem.h"
29 #include "staticassert.h"
35 #include "declaration.h"
36 #include "aggregate.h"
37 #include "expression.h"
39 #include "statement.h"
40 #include "aliasthis.h"
44 void linkageToBuffer(OutBuffer
*buf
, LINK linkage
);
45 void MODtoBuffer(OutBuffer
*buf
, MOD mod
);
47 void genhdrfile(Module
*m
)
52 buf
.printf("// D import file generated from '%s'", m
->srcfile
->toChars());
58 toCBuffer(m
, &buf
, &hgs
);
60 // Transfer image to file
61 m
->hdrfile
->setbuffer(buf
.data
, buf
.offset
);
64 ensurePathToNameExists(Loc(), m
->hdrfile
->toChars());
65 writeFile(m
->loc
, m
->hdrfile
);
69 * Dumps the full contents of module `m` to `buf`.
71 * buf = buffer to write to.
72 * m = module to visit all members of.
74 void moduleToBuffer(OutBuffer
*buf
, Module
*m
)
78 toCBuffer(m
, buf
, &hgs
);
81 class PrettyPrintVisitor
: public Visitor
86 bool declstring
; // set while declaring alias for string,wstring or dstring
87 EnumDeclaration
*inEnumDecl
;
89 PrettyPrintVisitor(OutBuffer
*buf
, HdrGenState
*hgs
)
90 : buf(buf
), hgs(hgs
), declstring(false), inEnumDecl(NULL
)
94 void visit(Statement
*)
96 buf
->printf("Statement::toCBuffer()");
101 void visit(ErrorStatement
*)
103 buf
->printf("__error__");
107 void visit(ExpStatement
*s
)
109 if (s
->exp
&& s
->exp
->op
== TOKdeclaration
)
111 // bypass visit(DeclarationExp)
112 ((DeclarationExp
*)s
->exp
)->declaration
->accept(this);
116 s
->exp
->accept(this);
118 if (!hgs
->forStmtInit
)
122 void visit(CompileStatement
*s
)
124 buf
->writestring("mixin(");
125 s
->exp
->accept(this);
126 buf
->writestring(");");
127 if (!hgs
->forStmtInit
)
131 void visit(CompoundStatement
*s
)
133 for (size_t i
= 0; i
< s
->statements
->length
; i
++)
135 Statement
*sx
= (*s
->statements
)[i
];
141 void visit(CompoundDeclarationStatement
*s
)
143 bool anywritten
= false;
144 for (size_t i
= 0; i
< s
->statements
->length
; i
++)
146 Statement
*sx
= (*s
->statements
)[i
];
147 ExpStatement
*ds
= sx
? sx
->isExpStatement() : NULL
;
148 if (ds
&& ds
->exp
->op
== TOKdeclaration
)
150 Dsymbol
*d
= ((DeclarationExp
*)ds
->exp
)->declaration
;
151 assert(d
->isDeclaration());
152 if (VarDeclaration
*v
= d
->isVarDeclaration())
153 visitVarDecl(v
, anywritten
);
160 if (!hgs
->forStmtInit
)
164 void visit(UnrolledLoopStatement
*s
)
166 buf
->writestring("unrolled {");
170 for (size_t i
= 0; i
< s
->statements
->length
; i
++)
172 Statement
*sx
= (*s
->statements
)[i
];
182 void visit(ScopeStatement
*s
)
189 s
->statement
->accept(this);
196 void visit(WhileStatement
*s
)
198 buf
->writestring("while (");
199 s
->condition
->accept(this);
203 s
->_body
->accept(this);
206 void visit(DoStatement
*s
)
208 buf
->writestring("do");
211 s
->_body
->accept(this);
212 buf
->writestring("while (");
213 s
->condition
->accept(this);
214 buf
->writestring(");");
218 void visit(ForStatement
*s
)
220 buf
->writestring("for (");
224 s
->_init
->accept(this);
232 s
->condition
->accept(this);
238 s
->increment
->accept(this);
246 s
->_body
->accept(this);
252 void foreachWithoutBody(ForeachStatement
*s
)
254 buf
->writestring(Token::toChars(s
->op
));
255 buf
->writestring(" (");
256 for (size_t i
= 0; i
< s
->parameters
->length
; i
++)
258 Parameter
*p
= (*s
->parameters
)[i
];
260 buf
->writestring(", ");
261 if (stcToBuffer(buf
, p
->storageClass
))
264 typeToBuffer(p
->type
, p
->ident
);
266 buf
->writestring(p
->ident
->toChars());
268 buf
->writestring("; ");
269 s
->aggr
->accept(this);
274 void visit(ForeachStatement
*s
)
276 foreachWithoutBody(s
);
281 s
->_body
->accept(this);
287 void foreachRangeWithoutBody(ForeachRangeStatement
*s
)
289 buf
->writestring(Token::toChars(s
->op
));
290 buf
->writestring(" (");
293 typeToBuffer(s
->prm
->type
, s
->prm
->ident
);
295 buf
->writestring(s
->prm
->ident
->toChars());
297 buf
->writestring("; ");
298 s
->lwr
->accept(this);
299 buf
->writestring(" .. ");
300 s
->upr
->accept(this);
307 void visit(ForeachRangeStatement
*s
)
309 foreachRangeWithoutBody(s
);
312 s
->_body
->accept(this);
318 void visit(StaticForeachStatement
*s
)
320 buf
->writestring("static ");
323 visit(s
->sfe
->aggrfe
);
327 assert(s
->sfe
->rangefe
);
328 visit(s
->sfe
->rangefe
);
332 void visit(IfStatement
*s
)
334 buf
->writestring("if (");
335 if (Parameter
*p
= s
->prm
)
337 StorageClass stc
= p
->storageClass
;
338 if (!p
->type
&& !stc
)
340 if (stcToBuffer(buf
, stc
))
343 typeToBuffer(p
->type
, p
->ident
);
345 buf
->writestring(p
->ident
->toChars());
346 buf
->writestring(" = ");
348 s
->condition
->accept(this);
351 if (s
->ifbody
->isScopeStatement())
353 s
->ifbody
->accept(this);
358 s
->ifbody
->accept(this);
363 buf
->writestring("else");
364 if (!s
->elsebody
->isIfStatement())
372 if (s
->elsebody
->isScopeStatement() || s
->elsebody
->isIfStatement())
374 s
->elsebody
->accept(this);
379 s
->elsebody
->accept(this);
385 void visit(ConditionalStatement
*s
)
387 s
->condition
->accept(this);
393 s
->ifbody
->accept(this);
399 buf
->writestring("else");
404 s
->elsebody
->accept(this);
411 void visit(PragmaStatement
*s
)
413 buf
->writestring("pragma (");
414 buf
->writestring(s
->ident
->toChars());
415 if (s
->args
&& s
->args
->length
)
417 buf
->writestring(", ");
418 argsToBuffer(s
->args
);
428 s
->_body
->accept(this);
441 void visit(StaticAssertStatement
*s
)
446 void visit(SwitchStatement
*s
)
448 buf
->writestring(s
->isFinal
? "final switch (" : "switch (");
449 s
->condition
->accept(this);
454 if (!s
->_body
->isScopeStatement())
459 s
->_body
->accept(this);
466 s
->_body
->accept(this);
471 void visit(CaseStatement
*s
)
473 buf
->writestring("case ");
474 s
->exp
->accept(this);
477 s
->statement
->accept(this);
480 void visit(CaseRangeStatement
*s
)
482 buf
->writestring("case ");
483 s
->first
->accept(this);
484 buf
->writestring(": .. case ");
485 s
->last
->accept(this);
488 s
->statement
->accept(this);
491 void visit(DefaultStatement
*s
)
493 buf
->writestring("default:");
495 s
->statement
->accept(this);
498 void visit(GotoDefaultStatement
*)
500 buf
->writestring("goto default;");
504 void visit(GotoCaseStatement
*s
)
506 buf
->writestring("goto case");
510 s
->exp
->accept(this);
516 void visit(SwitchErrorStatement
*)
518 buf
->writestring("SwitchErrorStatement::toCBuffer()");
522 void visit(ReturnStatement
*s
)
524 buf
->printf("return ");
526 s
->exp
->accept(this);
531 void visit(BreakStatement
*s
)
533 buf
->writestring("break");
537 buf
->writestring(s
->ident
->toChars());
543 void visit(ContinueStatement
*s
)
545 buf
->writestring("continue");
549 buf
->writestring(s
->ident
->toChars());
555 void visit(SynchronizedStatement
*s
)
557 buf
->writestring("synchronized");
561 s
->exp
->accept(this);
567 s
->_body
->accept(this);
571 void visit(WithStatement
*s
)
573 buf
->writestring("with (");
574 s
->exp
->accept(this);
575 buf
->writestring(")");
578 s
->_body
->accept(this);
581 void visit(TryCatchStatement
*s
)
583 buf
->writestring("try");
586 s
->_body
->accept(this);
587 for (size_t i
= 0; i
< s
->catches
->length
; i
++)
589 Catch
*c
= (*s
->catches
)[i
];
594 void visit(TryFinallyStatement
*s
)
596 buf
->writestring("try");
601 s
->_body
->accept(this);
605 buf
->writestring("finally");
607 if (s
->finalbody
->isScopeStatement())
609 s
->finalbody
->accept(this);
614 s
->finalbody
->accept(this);
621 void visit(OnScopeStatement
*s
)
623 buf
->writestring(Token::toChars(s
->tok
));
625 s
->statement
->accept(this);
628 void visit(ThrowStatement
*s
)
630 buf
->printf("throw ");
631 s
->exp
->accept(this);
636 void visit(DebugStatement
*s
)
640 s
->statement
->accept(this);
644 void visit(GotoStatement
*s
)
646 buf
->writestring("goto ");
647 buf
->writestring(s
->ident
->toChars());
652 void visit(LabelStatement
*s
)
654 buf
->writestring(s
->ident
->toChars());
658 s
->statement
->accept(this);
661 void visit(AsmStatement
*s
)
663 buf
->writestring("asm { ");
664 Token
*t
= s
->tokens
;
668 buf
->writestring(t
->toChars());
670 t
->value
!= TOKmin
&&
671 t
->value
!= TOKcomma
&& t
->next
->value
!= TOKcomma
&&
672 t
->value
!= TOKlbracket
&& t
->next
->value
!= TOKlbracket
&&
673 t
->next
->value
!= TOKrbracket
&&
674 t
->value
!= TOKlparen
&& t
->next
->value
!= TOKlparen
&&
675 t
->next
->value
!= TOKrparen
&&
676 t
->value
!= TOKdot
&& t
->next
->value
!= TOKdot
)
683 buf
->writestring("; }");
687 void visit(ImportStatement
*s
)
689 for (size_t i
= 0; i
< s
->imports
->length
; i
++)
691 Dsymbol
*imp
= (*s
->imports
)[i
];
698 buf
->writestring("catch");
702 typeToBuffer(c
->type
, c
->ident
);
710 c
->handler
->accept(this);
716 ////////////////////////////////////////////////////////////////////////////
718 /**************************************************
719 * An entry point to pretty-print type.
721 void typeToBuffer(Type
*t
, Identifier
*ident
)
723 if (t
->ty
== Tfunction
)
725 visitFuncIdentWithPrefix((TypeFunction
*)t
, ident
, NULL
);
734 buf
->writestring(ident
->toChars());
738 void visitWithMask(Type
*t
, unsigned char modMask
)
740 // Tuples and functions don't use the type constructor syntax
741 if (modMask
== t
->mod
||
742 t
->ty
== Tfunction
||
749 unsigned char m
= t
->mod
& ~(t
->mod
& modMask
);
752 MODtoBuffer(buf
, MODshared
);
757 MODtoBuffer(buf
, MODwild
);
760 if (m
& (MODconst
| MODimmutable
))
762 MODtoBuffer(buf
, m
& (MODconst
| MODimmutable
));
768 if (m
& (MODconst
| MODimmutable
))
779 printf("t = %p, ty = %d\n", t
, t
->ty
);
783 void visit(TypeError
*)
785 buf
->writestring("_error_");
788 void visit(TypeBasic
*t
)
790 //printf("TypeBasic::toCBuffer2(t->mod = %d)\n", t->mod);
791 buf
->writestring(t
->dstring
);
794 void visit(TypeTraits
*t
)
796 //printf("TypeBasic::toCBuffer2(t.mod = %d)\n", t.mod);
797 t
->exp
->accept(this);
800 void visit(TypeVector
*t
)
802 //printf("TypeVector::toCBuffer2(t->mod = %d)\n", t->mod);
803 buf
->writestring("__vector(");
804 visitWithMask(t
->basetype
, t
->mod
);
805 buf
->writestring(")");
808 void visit(TypeSArray
*t
)
810 visitWithMask(t
->next
, t
->mod
);
812 sizeToBuffer(t
->dim
);
816 void visit(TypeDArray
*t
)
818 Type
*ut
= t
->castMod(0);
821 if (ut
->equals(Type::tstring
))
822 buf
->writestring("string");
823 else if (ut
->equals(Type::twstring
))
824 buf
->writestring("wstring");
825 else if (ut
->equals(Type::tdstring
))
826 buf
->writestring("dstring");
830 visitWithMask(t
->next
, t
->mod
);
831 buf
->writestring("[]");
835 void visit(TypeAArray
*t
)
837 visitWithMask(t
->next
, t
->mod
);
839 visitWithMask(t
->index
, 0);
843 void visit(TypePointer
*t
)
845 //printf("TypePointer::toCBuffer2() next = %d\n", t->next->ty);
846 if (t
->next
->ty
== Tfunction
)
847 visitFuncIdentWithPostfix((TypeFunction
*)t
->next
, "function");
850 visitWithMask(t
->next
, t
->mod
);
855 void visit(TypeReference
*t
)
857 visitWithMask(t
->next
, t
->mod
);
861 void visit(TypeFunction
*t
)
863 //printf("TypeFunction::toCBuffer2() t = %p, ref = %d\n", t, t->isref);
864 visitFuncIdentWithPostfix(t
, NULL
);
867 // callback for TypeFunction::attributesApply
868 struct PrePostAppendStrings
874 static int fp(void *param
, const char *str
)
876 PrePostAppendStrings
*p
= (PrePostAppendStrings
*)param
;
878 // don't write 'ref' for ctors
879 if (p
->isCtor
&& strcmp(str
, "ref") == 0)
882 if ( p
->isPostfixStyle
) p
->buf
->writeByte(' ');
883 p
->buf
->writestring(str
);
884 if (!p
->isPostfixStyle
) p
->buf
->writeByte(' ');
889 void visitFuncIdentWithPostfix(TypeFunction
*t
, const char *ident
)
893 t
->inuse
= 2; // flag error to caller
898 PrePostAppendStrings pas
;
901 pas
.isPostfixStyle
= true;
903 if (t
->linkage
> LINKd
&& hgs
->ddoc
!= 1 && !hgs
->hdrgen
)
905 linkageToBuffer(buf
, t
->linkage
);
911 typeToBuffer(t
->next
, NULL
);
916 buf
->writestring("auto ");
919 buf
->writestring(ident
);
921 parametersToBuffer(t
->parameterList
.parameters
, t
->parameterList
.varargs
);
923 /* Use postfix style for attributes
928 MODtoBuffer(buf
, t
->mod
);
930 t
->attributesApply(&pas
, &PrePostAppendStrings::fp
);
934 void visitFuncIdentWithPrefix(TypeFunction
*t
, Identifier
*ident
, TemplateDeclaration
*td
)
938 t
->inuse
= 2; // flag error to caller
943 PrePostAppendStrings pas
;
945 pas
.isCtor
= (ident
== Id::ctor
);
946 pas
.isPostfixStyle
= false;
948 /* Use 'storage class' (prefix) style for attributes
952 MODtoBuffer(buf
, t
->mod
);
955 t
->attributesApply(&pas
, &PrePostAppendStrings::fp
);
957 if (t
->linkage
> LINKd
&& hgs
->ddoc
!= 1 && !hgs
->hdrgen
)
959 linkageToBuffer(buf
, t
->linkage
);
963 if (ident
&& ident
->toHChars2() != ident
->toChars())
965 // Don't print return type for ctor, dtor, unittest, etc
969 typeToBuffer(t
->next
, NULL
);
974 buf
->writestring("auto ");
977 buf
->writestring(ident
->toHChars2());
982 for (size_t i
= 0; i
< td
->origParameters
->length
; i
++)
984 TemplateParameter
*p
= (*td
->origParameters
)[i
];
986 buf
->writestring(", ");
991 parametersToBuffer(t
->parameterList
.parameters
, t
->parameterList
.varargs
);
996 void visit(TypeDelegate
*t
)
998 visitFuncIdentWithPostfix((TypeFunction
*)t
->next
, "delegate");
1001 void visitTypeQualifiedHelper(TypeQualified
*t
)
1003 for (size_t i
= 0; i
< t
->idents
.length
; i
++)
1005 RootObject
*id
= t
->idents
[i
];
1007 if (id
->dyncast() == DYNCAST_DSYMBOL
)
1009 buf
->writeByte('.');
1010 TemplateInstance
*ti
= (TemplateInstance
*)id
;
1013 else if (id
->dyncast() == DYNCAST_EXPRESSION
)
1015 buf
->writeByte('[');
1016 ((Expression
*)id
)->accept(this);
1017 buf
->writeByte(']');
1019 else if (id
->dyncast() == DYNCAST_TYPE
)
1021 buf
->writeByte('[');
1022 ((Type
*)id
)->accept(this);
1023 buf
->writeByte(']');
1027 buf
->writeByte('.');
1028 buf
->writestring(id
->toChars());
1033 void visit(TypeIdentifier
*t
)
1035 buf
->writestring(t
->ident
->toChars());
1036 visitTypeQualifiedHelper(t
);
1039 void visit(TypeInstance
*t
)
1041 t
->tempinst
->accept(this);
1042 visitTypeQualifiedHelper(t
);
1045 void visit(TypeTypeof
*t
)
1047 buf
->writestring("typeof(");
1048 t
->exp
->accept(this);
1049 buf
->writeByte(')');
1050 visitTypeQualifiedHelper(t
);
1053 void visit(TypeReturn
*t
)
1055 buf
->writestring("typeof(return)");
1056 visitTypeQualifiedHelper(t
);
1059 void visit(TypeEnum
*t
)
1061 buf
->writestring(t
->sym
->toChars());
1064 void visit(TypeStruct
*t
)
1066 // Bugzilla 13776: Don't use ti->toAlias() to avoid forward reference error
1067 // while printing messages.
1068 TemplateInstance
*ti
= t
->sym
->parent
? t
->sym
->parent
->isTemplateInstance() : NULL
;
1069 if (ti
&& ti
->aliasdecl
== t
->sym
)
1070 buf
->writestring(hgs
->fullQual
? ti
->toPrettyChars() : ti
->toChars());
1072 buf
->writestring(hgs
->fullQual
? t
->sym
->toPrettyChars() : t
->sym
->toChars());
1075 void visit(TypeClass
*t
)
1077 // Bugzilla 13776: Don't use ti->toAlias() to avoid forward reference error
1078 // while printing messages.
1079 TemplateInstance
*ti
= t
->sym
->parent
->isTemplateInstance();
1080 if (ti
&& ti
->aliasdecl
== t
->sym
)
1081 buf
->writestring(hgs
->fullQual
? ti
->toPrettyChars() : ti
->toChars());
1083 buf
->writestring(hgs
->fullQual
? t
->sym
->toPrettyChars() : t
->sym
->toChars());
1086 void visit(TypeTuple
*t
)
1088 parametersToBuffer(t
->arguments
, 0);
1091 void visit(TypeSlice
*t
)
1093 visitWithMask(t
->next
, t
->mod
);
1095 buf
->writeByte('[');
1096 sizeToBuffer(t
->lwr
);
1097 buf
->writestring(" .. ");
1098 sizeToBuffer(t
->upr
);
1099 buf
->writeByte(']');
1102 void visit(TypeNull
*)
1104 buf
->writestring("typeof(null)");
1107 ////////////////////////////////////////////////////////////////////////////
1109 void visit(Dsymbol
*s
)
1111 buf
->writestring(s
->toChars());
1114 void visit(StaticAssert
*s
)
1116 buf
->writestring(s
->kind());
1117 buf
->writeByte('(');
1118 s
->exp
->accept(this);
1121 buf
->writestring(", ");
1122 s
->msg
->accept(this);
1124 buf
->writestring(");");
1128 void visit(DebugSymbol
*s
)
1130 buf
->writestring("debug = ");
1132 buf
->writestring(s
->ident
->toChars());
1134 buf
->printf("%u", s
->level
);
1135 buf
->writestring(";");
1139 void visit(VersionSymbol
*s
)
1141 buf
->writestring("version = ");
1143 buf
->writestring(s
->ident
->toChars());
1145 buf
->printf("%u", s
->level
);
1146 buf
->writestring(";");
1150 void visit(EnumMember
*em
)
1153 typeToBuffer(em
->type
, em
->ident
);
1155 buf
->writestring(em
->ident
->toChars());
1158 buf
->writestring(" = ");
1159 em
->value()->accept(this);
1163 void visit(Import
*imp
)
1165 if (hgs
->hdrgen
&& imp
->id
== Id::object
)
1166 return; // object is imported by default
1169 buf
->writestring("static ");
1170 buf
->writestring("import ");
1173 buf
->printf("%s = ", imp
->aliasId
->toChars());
1175 if (imp
->packages
&& imp
->packages
->length
)
1177 for (size_t i
= 0; i
< imp
->packages
->length
; i
++)
1179 Identifier
*pid
= (*imp
->packages
)[i
];
1180 buf
->printf("%s.", pid
->toChars());
1183 buf
->printf("%s", imp
->id
->toChars());
1184 if (imp
->names
.length
)
1186 buf
->writestring(" : ");
1187 for (size_t i
= 0; i
< imp
->names
.length
; i
++)
1190 buf
->writestring(", ");
1192 Identifier
*name
= imp
->names
[i
];
1193 Identifier
*alias
= imp
->aliases
[i
];
1195 buf
->printf("%s = %s", alias
->toChars(), name
->toChars());
1197 buf
->printf("%s", name
->toChars());
1204 void visit(AliasThis
*d
)
1206 buf
->writestring("alias ");
1207 buf
->writestring(d
->ident
->toChars());
1208 buf
->writestring(" this;\n");
1211 void visit(AttribDeclaration
*d
)
1215 buf
->writeByte(';');
1220 if (d
->decl
->length
== 0)
1221 buf
->writestring("{}");
1222 else if (hgs
->hdrgen
&& d
->decl
->length
== 1 && (*d
->decl
)[0]->isUnitTestDeclaration())
1224 // hack for bugzilla 8081
1225 buf
->writestring("{}");
1227 else if (d
->decl
->length
== 1)
1229 ((*d
->decl
)[0])->accept(this);
1235 buf
->writeByte('{');
1238 for (size_t i
= 0; i
< d
->decl
->length
; i
++)
1240 Dsymbol
*de
= (*d
->decl
)[i
];
1244 buf
->writeByte('}');
1249 void visit(StorageClassDeclaration
*d
)
1251 if (stcToBuffer(buf
, d
->stc
))
1252 buf
->writeByte(' ');
1253 visit((AttribDeclaration
*)d
);
1256 void visit(DeprecatedDeclaration
*d
)
1258 buf
->writestring("deprecated(");
1259 d
->msg
->accept(this);
1260 buf
->writestring(") ");
1261 visit((AttribDeclaration
*)d
);
1264 void visit(LinkDeclaration
*d
)
1270 case LINKd
: p
= "D"; break;
1271 case LINKc
: p
= "C"; break;
1272 case LINKcpp
: p
= "C++"; break;
1273 case LINKwindows
: p
= "Windows"; break;
1274 case LINKpascal
: p
= "Pascal"; break;
1275 case LINKobjc
: p
= "Objective-C"; break;
1280 buf
->writestring("extern (");
1281 buf
->writestring(p
);
1282 buf
->writestring(") ");
1283 visit((AttribDeclaration
*)d
);
1286 void visit(CPPMangleDeclaration
*d
)
1290 switch (d
->cppmangle
)
1292 case CPPMANGLEclass
: p
= "class"; break;
1293 case CPPMANGLEstruct
: p
= "struct"; break;
1298 buf
->writestring("extern (C++, ");
1299 buf
->writestring(p
);
1300 buf
->writestring(") ");
1301 visit((AttribDeclaration
*)d
);
1304 void visit(ProtDeclaration
*d
)
1306 protectionToBuffer(buf
, d
->protection
);
1307 buf
->writeByte(' ');
1308 visit((AttribDeclaration
*)d
);
1311 void visit(AlignDeclaration
*d
)
1314 buf
->printf("align ");
1316 buf
->printf("align (%s)", d
->ealign
->toChars());
1317 visit((AttribDeclaration
*)d
);
1320 void visit(AnonDeclaration
*d
)
1322 buf
->printf(d
->isunion
? "union" : "struct");
1324 buf
->writestring("{");
1329 for (size_t i
= 0; i
< d
->decl
->length
; i
++)
1331 Dsymbol
*de
= (*d
->decl
)[i
];
1336 buf
->writestring("}");
1340 void visit(PragmaDeclaration
*d
)
1342 buf
->printf("pragma (%s", d
->ident
->toChars());
1343 if (d
->args
&& d
->args
->length
)
1345 buf
->writestring(", ");
1346 argsToBuffer(d
->args
);
1348 buf
->writeByte(')');
1349 visit((AttribDeclaration
*)d
);
1352 void visit(ConditionalDeclaration
*d
)
1354 d
->condition
->accept(this);
1355 if (d
->decl
|| d
->elsedecl
)
1358 buf
->writeByte('{');
1363 for (size_t i
= 0; i
< d
->decl
->length
; i
++)
1365 Dsymbol
*de
= (*d
->decl
)[i
];
1370 buf
->writeByte('}');
1374 buf
->writestring("else");
1376 buf
->writeByte('{');
1379 for (size_t i
= 0; i
< d
->elsedecl
->length
; i
++)
1381 Dsymbol
*de
= (*d
->elsedecl
)[i
];
1385 buf
->writeByte('}');
1389 buf
->writeByte(':');
1393 void visit(ForwardingStatement
*s
)
1395 s
->statement
->accept(this);
1398 void visit(StaticForeachDeclaration
*s
)
1400 buf
->writestring("static ");
1403 foreachWithoutBody(s
->sfe
->aggrfe
);
1407 assert(s
->sfe
->rangefe
);
1408 foreachRangeWithoutBody(s
->sfe
->rangefe
);
1410 buf
->writeByte('{');
1413 visit((AttribDeclaration
*)s
);
1415 buf
->writeByte('}');
1419 void visit(CompileDeclaration
*d
)
1421 buf
->writestring("mixin(");
1422 d
->exp
->accept(this);
1423 buf
->writestring(");");
1427 void visit(UserAttributeDeclaration
*d
)
1429 buf
->writestring("@(");
1430 argsToBuffer(d
->atts
);
1431 buf
->writeByte(')');
1432 visit((AttribDeclaration
*)d
);
1435 void visit(TemplateDeclaration
*d
)
1437 if ((hgs
->hdrgen
|| hgs
->fullDump
) && visitEponymousMember(d
))
1441 buf
->writestring(d
->kind());
1443 buf
->writestring("template");
1444 buf
->writeByte(' ');
1445 buf
->writestring(d
->ident
->toChars());
1446 buf
->writeByte('(');
1447 visitTemplateParameters(hgs
->ddoc
? d
->origParameters
: d
->parameters
);
1448 buf
->writeByte(')');
1449 visitTemplateConstraint(d
->constraint
);
1451 if (hgs
->hdrgen
|| hgs
->fullDump
)
1455 buf
->writeByte('{');
1458 for (size_t i
= 0; i
< d
->members
->length
; i
++)
1460 Dsymbol
*s
= (*d
->members
)[i
];
1464 buf
->writeByte('}');
1470 bool visitEponymousMember(TemplateDeclaration
*d
)
1472 if (!d
->members
|| d
->members
->length
!= 1)
1475 Dsymbol
*onemember
= (*d
->members
)[0];
1476 if (onemember
->ident
!= d
->ident
)
1479 if (FuncDeclaration
*fd
= onemember
->isFuncDeclaration())
1482 if (stcToBuffer(buf
, fd
->storage_class
))
1483 buf
->writeByte(' ');
1484 functionToBufferFull((TypeFunction
*)fd
->type
, buf
, d
->ident
, hgs
, d
);
1485 visitTemplateConstraint(d
->constraint
);
1492 if (AggregateDeclaration
*ad
= onemember
->isAggregateDeclaration())
1494 buf
->writestring(ad
->kind());
1495 buf
->writeByte(' ');
1496 buf
->writestring(ad
->ident
->toChars());
1497 buf
->writeByte('(');
1498 visitTemplateParameters(hgs
->ddoc
? d
->origParameters
: d
->parameters
);
1499 buf
->writeByte(')');
1500 visitTemplateConstraint(d
->constraint
);
1501 visitBaseClasses(ad
->isClassDeclaration());
1507 buf
->writeByte('{');
1510 for (size_t i
= 0; i
< ad
->members
->length
; i
++)
1512 Dsymbol
*s
= (*ad
->members
)[i
];
1516 buf
->writeByte('}');
1519 buf
->writeByte(';');
1524 if (VarDeclaration
*vd
= onemember
->isVarDeclaration())
1529 if (stcToBuffer(buf
, vd
->storage_class
))
1530 buf
->writeByte(' ');
1532 typeToBuffer(vd
->type
, vd
->ident
);
1534 buf
->writestring(vd
->ident
->toChars());
1536 buf
->writeByte('(');
1537 visitTemplateParameters(hgs
->ddoc
? d
->origParameters
: d
->parameters
);
1538 buf
->writeByte(')');
1542 buf
->writestring(" = ");
1543 ExpInitializer
*ie
= vd
->_init
->isExpInitializer();
1544 if (ie
&& (ie
->exp
->op
== TOKconstruct
|| ie
->exp
->op
== TOKblit
))
1545 ((AssignExp
*)ie
->exp
)->e2
->accept(this);
1547 vd
->_init
->accept(this);
1549 buf
->writeByte(';');
1556 void visitTemplateParameters(TemplateParameters
*parameters
)
1558 if (!parameters
|| !parameters
->length
)
1560 for (size_t i
= 0; i
< parameters
->length
; i
++)
1562 TemplateParameter
*p
= (*parameters
)[i
];
1564 buf
->writestring(", ");
1568 void visitTemplateConstraint(Expression
*constraint
)
1572 buf
->writestring(" if (");
1573 constraint
->accept(this);
1574 buf
->writeByte(')');
1577 void visit(TemplateInstance
*ti
)
1579 buf
->writestring(ti
->name
->toChars());
1587 // the ti.aliasDecl is the instantiated body
1588 // if we have it, print it.
1589 ti
->aliasdecl
->accept(this);
1594 void visit(TemplateMixin
*tm
)
1596 buf
->writestring("mixin ");
1598 typeToBuffer(tm
->tqual
, NULL
);
1601 if (tm
->ident
&& memcmp(tm
->ident
->toChars(), "__mixin", 7) != 0)
1603 buf
->writeByte(' ');
1604 buf
->writestring(tm
->ident
->toChars());
1606 buf
->writeByte(';');
1610 void tiargsToBuffer(TemplateInstance
*ti
)
1612 buf
->writeByte('!');
1615 buf
->writestring("(...)");
1620 buf
->writestring("()");
1624 if (ti
->tiargs
->length
== 1)
1626 RootObject
*oarg
= (*ti
->tiargs
)[0];
1627 if (Type
*t
= isType(oarg
))
1629 if (t
->equals(Type::tstring
) ||
1630 t
->equals(Type::twstring
) ||
1631 t
->equals(Type::tdstring
) ||
1633 (t
->isTypeBasic() ||
1634 (t
->ty
== Tident
&& ((TypeIdentifier
*)t
)->idents
.length
== 0))))
1636 buf
->writestring(t
->toChars());
1640 else if (Expression
*e
= isExpression(oarg
))
1642 if (e
->op
== TOKint64
||
1643 e
->op
== TOKfloat64
||
1645 e
->op
== TOKstring
||
1648 buf
->writestring(e
->toChars());
1653 buf
->writeByte('(');
1655 for (size_t i
= 0; i
< ti
->tiargs
->length
; i
++)
1657 RootObject
*arg
= (*ti
->tiargs
)[i
];
1659 buf
->writestring(", ");
1660 objectToBuffer(arg
);
1663 buf
->writeByte(')');
1666 /****************************************
1667 * This makes a 'pretty' version of the template arguments.
1668 * It's analogous to genIdent() which makes a mangled version.
1670 void objectToBuffer(RootObject
*oarg
)
1672 //printf("objectToBuffer()\n");
1674 /* The logic of this should match what genIdent() does. The _dynamic_cast()
1675 * function relies on all the pretty strings to be unique for different classes
1676 * (see Bugzilla 7375).
1677 * Perhaps it would be better to demangle what genIdent() does.
1679 if (Type
*t
= isType(oarg
))
1681 //printf("\tt: %s ty = %d\n", t->toChars(), t->ty);
1682 typeToBuffer(t
, NULL
);
1684 else if (Expression
*e
= isExpression(oarg
))
1686 if (e
->op
== TOKvar
)
1687 e
= e
->optimize(WANTvalue
); // added to fix Bugzilla 7375
1690 else if (Dsymbol
*s
= isDsymbol(oarg
))
1692 const char *p
= s
->ident
? s
->ident
->toChars() : s
->toChars();
1693 buf
->writestring(p
);
1695 else if (Tuple
*v
= isTuple(oarg
))
1697 Objects
*args
= &v
->objects
;
1698 for (size_t i
= 0; i
< args
->length
; i
++)
1700 RootObject
*arg
= (*args
)[i
];
1702 buf
->writestring(", ");
1703 objectToBuffer(arg
);
1708 buf
->writestring("NULL");
1716 void visit(EnumDeclaration
*d
)
1718 EnumDeclaration
*oldInEnumDecl
= inEnumDecl
;
1720 buf
->writestring("enum ");
1723 buf
->writestring(d
->ident
->toChars());
1724 buf
->writeByte(' ');
1728 buf
->writestring(": ");
1729 typeToBuffer(d
->memtype
, NULL
);
1733 buf
->writeByte(';');
1735 inEnumDecl
= oldInEnumDecl
;
1739 buf
->writeByte('{');
1742 for (size_t i
= 0; i
< d
->members
->length
; i
++)
1744 EnumMember
*em
= (*d
->members
)[i
]->isEnumMember();
1748 buf
->writeByte(',');
1752 buf
->writeByte('}');
1754 inEnumDecl
= oldInEnumDecl
;
1757 void visit(Nspace
*d
)
1759 buf
->writestring("extern (C++, ");
1760 buf
->writestring(d
->ident
->toChars());
1761 buf
->writeByte(')');
1763 buf
->writeByte('{');
1766 for (size_t i
= 0; i
< d
->members
->length
; i
++)
1768 Dsymbol
*s
= (*d
->members
)[i
];
1772 buf
->writeByte('}');
1776 void visit(StructDeclaration
*d
)
1778 buf
->printf("%s ", d
->kind());
1779 if (!d
->isAnonymous())
1780 buf
->writestring(d
->toChars());
1783 buf
->writeByte(';');
1788 buf
->writeByte('{');
1791 for (size_t i
= 0; i
< d
->members
->length
; i
++)
1793 Dsymbol
*s
= (*d
->members
)[i
];
1797 buf
->writeByte('}');
1801 void visit(ClassDeclaration
*d
)
1803 if (!d
->isAnonymous())
1805 buf
->writestring(d
->kind());
1806 buf
->writeByte(' ');
1807 buf
->writestring(d
->ident
->toChars());
1809 visitBaseClasses(d
);
1813 buf
->writeByte('{');
1816 for (size_t i
= 0; i
< d
->members
->length
; i
++)
1818 Dsymbol
*s
= (*d
->members
)[i
];
1822 buf
->writeByte('}');
1825 buf
->writeByte(';');
1829 void visitBaseClasses(ClassDeclaration
*d
)
1831 if (!d
|| !d
->baseclasses
->length
)
1834 buf
->writestring(" : ");
1835 for (size_t i
= 0; i
< d
->baseclasses
->length
; i
++)
1838 buf
->writestring(", ");
1839 BaseClass
*b
= (*d
->baseclasses
)[i
];
1840 typeToBuffer(b
->type
, NULL
);
1844 void visit(AliasDeclaration
*d
)
1846 if (d
->storage_class
& STClocal
)
1848 buf
->writestring("alias ");
1851 buf
->writestring(d
->ident
->toChars());
1852 buf
->writestring(" = ");
1853 if (stcToBuffer(buf
, d
->storage_class
))
1854 buf
->writeByte(' ');
1855 d
->aliassym
->accept(this);
1857 else if (d
->type
->ty
== Tfunction
)
1859 if (stcToBuffer(buf
, d
->storage_class
))
1860 buf
->writeByte(' ');
1861 typeToBuffer(d
->type
, d
->ident
);
1865 declstring
= (d
->ident
== Id::string
|| d
->ident
== Id::wstring
|| d
->ident
== Id::dstring
);
1866 buf
->writestring(d
->ident
->toChars());
1867 buf
->writestring(" = ");
1868 if (stcToBuffer(buf
, d
->storage_class
))
1869 buf
->writeByte(' ');
1870 typeToBuffer(d
->type
, NULL
);
1873 buf
->writeByte(';');
1877 void visit(VarDeclaration
*d
)
1879 if (d
->storage_class
& STClocal
)
1881 visitVarDecl(d
, false);
1882 buf
->writeByte(';');
1885 void visitVarDecl(VarDeclaration
*v
, bool anywritten
)
1889 buf
->writestring(", ");
1890 buf
->writestring(v
->ident
->toChars());
1894 if (stcToBuffer(buf
, v
->storage_class
))
1895 buf
->writeByte(' ');
1897 typeToBuffer(v
->type
, v
->ident
);
1899 buf
->writestring(v
->ident
->toChars());
1903 buf
->writestring(" = ");
1904 ExpInitializer
*ie
= v
->_init
->isExpInitializer();
1905 if (ie
&& (ie
->exp
->op
== TOKconstruct
|| ie
->exp
->op
== TOKblit
))
1906 ((AssignExp
*)ie
->exp
)->e2
->accept(this);
1908 v
->_init
->accept(this);
1912 void visit(FuncDeclaration
*f
)
1914 //printf("FuncDeclaration::toCBuffer() '%s'\n", f->toChars());
1916 if (stcToBuffer(buf
, f
->storage_class
))
1917 buf
->writeByte(' ');
1918 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1919 typeToBuffer(tf
, f
->ident
);
1922 // if the return type is missing (e.g. ref functions or auto)
1923 if (!tf
->next
|| f
->storage_class
& STCauto
)
1929 else if (hgs
->tpltMember
== 0 && global
.params
.hdrStripPlainFunctions
)
1931 buf
->writeByte(';');
1941 void bodyToBuffer(FuncDeclaration
*f
)
1943 if (!f
->fbody
|| (hgs
->hdrgen
&& global
.params
.hdrStripPlainFunctions
&& !hgs
->autoMember
&& !hgs
->tpltMember
))
1945 buf
->writeByte(';');
1950 int savetlpt
= hgs
->tpltMember
;
1951 int saveauto
= hgs
->autoMember
;
1952 hgs
->tpltMember
= 0;
1953 hgs
->autoMember
= 0;
1960 buf
->writestring("in");
1962 f
->frequire
->accept(this);
1968 buf
->writestring("out");
1971 buf
->writeByte('(');
1972 buf
->writestring(f
->outId
->toChars());
1973 buf
->writeByte(')');
1976 f
->fensure
->accept(this);
1979 if (f
->frequire
|| f
->fensure
)
1981 buf
->writestring("body");
1985 buf
->writeByte('{');
1988 f
->fbody
->accept(this);
1990 buf
->writeByte('}');
1993 hgs
->tpltMember
= savetlpt
;
1994 hgs
->autoMember
= saveauto
;
1997 void visit(FuncLiteralDeclaration
*f
)
1999 if (f
->type
->ty
== Terror
)
2001 buf
->writestring("__error");
2005 if (f
->tok
!= TOKreserved
)
2007 buf
->writestring(f
->kind());
2008 buf
->writeByte(' ');
2011 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
2012 // Don't print tf->mod, tf->trust, and tf->linkage
2013 if (!f
->inferRetType
&& tf
->next
)
2014 typeToBuffer(tf
->next
, NULL
);
2015 parametersToBuffer(tf
->parameterList
.parameters
, tf
->parameterList
.varargs
);
2017 CompoundStatement
*cs
= f
->fbody
->isCompoundStatement();
2019 if (f
->semanticRun
>= PASSsemantic3done
&& cs
)
2021 s1
= (*cs
->statements
)[cs
->statements
->length
- 1];
2024 s1
= !cs
? f
->fbody
: NULL
;
2025 ReturnStatement
*rs
= s1
? s1
->isReturnStatement() : NULL
;
2028 buf
->writestring(" => ");
2029 rs
->exp
->accept(this);
2039 void visit(PostBlitDeclaration
*d
)
2041 if (stcToBuffer(buf
, d
->storage_class
))
2042 buf
->writeByte(' ');
2043 buf
->writestring("this(this)");
2047 void visit(DtorDeclaration
*d
)
2049 if (d
->storage_class
& STCtrusted
)
2050 buf
->writestring("@trusted ");
2051 if (d
->storage_class
& STCsafe
)
2052 buf
->writestring("@safe ");
2053 if (d
->storage_class
& STCnogc
)
2054 buf
->writestring("@nogc ");
2055 if (d
->storage_class
& STCdisable
)
2056 buf
->writestring("@disable ");
2058 buf
->writestring("~this()");
2062 void visit(StaticCtorDeclaration
*d
)
2064 if (stcToBuffer(buf
, d
->storage_class
& ~STCstatic
))
2065 buf
->writeByte(' ');
2066 if (d
->isSharedStaticCtorDeclaration())
2067 buf
->writestring("shared ");
2068 buf
->writestring("static this()");
2069 if (hgs
->hdrgen
&& !hgs
->tpltMember
)
2071 buf
->writeByte(';');
2078 void visit(StaticDtorDeclaration
*d
)
2082 if (stcToBuffer(buf
, d
->storage_class
& ~STCstatic
))
2083 buf
->writeByte(' ');
2084 if (d
->isSharedStaticDtorDeclaration())
2085 buf
->writestring("shared ");
2086 buf
->writestring("static ~this()");
2090 void visit(InvariantDeclaration
*d
)
2094 if (stcToBuffer(buf
, d
->storage_class
))
2095 buf
->writeByte(' ');
2096 buf
->writestring("invariant");
2100 void visit(UnitTestDeclaration
*d
)
2104 if (stcToBuffer(buf
, d
->storage_class
))
2105 buf
->writeByte(' ');
2106 buf
->writestring("unittest");
2110 void visit(NewDeclaration
*d
)
2112 if (stcToBuffer(buf
, d
->storage_class
& ~STCstatic
))
2113 buf
->writeByte(' ');
2114 buf
->writestring("new");
2115 parametersToBuffer(d
->parameters
, d
->varargs
);
2119 void visit(DeleteDeclaration
*d
)
2121 if (stcToBuffer(buf
, d
->storage_class
& ~STCstatic
))
2122 buf
->writeByte(' ');
2123 buf
->writestring("delete");
2124 parametersToBuffer(d
->parameters
, 0);
2128 ////////////////////////////////////////////////////////////////////////////
2130 void visit(ErrorInitializer
*)
2132 buf
->writestring("__error__");
2135 void visit(VoidInitializer
*)
2137 buf
->writestring("void");
2140 void visit(StructInitializer
*si
)
2142 //printf("StructInitializer::toCBuffer()\n");
2143 buf
->writeByte('{');
2144 for (size_t i
= 0; i
< si
->field
.length
; i
++)
2147 buf
->writestring(", ");
2148 if (Identifier
*id
= si
->field
[i
])
2150 buf
->writestring(id
->toChars());
2151 buf
->writeByte(':');
2153 if (Initializer
*iz
= si
->value
[i
])
2156 buf
->writeByte('}');
2159 void visit(ArrayInitializer
*ai
)
2161 buf
->writeByte('[');
2162 for (size_t i
= 0; i
< ai
->index
.length
; i
++)
2165 buf
->writestring(", ");
2166 if (Expression
*ex
= ai
->index
[i
])
2169 buf
->writeByte(':');
2171 if (Initializer
*iz
= ai
->value
[i
])
2174 buf
->writeByte(']');
2177 void visit(ExpInitializer
*ei
)
2179 ei
->exp
->accept(this);
2182 ////////////////////////////////////////////////////////////////////////////
2184 /**************************************************
2185 * Write out argument list to buf.
2187 void argsToBuffer(Expressions
*expressions
, Expression
*basis
= NULL
)
2189 if (!expressions
|| !expressions
->length
)
2192 for (size_t i
= 0; i
< expressions
->length
; i
++)
2194 Expression
*el
= (*expressions
)[i
];
2196 buf
->writestring(", ");
2200 expToBuffer(el
, PREC_assign
);
2204 void sizeToBuffer(Expression
*e
)
2206 if (e
->type
== Type::tsize_t
)
2208 Expression
*ex
= (e
->op
== TOKcast
? ((CastExp
*)e
)->e1
: e
);
2209 ex
= ex
->optimize(WANTvalue
);
2211 dinteger_t uval
= ex
->op
== TOKint64
? ex
->toInteger() : (dinteger_t
)-1;
2212 if ((sinteger_t
)uval
>= 0)
2215 if (target
.ptrsize
== 8)
2216 sizemax
= 0xFFFFFFFFFFFFFFFFULL
;
2217 else if (target
.ptrsize
== 4)
2218 sizemax
= 0xFFFFFFFFUL
;
2219 else if (target
.ptrsize
== 2)
2223 if (uval
<= sizemax
&& uval
<= 0x7FFFFFFFFFFFFFFFULL
)
2225 buf
->printf("%llu", uval
);
2230 expToBuffer(e
, PREC_assign
);
2233 /**************************************************
2234 * Write expression out to buf, but wrap it
2235 * in ( ) if its precedence is less than pr.
2237 void expToBuffer(Expression
*e
, PREC pr
)
2239 assert(precedence
[e
->op
] != PREC_zero
);
2240 assert(pr
!= PREC_zero
);
2242 //if (precedence[e->op] == 0) e->print();
2243 /* Despite precedence, we don't allow a<b<c expressions.
2244 * They must be parenthesized.
2246 if (precedence
[e
->op
] < pr
||
2247 (pr
== PREC_rel
&& precedence
[e
->op
] == pr
))
2249 buf
->writeByte('(');
2251 buf
->writeByte(')');
2257 void visit(Expression
*e
)
2259 buf
->writestring(Token::toChars(e
->op
));
2262 void visit(IntegerExp
*e
)
2264 dinteger_t v
= e
->toInteger();
2274 TypeEnum
*te
= (TypeEnum
*)t
;
2277 EnumDeclaration
*sym
= te
->sym
;
2278 if (inEnumDecl
!= sym
)
2280 for (size_t i
= 0; i
< sym
->members
->length
; i
++)
2282 EnumMember
*em
= (EnumMember
*)(*sym
->members
)[i
];
2283 if (em
->value()->toInteger() == v
)
2285 buf
->printf("%s.%s", sym
->toChars(), em
->ident
->toChars());
2291 buf
->printf("cast(%s)", te
->sym
->toChars());
2292 t
= te
->sym
->memtype
;
2296 case Twchar
: // BUG: need to cast(wchar)
2297 case Tdchar
: // BUG: need to cast(dchar)
2298 if ((uinteger_t
)v
> 0xFF)
2300 buf
->printf("'\\U%08x'", v
);
2306 size_t o
= buf
->offset
;
2308 buf
->writestring("'\\''");
2309 else if (isprint((int)v
) && v
!= '\\')
2310 buf
->printf("'%c'", (int)v
);
2312 buf
->printf("'\\x%02x'", (int)v
);
2314 escapeDdocString(buf
, o
);
2319 buf
->writestring("cast(byte)");
2323 buf
->writestring("cast(short)");
2328 buf
->printf("%d", (int)v
);
2332 buf
->writestring("cast(ubyte)");
2336 buf
->writestring("cast(ushort)");
2341 buf
->printf("%uu", (unsigned)v
);
2345 buf
->printf("%lldL", v
);
2350 buf
->printf("%lluLU", v
);
2354 buf
->writestring(v
? "true" : "false");
2358 buf
->writestring("cast(");
2359 buf
->writestring(t
->toChars());
2360 buf
->writeByte(')');
2361 if (target
.ptrsize
== 8)
2367 /* This can happen if errors, such as
2368 * the type is painted on like in fromConstInitializer().
2377 else if (v
& 0x8000000000000000LL
)
2378 buf
->printf("0x%llx", v
);
2380 buf
->printf("%lld", v
);
2383 void visit(ErrorExp
*)
2385 buf
->writestring("__error");
2388 void floatToBuffer(Type
*type
, real_t value
)
2390 /** sizeof(value)*3 is because each byte of mantissa is max
2391 of 256 (3 characters). The string will be "-M.MMMMe-4932".
2392 (ie, 8 chars more than mantissa). Plus one for trailing \0.
2393 Plus one for rounding. */
2394 const size_t BUFFER_LEN
= sizeof(value
) * 3 + 8 + 1 + 1;
2395 char buffer
[BUFFER_LEN
];
2396 memset(buffer
, 0, BUFFER_LEN
);
2397 CTFloat::sprint(buffer
, 'g', value
);
2398 assert(strlen(buffer
) < BUFFER_LEN
);
2402 real_t r
= CTFloat::parse(buffer
);
2403 if (r
!= value
) // if exact duplication
2404 CTFloat::sprint(buffer
, 'a', value
);
2406 buf
->writestring(buffer
);
2410 Type
*t
= type
->toBasetype();
2416 buf
->writeByte('F');
2422 buf
->writeByte('L');
2428 if (t
->isimaginary())
2429 buf
->writeByte('i');
2433 void visit(RealExp
*e
)
2435 floatToBuffer(e
->type
, e
->value
);
2438 void visit(ComplexExp
*e
)
2443 buf
->writeByte('(');
2444 floatToBuffer(e
->type
, creall(e
->value
));
2445 buf
->writeByte('+');
2446 floatToBuffer(e
->type
, cimagl(e
->value
));
2447 buf
->writestring("i)");
2450 void visit(IdentifierExp
*e
)
2452 if (hgs
->hdrgen
|| hgs
->ddoc
)
2453 buf
->writestring(e
->ident
->toHChars2());
2455 buf
->writestring(e
->ident
->toChars());
2458 void visit(DsymbolExp
*e
)
2460 buf
->writestring(e
->s
->toChars());
2463 void visit(ThisExp
*)
2465 buf
->writestring("this");
2468 void visit(SuperExp
*)
2470 buf
->writestring("super");
2473 void visit(NullExp
*)
2475 buf
->writestring("null");
2478 void visit(StringExp
*e
)
2480 buf
->writeByte('"');
2481 size_t o
= buf
->offset
;
2482 for (size_t i
= 0; i
< e
->len
; i
++)
2484 unsigned c
= e
->charAt(i
);
2489 buf
->writeByte('\\');
2494 if (c
<= 0x7F && isprint(c
))
2497 buf
->printf("\\x%02x", c
);
2499 else if (c
<= 0xFFFF)
2500 buf
->printf("\\x%02x\\x%02x", c
& 0xFF, c
>> 8);
2502 buf
->printf("\\x%02x\\x%02x\\x%02x\\x%02x",
2503 c
& 0xFF, (c
>> 8) & 0xFF, (c
>> 16) & 0xFF, c
>> 24);
2508 escapeDdocString(buf
, o
);
2509 buf
->writeByte('"');
2511 buf
->writeByte(e
->postfix
);
2514 void visit(ArrayLiteralExp
*e
)
2516 buf
->writeByte('[');
2517 argsToBuffer(e
->elements
, e
->basis
);
2518 buf
->writeByte(']');
2521 void visit(AssocArrayLiteralExp
*e
)
2523 buf
->writeByte('[');
2524 for (size_t i
= 0; i
< e
->keys
->length
; i
++)
2526 Expression
*key
= (*e
->keys
)[i
];
2527 Expression
*value
= (*e
->values
)[i
];
2530 buf
->writestring(", ");
2531 expToBuffer(key
, PREC_assign
);
2532 buf
->writeByte(':');
2533 expToBuffer(value
, PREC_assign
);
2535 buf
->writeByte(']');
2538 void visit(StructLiteralExp
*e
)
2540 buf
->writestring(e
->sd
->toChars());
2541 buf
->writeByte('(');
2543 // CTFE can generate struct literals that contain an AddrExp pointing
2544 // to themselves, need to avoid infinite recursion:
2545 // struct S { this(int){ this.s = &this; } S* s; }
2546 // const foo = new S(0);
2547 if (e
->stageflags
& stageToCBuffer
)
2548 buf
->writestring("<recursion>");
2551 int old
= e
->stageflags
;
2552 e
->stageflags
|= stageToCBuffer
;
2553 argsToBuffer(e
->elements
);
2554 e
->stageflags
= old
;
2557 buf
->writeByte(')');
2560 void visit(TypeExp
*e
)
2562 typeToBuffer(e
->type
, NULL
);
2565 void visit(ScopeExp
*e
)
2567 if (e
->sds
->isTemplateInstance())
2569 e
->sds
->accept(this);
2571 else if (hgs
!= NULL
&& hgs
->ddoc
)
2574 Module
*m
= e
->sds
->isModule();
2576 buf
->writestring(m
->md
->toChars());
2578 buf
->writestring(e
->sds
->toChars());
2582 buf
->writestring(e
->sds
->kind());
2583 buf
->writeByte(' ');
2584 buf
->writestring(e
->sds
->toChars());
2588 void visit(TemplateExp
*e
)
2590 buf
->writestring(e
->td
->toChars());
2593 void visit(NewExp
*e
)
2597 expToBuffer(e
->thisexp
, PREC_primary
);
2598 buf
->writeByte('.');
2600 buf
->writestring("new ");
2601 if (e
->newargs
&& e
->newargs
->length
)
2603 buf
->writeByte('(');
2604 argsToBuffer(e
->newargs
);
2605 buf
->writeByte(')');
2607 typeToBuffer(e
->newtype
, NULL
);
2608 if (e
->arguments
&& e
->arguments
->length
)
2610 buf
->writeByte('(');
2611 argsToBuffer(e
->arguments
);
2612 buf
->writeByte(')');
2616 void visit(NewAnonClassExp
*e
)
2620 expToBuffer(e
->thisexp
, PREC_primary
);
2621 buf
->writeByte('.');
2623 buf
->writestring("new");
2624 if (e
->newargs
&& e
->newargs
->length
)
2626 buf
->writeByte('(');
2627 argsToBuffer(e
->newargs
);
2628 buf
->writeByte(')');
2630 buf
->writestring(" class ");
2631 if (e
->arguments
&& e
->arguments
->length
)
2633 buf
->writeByte('(');
2634 argsToBuffer(e
->arguments
);
2635 buf
->writeByte(')');
2638 e
->cd
->accept(this);
2641 void visit(SymOffExp
*e
)
2644 buf
->printf("(& %s+%u)", e
->var
->toChars(), e
->offset
);
2645 else if (e
->var
->isTypeInfoDeclaration())
2646 buf
->printf("%s", e
->var
->toChars());
2648 buf
->printf("& %s", e
->var
->toChars());
2651 void visit(VarExp
*e
)
2653 buf
->writestring(e
->var
->toChars());
2656 void visit(OverExp
*e
)
2658 buf
->writestring(e
->vars
->ident
->toChars());
2661 void visit(TupleExp
*e
)
2665 buf
->writeByte('(');
2666 e
->e0
->accept(this);
2667 buf
->writestring(", tuple(");
2668 argsToBuffer(e
->exps
);
2669 buf
->writestring("))");
2673 buf
->writestring("tuple(");
2674 argsToBuffer(e
->exps
);
2675 buf
->writeByte(')');
2679 void visit(FuncExp
*e
)
2681 e
->fd
->accept(this);
2682 //buf->writestring(e->fd->toChars());
2685 void visit(DeclarationExp
*e
)
2687 /* Normal dmd execution won't reach here - regular variable declarations
2688 * are handled in visit(ExpStatement), so here would be used only when
2689 * we'll directly call Expression::toChars() for debugging.
2691 if (VarDeclaration
*v
= e
->declaration
->isVarDeclaration())
2693 // For debugging use:
2694 // - Avoid printing newline.
2695 // - Intentionally use the format (Type var;)
2696 // which isn't correct as regular D code.
2697 buf
->writeByte('(');
2698 visitVarDecl(v
, false);
2699 buf
->writeByte(';');
2700 buf
->writeByte(')');
2703 e
->declaration
->accept(this);
2706 void visit(TypeidExp
*e
)
2708 buf
->writestring("typeid(");
2709 objectToBuffer(e
->obj
);
2710 buf
->writeByte(')');
2713 void visit(TraitsExp
*e
)
2715 buf
->writestring("__traits(");
2717 buf
->writestring(e
->ident
->toChars());
2720 for (size_t i
= 0; i
< e
->args
->length
; i
++)
2722 RootObject
*arg
= (*e
->args
)[i
];
2723 buf
->writestring(", ");
2724 objectToBuffer(arg
);
2727 buf
->writeByte(')');
2730 void visit(HaltExp
*)
2732 buf
->writestring("halt");
2735 void visit(IsExp
*e
)
2737 buf
->writestring("is(");
2738 typeToBuffer(e
->targ
, e
->id
);
2739 if (e
->tok2
!= TOKreserved
)
2741 buf
->printf(" %s %s", Token::toChars(e
->tok
), Token::toChars(e
->tok2
));
2745 if (e
->tok
== TOKcolon
)
2746 buf
->writestring(" : ");
2748 buf
->writestring(" == ");
2749 typeToBuffer(e
->tspec
, NULL
);
2751 if (e
->parameters
&& e
->parameters
->length
)
2753 buf
->writestring(", ");
2754 visitTemplateParameters(e
->parameters
);
2756 buf
->writeByte(')');
2759 void visit(UnaExp
*e
)
2761 buf
->writestring(Token::toChars(e
->op
));
2762 expToBuffer(e
->e1
, precedence
[e
->op
]);
2765 void visit(BinExp
*e
)
2767 expToBuffer(e
->e1
, precedence
[e
->op
]);
2768 buf
->writeByte(' ');
2769 buf
->writestring(Token::toChars(e
->op
));
2770 buf
->writeByte(' ');
2771 expToBuffer(e
->e2
, (PREC
)(precedence
[e
->op
] + 1));
2774 void visit(CompileExp
*e
)
2776 buf
->writestring("mixin(");
2777 expToBuffer(e
->e1
, PREC_assign
);
2778 buf
->writeByte(')');
2781 void visit(ImportExp
*e
)
2783 buf
->writestring("import(");
2784 expToBuffer(e
->e1
, PREC_assign
);
2785 buf
->writeByte(')');
2788 void visit(AssertExp
*e
)
2790 buf
->writestring("assert(");
2791 expToBuffer(e
->e1
, PREC_assign
);
2794 buf
->writestring(", ");
2795 expToBuffer(e
->msg
, PREC_assign
);
2797 buf
->writeByte(')');
2800 void visit(DotIdExp
*e
)
2802 expToBuffer(e
->e1
, PREC_primary
);
2803 buf
->writeByte('.');
2804 buf
->writestring(e
->ident
->toChars());
2807 void visit(DotTemplateExp
*e
)
2809 expToBuffer(e
->e1
, PREC_primary
);
2810 buf
->writeByte('.');
2811 buf
->writestring(e
->td
->toChars());
2814 void visit(DotVarExp
*e
)
2816 expToBuffer(e
->e1
, PREC_primary
);
2817 buf
->writeByte('.');
2818 buf
->writestring(e
->var
->toChars());
2821 void visit(DotTemplateInstanceExp
*e
)
2823 expToBuffer(e
->e1
, PREC_primary
);
2824 buf
->writeByte('.');
2825 e
->ti
->accept(this);
2828 void visit(DelegateExp
*e
)
2830 buf
->writeByte('&');
2831 if (!e
->func
->isNested())
2833 expToBuffer(e
->e1
, PREC_primary
);
2834 buf
->writeByte('.');
2836 buf
->writestring(e
->func
->toChars());
2839 void visit(DotTypeExp
*e
)
2841 expToBuffer(e
->e1
, PREC_primary
);
2842 buf
->writeByte('.');
2843 buf
->writestring(e
->sym
->toChars());
2846 void visit(CallExp
*e
)
2848 if (e
->e1
->op
== TOKtype
)
2850 /* Avoid parens around type to prevent forbidden cast syntax:
2852 * This is ok since types in constructor calls
2853 * can never depend on parens anyway
2855 e
->e1
->accept(this);
2858 expToBuffer(e
->e1
, precedence
[e
->op
]);
2859 buf
->writeByte('(');
2860 argsToBuffer(e
->arguments
);
2861 buf
->writeByte(')');
2864 void visit(PtrExp
*e
)
2866 buf
->writeByte('*');
2867 expToBuffer(e
->e1
, precedence
[e
->op
]);
2870 void visit(DeleteExp
*e
)
2872 buf
->writestring("delete ");
2873 expToBuffer(e
->e1
, precedence
[e
->op
]);
2876 void visit(CastExp
*e
)
2878 buf
->writestring("cast(");
2880 typeToBuffer(e
->to
, NULL
);
2883 MODtoBuffer(buf
, e
->mod
);
2885 buf
->writeByte(')');
2886 expToBuffer(e
->e1
, precedence
[e
->op
]);
2889 void visit(VectorExp
*e
)
2891 buf
->writestring("cast(");
2892 typeToBuffer(e
->to
, NULL
);
2893 buf
->writeByte(')');
2894 expToBuffer(e
->e1
, precedence
[e
->op
]);
2897 void visit(VectorArrayExp
*e
)
2899 expToBuffer(e
->e1
, PREC_primary
);
2900 buf
->writestring(".array");
2903 void visit(SliceExp
*e
)
2905 expToBuffer(e
->e1
, precedence
[e
->op
]);
2906 buf
->writeByte('[');
2907 if (e
->upr
|| e
->lwr
)
2910 sizeToBuffer(e
->lwr
);
2912 buf
->writeByte('0');
2913 buf
->writestring("..");
2915 sizeToBuffer(e
->upr
);
2917 buf
->writeByte('$');
2919 buf
->writeByte(']');
2922 void visit(ArrayLengthExp
*e
)
2924 expToBuffer(e
->e1
, PREC_primary
);
2925 buf
->writestring(".length");
2928 void visit(IntervalExp
*e
)
2930 expToBuffer(e
->lwr
, PREC_assign
);
2931 buf
->writestring("..");
2932 expToBuffer(e
->upr
, PREC_assign
);
2935 void visit(DelegatePtrExp
*e
)
2937 expToBuffer(e
->e1
, PREC_primary
);
2938 buf
->writestring(".ptr");
2941 void visit(DelegateFuncptrExp
*e
)
2943 expToBuffer(e
->e1
, PREC_primary
);
2944 buf
->writestring(".funcptr");
2947 void visit(ArrayExp
*e
)
2949 expToBuffer(e
->e1
, PREC_primary
);
2950 buf
->writeByte('[');
2951 argsToBuffer(e
->arguments
);
2952 buf
->writeByte(']');
2955 void visit(DotExp
*e
)
2957 expToBuffer(e
->e1
, PREC_primary
);
2958 buf
->writeByte('.');
2959 expToBuffer(e
->e2
, PREC_primary
);
2962 void visit(IndexExp
*e
)
2964 expToBuffer(e
->e1
, PREC_primary
);
2965 buf
->writeByte('[');
2966 sizeToBuffer(e
->e2
);
2967 buf
->writeByte(']');
2970 void visit(PostExp
*e
)
2972 expToBuffer(e
->e1
, precedence
[e
->op
]);
2973 buf
->writestring(Token::toChars(e
->op
));
2976 void visit(PreExp
*e
)
2978 buf
->writestring(Token::toChars(e
->op
));
2979 expToBuffer(e
->e1
, precedence
[e
->op
]);
2982 void visit(RemoveExp
*e
)
2984 expToBuffer(e
->e1
, PREC_primary
);
2985 buf
->writestring(".remove(");
2986 expToBuffer(e
->e2
, PREC_assign
);
2987 buf
->writeByte(')');
2990 void visit(CondExp
*e
)
2992 expToBuffer(e
->econd
, PREC_oror
);
2993 buf
->writestring(" ? ");
2994 expToBuffer(e
->e1
, PREC_expr
);
2995 buf
->writestring(" : ");
2996 expToBuffer(e
->e2
, PREC_cond
);
2999 void visit(DefaultInitExp
*e
)
3001 buf
->writestring(Token::toChars(e
->subop
));
3004 void visit(ClassReferenceExp
*e
)
3006 buf
->writestring(e
->value
->toChars());
3009 ////////////////////////////////////////////////////////////////////////////
3011 void visit(TemplateTypeParameter
*tp
)
3013 buf
->writestring(tp
->ident
->toChars());
3016 buf
->writestring(" : ");
3017 typeToBuffer(tp
->specType
, NULL
);
3019 if (tp
->defaultType
)
3021 buf
->writestring(" = ");
3022 typeToBuffer(tp
->defaultType
, NULL
);
3026 void visit(TemplateThisParameter
*tp
)
3028 buf
->writestring("this ");
3029 visit((TemplateTypeParameter
*)tp
);
3032 void visit(TemplateAliasParameter
*tp
)
3034 buf
->writestring("alias ");
3036 typeToBuffer(tp
->specType
, tp
->ident
);
3038 buf
->writestring(tp
->ident
->toChars());
3041 buf
->writestring(" : ");
3042 objectToBuffer(tp
->specAlias
);
3044 if (tp
->defaultAlias
)
3046 buf
->writestring(" = ");
3047 objectToBuffer(tp
->defaultAlias
);
3051 void visit(TemplateValueParameter
*tp
)
3053 typeToBuffer(tp
->valType
, tp
->ident
);
3056 buf
->writestring(" : ");
3057 tp
->specValue
->accept(this);
3059 if (tp
->defaultValue
)
3061 buf
->writestring(" = ");
3062 tp
->defaultValue
->accept(this);
3066 void visit(TemplateTupleParameter
*tp
)
3068 buf
->writestring(tp
->ident
->toChars());
3069 buf
->writestring("...");
3072 ////////////////////////////////////////////////////////////////////////////
3074 void visit(DebugCondition
*c
)
3077 buf
->printf("debug (%s)", c
->ident
->toChars());
3079 buf
->printf("debug (%u)", c
->level
);
3082 void visit(VersionCondition
*c
)
3085 buf
->printf("version (%s)", c
->ident
->toChars());
3087 buf
->printf("version (%u)", c
->level
);
3090 void visit(StaticIfCondition
*c
)
3092 buf
->writestring("static if (");
3093 c
->exp
->accept(this);
3094 buf
->writeByte(')');
3097 ////////////////////////////////////////////////////////////////////////////
3099 void visit(Parameter
*p
)
3101 if (p
->storageClass
& STCauto
)
3102 buf
->writestring("auto ");
3104 if (p
->storageClass
& STCreturn
)
3105 buf
->writestring("return ");
3107 if (p
->storageClass
& STCout
)
3108 buf
->writestring("out ");
3109 else if (p
->storageClass
& STCref
)
3110 buf
->writestring("ref ");
3111 else if (p
->storageClass
& STCin
)
3112 buf
->writestring("in ");
3113 else if (p
->storageClass
& STClazy
)
3114 buf
->writestring("lazy ");
3115 else if (p
->storageClass
& STCalias
)
3116 buf
->writestring("alias ");
3118 StorageClass stc
= p
->storageClass
;
3119 if (p
->type
&& p
->type
->mod
& MODshared
)
3122 if (stcToBuffer(buf
, stc
& (STCconst
| STCimmutable
| STCwild
| STCshared
| STCscope
| STCscopeinferred
)))
3123 buf
->writeByte(' ');
3125 if (p
->storageClass
& STCalias
)
3128 buf
->writestring(p
->ident
->toChars());
3130 else if (p
->type
->ty
== Tident
&&
3131 strlen(((TypeIdentifier
*)p
->type
)->ident
->toChars()) > 3 &&
3132 strncmp(((TypeIdentifier
*)p
->type
)->ident
->toChars(), "__T", 3) == 0)
3134 // print parameter name, instead of undetermined type parameter
3135 buf
->writestring(p
->ident
->toChars());
3138 typeToBuffer(p
->type
, p
->ident
);
3141 buf
->writestring(" = ");
3142 p
->defaultArg
->accept(this);
3146 void parametersToBuffer(Parameters
*parameters
, int varargs
)
3148 buf
->writeByte('(');
3151 size_t dim
= Parameter::dim(parameters
);
3152 for (size_t i
= 0; i
< dim
; i
++)
3155 buf
->writestring(", ");
3156 Parameter
*fparam
= Parameter::getNth(parameters
, i
);
3157 fparam
->accept(this);
3161 if (parameters
->length
&& varargs
== 1)
3162 buf
->writestring(", ");
3163 buf
->writestring("...");
3166 buf
->writeByte(')');
3169 void visit(Module
*m
)
3173 if (m
->userAttribDecl
)
3175 buf
->writestring("@(");
3176 argsToBuffer(m
->userAttribDecl
->atts
);
3177 buf
->writeByte(')');
3180 if (m
->md
->isdeprecated
)
3184 buf
->writestring("deprecated(");
3185 m
->md
->msg
->accept(this);
3186 buf
->writestring(") ");
3189 buf
->writestring("deprecated ");
3192 buf
->writestring("module ");
3193 buf
->writestring(m
->md
->toChars());
3194 buf
->writeByte(';');
3197 for (size_t i
= 0; i
< m
->members
->length
; i
++)
3199 Dsymbol
*s
= (*m
->members
)[i
];
3205 void toCBuffer(Statement
*s
, OutBuffer
*buf
, HdrGenState
*hgs
)
3207 PrettyPrintVisitor
v(buf
, hgs
);
3211 void toCBuffer(Type
*t
, OutBuffer
*buf
, Identifier
*ident
, HdrGenState
*hgs
)
3213 PrettyPrintVisitor
v(buf
, hgs
);
3214 v
.typeToBuffer(t
, ident
);
3217 void toCBuffer(Dsymbol
*s
, OutBuffer
*buf
, HdrGenState
*hgs
)
3219 PrettyPrintVisitor
v(buf
, hgs
);
3223 // used from TemplateInstance::toChars() and TemplateMixin::toChars()
3224 void toCBufferInstance(TemplateInstance
*ti
, OutBuffer
*buf
, bool qualifyTypes
)
3227 hgs
.fullQual
= qualifyTypes
;
3228 PrettyPrintVisitor
v(buf
, &hgs
);
3232 void toCBuffer(Initializer
*iz
, OutBuffer
*buf
, HdrGenState
*hgs
)
3234 PrettyPrintVisitor
v(buf
, hgs
);
3238 bool stcToBuffer(OutBuffer
*buf
, StorageClass stc
)
3240 bool result
= false;
3241 if ((stc
& (STCreturn
| STCscope
)) == (STCreturn
| STCscope
))
3243 if (stc
& STCscopeinferred
)
3244 stc
&= ~(STCscope
| STCscopeinferred
);
3247 const char *p
= stcToChars(stc
);
3253 buf
->writeByte(' ');
3254 buf
->writestring(p
);
3259 /*************************************************
3260 * Pick off one of the storage classes from stc,
3261 * and return a pointer to a string representation of it.
3262 * stc is reduced by the one picked.
3264 const char *stcToChars(StorageClass
& stc
)
3273 static SCstring table
[] =
3275 { STCauto
, TOKauto
, NULL
},
3276 { STCscope
, TOKscope
, NULL
},
3277 { STCstatic
, TOKstatic
, NULL
},
3278 { STCextern
, TOKextern
, NULL
},
3279 { STCconst
, TOKconst
, NULL
},
3280 { STCfinal
, TOKfinal
, NULL
},
3281 { STCabstract
, TOKabstract
, NULL
},
3282 { STCsynchronized
, TOKsynchronized
, NULL
},
3283 { STCdeprecated
, TOKdeprecated
, NULL
},
3284 { STCoverride
, TOKoverride
, NULL
},
3285 { STClazy
, TOKlazy
, NULL
},
3286 { STCalias
, TOKalias
, NULL
},
3287 { STCout
, TOKout
, NULL
},
3288 { STCin
, TOKin
, NULL
},
3289 { STCmanifest
, TOKenum
, NULL
},
3290 { STCimmutable
, TOKimmutable
, NULL
},
3291 { STCshared
, TOKshared
, NULL
},
3292 { STCnothrow
, TOKnothrow
, NULL
},
3293 { STCwild
, TOKwild
, NULL
},
3294 { STCpure
, TOKpure
, NULL
},
3295 { STCref
, TOKref
, NULL
},
3296 { STCtls
, TOKreserved
, NULL
},
3297 { STCgshared
, TOKgshared
, NULL
},
3298 { STCnogc
, TOKat
, "@nogc" },
3299 { STCproperty
, TOKat
, "@property" },
3300 { STCsafe
, TOKat
, "@safe" },
3301 { STCtrusted
, TOKat
, "@trusted" },
3302 { STCsystem
, TOKat
, "@system" },
3303 { STCdisable
, TOKat
, "@disable" },
3304 { STCfuture
, TOKat
, "@__future" },
3305 { STClocal
, TOKat
, "__local" },
3306 { 0, TOKreserved
, NULL
}
3309 for (int i
= 0; table
[i
].stc
; i
++)
3311 StorageClass tbl
= table
[i
].stc
;
3312 assert(tbl
& STCStorageClass
);
3316 if (tbl
== STCtls
) // TOKtls was removed
3319 TOK tok
= table
[i
].tok
;
3323 return Token::toChars(tok
);
3326 //printf("stc = %llx\n", stc);
3330 void trustToBuffer(OutBuffer
*buf
, TRUST trust
)
3332 const char *p
= trustToChars(trust
);
3334 buf
->writestring(p
);
3337 const char *trustToChars(TRUST trust
)
3341 case TRUSTdefault
: return NULL
;
3342 case TRUSTsystem
: return "@system";
3343 case TRUSTtrusted
: return "@trusted";
3344 case TRUSTsafe
: return "@safe";
3347 return NULL
; // never reached
3350 void linkageToBuffer(OutBuffer
*buf
, LINK linkage
)
3352 const char *p
= linkageToChars(linkage
);
3355 buf
->writestring("extern (");
3356 buf
->writestring(p
);
3357 buf
->writeByte(')');
3361 const char *linkageToChars(LINK linkage
)
3365 case LINKdefault
: return NULL
;
3366 case LINKd
: return "D";
3367 case LINKc
: return "C";
3368 case LINKcpp
: return "C++";
3369 case LINKwindows
: return "Windows";
3370 case LINKpascal
: return "Pascal";
3371 case LINKobjc
: return "Objective-C";
3372 case LINKsystem
: return "System";
3375 return NULL
; // never reached
3378 void protectionToBuffer(OutBuffer
*buf
, Prot prot
)
3380 const char *p
= protectionToChars(prot
.kind
);
3382 buf
->writestring(p
);
3384 if (prot
.kind
== PROTpackage
&& prot
.pkg
)
3386 buf
->writeByte('(');
3387 buf
->writestring(prot
.pkg
->toPrettyChars(true));
3388 buf
->writeByte(')');
3392 const char *protectionToChars(PROTKIND kind
)
3396 case PROTundefined
: return NULL
;
3397 case PROTnone
: return "none";
3398 case PROTprivate
: return "private";
3399 case PROTpackage
: return "package";
3400 case PROTprotected
: return "protected";
3401 case PROTpublic
: return "public";
3402 case PROTexport
: return "export";
3405 return NULL
; // never reached
3408 // Print the full function signature with correct ident, attributes and template args
3409 void functionToBufferFull(TypeFunction
*tf
, OutBuffer
*buf
, Identifier
*ident
,
3410 HdrGenState
* hgs
, TemplateDeclaration
*td
)
3412 //printf("TypeFunction::toCBuffer() this = %p\n", this);
3413 PrettyPrintVisitor
v(buf
, hgs
);
3414 v
.visitFuncIdentWithPrefix(tf
, ident
, td
);
3417 // ident is inserted before the argument list and will be "function" or "delegate" for a type
3418 void functionToBufferWithIdent(TypeFunction
*tf
, OutBuffer
*buf
, const char *ident
)
3421 PrettyPrintVisitor
v(buf
, &hgs
);
3422 v
.visitFuncIdentWithPostfix(tf
, ident
);
3425 void toCBuffer(Expression
*e
, OutBuffer
*buf
, HdrGenState
*hgs
)
3427 PrettyPrintVisitor
v(buf
, hgs
);
3431 /**************************************************
3432 * Write out argument types to buf.
3434 void argExpTypesToCBuffer(OutBuffer
*buf
, Expressions
*arguments
)
3436 if (!arguments
|| !arguments
->length
)
3440 PrettyPrintVisitor
v(buf
, &hgs
);
3441 for (size_t i
= 0; i
< arguments
->length
; i
++)
3443 Expression
*arg
= (*arguments
)[i
];
3445 buf
->writestring(", ");
3446 v
.typeToBuffer(arg
->type
, NULL
);
3450 void toCBuffer(TemplateParameter
*tp
, OutBuffer
*buf
, HdrGenState
*hgs
)
3452 PrettyPrintVisitor
v(buf
, hgs
);
3456 void arrayObjectsToBuffer(OutBuffer
*buf
, Objects
*objects
)
3458 if (!objects
|| !objects
->length
)
3462 PrettyPrintVisitor
v(buf
, &hgs
);
3463 for (size_t i
= 0; i
< objects
->length
; i
++)
3465 RootObject
*o
= (*objects
)[i
];
3467 buf
->writestring(", ");
3468 v
.objectToBuffer(o
);
3472 const char *parametersTypeToChars(ParameterList pl
)
3476 PrettyPrintVisitor
v(&buf
, &hgs
);
3477 v
.parametersToBuffer(pl
.parameters
, pl
.varargs
);
3478 return buf
.extractString();