Allow returning something of type void in a function that returns void
[delight/core.git] / d-codegen.h
blob6fca531b8b68f2f3c5deaf0452b9648d997e49df
1 /* GDC -- D front-end for GCC
2 Copyright (C) 2004 David Friedman
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef GCC_DCMPLR_CODEGEN_H
20 #define GCC_DCMPLR_CODEGEN_H
22 #include "d-irstate.h"
24 typedef integer_t xdmd_integer_t;
26 #include "d-objfile.h"
28 typedef enum {
29 LIBCALL_ASSERT,
30 LIBCALL_ASSERT_MSG,
31 LIBCALL_ARRAY_BOUNDS,
32 LIBCALL_SWITCH_ERROR,
33 LIBCALL_INVARIANT,
34 LIBCALL_NEWCLASS,
35 LIBCALL_NEWARRAYT,
36 LIBCALL_NEWARRAYIT,
37 //LIBCALL_NEWARRAYMT,
38 LIBCALL_NEWARRAYMTP,
39 //LIBCALL_NEWARRAYMIT,
40 LIBCALL_NEWARRAYMITP,
41 LIBCALL_ALLOCMEMORY,
42 LIBCALL_DELCLASS,
43 LIBCALL_DELINTERFACE,
44 LIBCALL_DELARRAY,
45 LIBCALL_DELMEMORY,
46 LIBCALL_CALLFINALIZER,
47 LIBCALL_CALLINTERFACEFINALIZER,
48 LIBCALL_ARRAYSETLENGTHT,
49 LIBCALL_ARRAYSETLENGTHIT,
50 LIBCALL_DYNAMIC_CAST,
51 LIBCALL_INTERFACE_CAST,
52 LIBCALL_ADEQ,
53 LIBCALL_ADCMP,
54 LIBCALL_ADCMPCHAR,
55 LIBCALL_AALEN,
56 /*LIBCALL_AAIN,
57 LIBCALL_AAGET,
58 LIBCALL_AAGETRVALUE,
59 LIBCALL_AADEL,*/
60 LIBCALL_AAINP,
61 LIBCALL_AAGETP,
62 LIBCALL_AAGETRVALUEP,
63 LIBCALL_AADELP,
64 LIBCALL_ARRAYCAST,
65 LIBCALL_ARRAYCOPY,
66 LIBCALL_ARRAYCATT,
67 LIBCALL_ARRAYCATNT,
68 LIBCALL_ARRAYAPPENDT,
69 //LIBCALL_ARRAYAPPENDCT,
70 LIBCALL_ARRAYAPPENDCTP,
71 #if V2
72 LIBCALL_ARRAYASSIGN,
73 LIBCALL_ARRAYCTOR,
74 LIBCALL_ARRAYSETASSIGN,
75 LIBCALL_ARRAYSETCTOR,
76 #endif
77 LIBCALL_MONITORENTER,
78 LIBCALL_MONITOREXIT,
79 LIBCALL_CRITICALENTER,
80 LIBCALL_CRITICALEXIT,
81 LIBCALL_THROW,
82 LIBCALL_SWITCH_STRING,
83 LIBCALL_SWITCH_USTRING,
84 LIBCALL_SWITCH_DSTRING,
85 LIBCALL_ASSOCARRAYLITERALTP,
86 #if V2
87 LIBCALL_HIDDEN_FUNC,
88 #endif
89 LIBCALL_count
90 } LibCall;
92 struct FuncFrameInfo
94 bool creates_closure;
95 tree closure_rec;
98 class ArrayScope;
100 // Code generation routines should be in a separate namespace, but so many
101 // routines need a reference to an IRState to expand Expressions. Solution
102 // is to make IRState the code generation namespace with the actual IR state
103 // routines as a mixin. There is still the global 'gen' which can be used when
104 // it is known the full function IR state is not needed. Also a lot of routines
105 // are static (don't need IR state or expand Expressions), but are still called
106 // using . or ->.
108 // Functions without a verb create trees
109 // Functions with 'do' affect the current instruction stream (or output assembler code.)
110 // functions with other names are for attribute manipulate, etc.
112 struct IRState : IRBase
114 typedef enum {
115 INTRINSIC_BSF, INTRINSIC_BSR,
116 INTRINSIC_BT, INTRINSIC_BTC, INTRINSIC_BTR, INTRINSIC_BTS,
117 INTRINSIC_BSWAP,
118 INTRINSIC_INP, INTRINSIC_INPW, INTRINSIC_INPL,
119 INTRINSIC_OUTP, INTRINSIC_OUTPW, INTRINSIC_OUTPL,
120 INTRINSIC_STD_VA_ARG,
121 INTRINSIC_C_VA_ARG,
122 INTRINSIC_C_VA_START,
123 INTRINSIC_count,
124 } Intrinsic;
126 static tree declContext(Dsymbol * d_sym);
128 // ** Local variables
129 void emitLocalVar(VarDeclaration * v, bool no_init = false);
130 tree localVar(tree t_type);
131 tree localVar(Type * e_type) { return localVar(e_type->toCtype()); }
132 tree exprVar(tree t_type);
133 tree maybeExprVar(tree exp, tree * out_var);
134 void expandDecl(tree t_decl);
136 #if V2
137 tree var(VarDeclaration * v);
138 #else
139 tree var(VarDeclaration * v) { return v->toSymbol()->Stree; }
140 #endif
142 // ** Type conversion
144 // 'convertTo' just to give it a different name from the extern "C" convert
145 tree convertTo(Expression * exp, Type * target_type);
146 tree convertTo(tree exp, Type * exp_type, Type * target_type);
148 tree convertForAssignment(Expression * exp, Type * target_type);
149 tree convertForAssignment(tree exp_tree, Type * exp_type, Type * target_type);
151 tree convertForArgument(Expression * exp, Argument * arg);
152 tree convertForCondition(Expression * exp) {
153 return convertForCondition(exp->toElem(this), exp->type); }
154 tree convertForCondition(tree exp_tree, Type * exp_type);
155 tree toDArray(Expression * exp);
156 static bool typesSame(Type * t1, Type * t2) {
157 #if V2
158 return t1->mutableOf()->equals(t2->mutableOf());
159 #else
160 return t1->equals(t2);
161 #endif
163 static bool typesCompatible(Type * t1, Type * t2) {
164 #if V2
165 return t1->implicitConvTo(t2) >= MATCHconst;
166 #else
167 return t1->equals(t2);
168 #endif
172 // ** Type management
173 static Type * getDType(tree t) {
174 // %% TODO: assert that its a type node..
175 struct lang_type * l = TYPE_LANG_SPECIFIC( t );
176 return l ? l->d_type : 0;
179 static Type * getObjectType() {
180 return ClassDeclaration::object->type;
183 // Routines to handle variables that are references.
184 static bool isDeclarationReferenceType(Declaration * decl);
185 static tree trueDeclarationType(Declaration * decl);
186 static bool isArgumentReferenceType(Argument * arg);
187 static tree trueArgumentType(Argument * arg);
189 static tree arrayType(Type * d_type, uinteger_t size) // %% use of integer_t
190 { return arrayType(d_type->toCtype(), size); }
191 static tree arrayType(tree type_node, uinteger_t size);
193 // Can't call this until common types have been built
194 static bool haveLongDouble() {
195 return TYPE_MODE(long_double_type_node) != TYPE_MODE(double_type_node);
198 static tree addTypeAttribute(tree type, const char * attrname, tree value = NULL_TREE);
199 static void addDeclAttribute(tree type, const char * attrname, tree value = NULL_TREE);
200 static tree attributes(Expressions * in_attrs);
202 // ** Simple constants
204 static tree nullPointer() { return d_null_pointer; }
205 static tree integerConstant(xdmd_integer_t value, tree type = 0);
206 static tree integerConstant(xdmd_integer_t value, Type * type) {
207 return integerConstant(value, type->toCtype());
210 static tree floatConstant(const real_t & value, TypeBasic * target_type );
212 static xdmd_integer_t hwi2toli(HOST_WIDE_INT low, HOST_WIDE_INT high);
214 // ** Routines for built in structured types
216 static tree realPart(tree c);
217 static tree imagPart(tree c);
219 // ** Dynamic arrays
220 static tree darrayPtrRef(tree exp);
221 tree darrayPtrRef(Expression * e) { return darrayPtrRef(e->toElem(this)); }
222 static tree darrayLenRef(tree exp);
224 static tree darrayVal(tree type, tree len, tree data);
225 // data may be NULL for a null pointer value
226 static tree darrayVal(tree type, uinteger_t len, tree data);
227 static tree darrayVal(Type * type, uinteger_t len, tree data) {
228 return darrayVal(type->toCtype(), len, data);
230 static tree darrayString(const char * str);
232 static char * hostToTargetString(char * str, size_t length, unsigned unit_size);
234 // Length of either a static or dynamic array
235 tree arrayLength(Expression * exp)
236 { return arrayLength(exp->toElem(this), exp->type); }
237 static tree arrayLength(tree exp, Type * exp_type);
239 // Delegates
240 static tree delegateMethodRef(tree exp);
241 static tree delegateObjectRef(tree exp);
242 static tree delegateVal(tree method_exp, tree object_exp, Type * d_type);
243 // These are for references to nested functions/methods as opposed to a variable of
244 // type Tdelegate
245 tree methodCallExpr(tree callee, tree object, Type * d_type) {
246 tree t = delegateVal(callee, object, d_type);
247 D_IS_METHOD_CALL_EXPR( t ) = 1;
248 return t;
250 void extractMethodCallExpr(tree mcr, tree & callee_out, tree & object_out);
251 tree objectInstanceMethod(Expression * obj_exp, FuncDeclaration * func, Type * d_type);
253 static tree twoFieldType(tree rec_type, tree ft1, tree ft2, Type * d_type = 0, const char * n1 = "_a", const char * n2 = "_b");
254 static tree twoFieldType(Type * ft1, Type * ft2, Type * d_type = 0, const char * n1 = "_a", const char * n2 = "_b");
255 static tree twoFieldCtor(tree rec_type, tree f1, tree f2, int storage_class = 0);
257 // ** Temporaries (currently just SAVE_EXPRs)
259 // Create a SAVE_EXPR if 't' might have unwanted side effects if referenced
260 // more than once in an expression.
261 tree maybeMakeTemp(tree t);
263 // Return true if t can be evaluated multiple times (i.e., in a loop body)
264 // without unwanted side effects. This is a stronger test than
265 // the one used for maybeMakeTemp.
266 static bool isFreeOfSideEffects(tree t);
268 // ** Various expressions
269 tree toElemLvalue(Expression * e);
271 static tree addressOf(tree exp) {
272 tree t;
274 d_mark_addressable(exp);
275 #if ENABLE_CHECKING
276 // Gimplify doesn't like &(*(ptr-to-array-type)) with static arrays
277 if (TREE_CODE(exp) == INDIRECT_REF)
278 t = nop(TREE_OPERAND(exp, 0), build_pointer_type(TREE_TYPE(exp)));
279 else
280 #endif
281 t = build1(ADDR_EXPR, build_pointer_type(TREE_TYPE(exp)), exp);
282 #if D_NO_TRAMPOLINES
283 if (TREE_CODE( exp ) == FUNCTION_DECL)
284 TREE_STATIC( t ) = 1;
285 #endif
286 return t;
288 static tree addressOf(Dsymbol *d) {
289 return addressOf( d->toSymbol()->Stree ); }
290 /* Cast exp (which should be a pointer) to TYPE* and then indirect. The
291 back-end requires this cast in many cases. */
292 static tree indirect(tree exp, tree type) {
293 return build1(INDIRECT_REF, type,
294 nop(exp, build_pointer_type(type)));
296 static tree indirect(tree exp) {
297 return build1(INDIRECT_REF, TREE_TYPE(TREE_TYPE(exp)), exp); }
298 static tree vmodify(tree dst, tree src) {
299 return build2(MODIFY_EXPR, void_type_node, dst, src); }
301 tree pointerIntSum(Expression * ptr_exp, Expression * idx_exp) {
302 return pointerIntSum(ptr_exp->toElem(this), idx_exp->toElem(this)); }
303 tree pointerIntSum(tree ptr_node, tree idx_exp);
305 static tree nop(tree e, tree t) {
306 return build1(NOP_EXPR, t, e); }
308 // DMD allows { void[] a; & a[3]; }
309 static tree
310 pvoidOkay(tree t) {
311 if ( VOID_TYPE_P( TREE_TYPE( TREE_TYPE( t ))) ) {
312 // ::warning("indexing array of void");
313 return convert(Type::tuns8->pointerTo()->toCtype(), t);
314 } else
315 return t;
318 tree boolOp(enum tree_code code, tree a, tree b) {
319 return build(code, boolean_type_node, a, b);
322 tree checkedIndex(Loc loc, tree index, tree upper_bound, bool inclusive);
323 tree boundsCond(tree index, tree upper_bound, bool inclusive);
325 tree arrayElemRef(IndexExp * aer_exp, ArrayScope * aryscp);
327 #if D_GCC_VER < 40
328 static tree binding(tree var_chain, tree body)
330 return build(BIND_EXPR, TREE_TYPE(body), var_chain, body, NULL_TREE);
332 #else
333 static tree binding(tree var_chain, tree body);
334 #endif
336 static tree compound(tree a, tree b, tree type = 0) {
337 return build(COMPOUND_EXPR, type ? type : TREE_TYPE(b), a, b);
339 tree voidCompound(tree a, tree b) { return compound(a, b, void_type_node); }
340 tree maybeCompound(tree a, tree b) {
341 if (a == NULL_TREE)
342 return b;
343 else if (b == NULL_TREE)
344 return a;
345 else
346 return build(COMPOUND_EXPR, TREE_TYPE(b), a, b);
348 tree maybeVoidCompound(tree a, tree b) {
349 if (a == NULL_TREE)
350 return b;
351 else if (b == NULL_TREE)
352 return a;
353 else
354 return build(COMPOUND_EXPR, void_type_node, a, b);
357 static tree component(tree v, tree f)
359 #if D_GCC_VER < 40
360 return build(COMPONENT_REF, TREE_TYPE(f), v, f);
361 #else
362 return build3(COMPONENT_REF, TREE_TYPE(f), v, f, NULL_TREE);
363 #endif
366 // Giving error_mark_node a type allows for some assumptions about
367 // the type of an arbitrary expression.
368 static tree errorMark(Type * t);
369 static bool isErrorMark(tree t) {
370 return TREE_CODE(t) == ERROR_MARK ||
371 (TREE_CODE(t) == NOP_EXPR &&
372 TREE_CODE( TREE_OPERAND(t, 0) ) == ERROR_MARK);
375 // ** Function calls
376 tree call(Expression * expr, Array * arguments);
377 tree call(FuncDeclaration * func_decl, Array * args);
378 tree call(FuncDeclaration * func_decl, tree object, Array * args);
379 tree call(TypeFunction *guess, tree callable, tree object, Array * arguments);
381 tree assertCall(Loc loc, LibCall libcall = LIBCALL_ASSERT);
382 tree assertCall(Loc loc, Expression * msg);
383 static FuncDeclaration * getLibCallDecl(LibCall lib_call);
384 static void replaceLibCallDecl(FuncDeclaration * d_decl);
385 // This does not perform conversions on the arguments. This allows
386 // arbitrary data to be passed through varargs without going through the
387 // usual conversions.
388 static tree libCall(LibCall lib_call, unsigned n_args, tree *args, tree force_result_type = 0);
390 // GCC 3.3 does not set TREE_SIDE_EFFECTS call by default. GCC 3.4
391 // sets it depending on the const/pure attributes of the funcion
392 // and the SIDE_EFFECTS flags of the arguments.
393 static tree buildCall(tree type, tree callee, tree args) {
394 #if D_GCC_VER < 40
395 tree t = build(CALL_EXPR, type, callee, args);
396 #else
397 tree t = build3(CALL_EXPR, type, callee, args, NULL_TREE);
398 #endif
399 #if D_GCC_VER <= 33
400 TREE_SIDE_EFFECTS(t) = 1;
401 #endif
402 return t;
405 tree assignValue(Expression * e, VarDeclaration * v);
407 static TemplateEmission emitTemplates;
408 static bool splitDynArrayVarArgs;
409 static bool useBuiltins;
411 // Warnings
412 static bool warnSignCompare;
414 // %%
415 static bool originalOmitFramePointer;
417 protected:
418 tree maybeExpandSpecialCall(tree call_exp);
419 public:
420 tree floatMod(tree a, tree b, Type * d_type);
422 tree typeinfoReference(Type * t);
424 target_size_t getTargetSizeConst(tree t);
426 static Module * builtinsModule;
427 static Module * intrinsicModule;
428 static TemplateDeclaration * stdargTemplateDecl;
429 static TemplateDeclaration * cstdargStartTemplateDecl;
430 static TemplateDeclaration * cstdargArgTemplateDecl;
431 static void setBuiltinsModule(Module * mod) { builtinsModule = mod; }
432 static void setIntrinsicModule(Module * mod) { intrinsicModule = mod; }
433 static void setStdArg(TemplateDeclaration * td) { stdargTemplateDecl = td; }
434 static void setCStdArgStart(TemplateDeclaration * td) { cstdargStartTemplateDecl = td; }
435 static void setCStdArgArg(TemplateDeclaration * td) { cstdargArgTemplateDecl = td; }
436 static bool maybeSetUpBuiltin(Declaration * decl);
438 static tree functionPointer(FuncDeclaration * func_decl) { return addressOf(func_decl); }
440 // Returns the D object that was thrown. Different from the generic exception pointer
441 static tree exceptionObject();
443 static tree label(Loc loc, Identifier * ident = 0);
445 // Static chain for nested functions
446 tree getFrameForFunction(FuncDeclaration * f);
447 tree getFrameForNestedClass(ClassDeclaration * c);
448 #if V2
449 void useClosure(FuncDeclaration * f, tree l) {
450 _closureLink = l;
451 closureFunc = f;
453 void useParentClosure() {
454 if (parent)
456 _closureLink = ((IRState*)parent)->_closureLink;
457 closureFunc = ((IRState*)parent)->closureFunc;
460 tree closureLink() { return _closureLink; }
461 #endif
462 protected:
463 tree getFrameForSymbol(Dsymbol * nested_sym);
464 #if V2
465 tree getClosureRef(FuncDeclaration *outer_func);
466 FuncDeclaration * closureFunc;
467 tree _closureLink;
468 public:
469 static FuncFrameInfo * getFrameInfo(FuncDeclaration *fd);
470 #endif
471 public:
472 static bool functionNeedsChain(FuncDeclaration *f);
474 // ** Instruction stream manipulation
475 void startCond(Statement * stmt, Expression * e_cond);
476 void startElse();
477 void endCond();
478 void startLoop(Statement * stmt);
479 void continueHere();
480 void setContinueLabel(tree lbl);
481 void exitIfFalse(tree t_cond, bool is_top_cond = 0);
482 void exitIfFalse(Expression * e_cond, bool is_top_cond = 0) {
483 exitIfFalse(convertForCondition(e_cond), is_top_cond);
485 void endLoop();
486 void startCase(Statement * stmt, tree t_cond);
487 void doCase(tree t_value, tree t_label);
488 void endCase(tree t_cond);
489 void continueLoop(Identifier * ident);
490 void exitLoop(Identifier * ident);
491 void startTry(Statement * stmt);
492 void startCatches();
493 void startCatch(tree t_type);
494 void endCatch();
495 void endCatches();
496 void startFinally();
497 void endFinally();
498 /*static*/ void doReturn(tree t_value);
499 /*static*/ void doJump(Statement * stmt, tree t_label);
500 void doExp(tree t) { addExp(t); }
501 void doExp(Expression * e) { doExp(e->toElem(this)); } // %% should handle volatile...?
502 void doAsm(tree insn_tmpl, tree outputs, tree inputs, tree clobbers);
504 // ** Callback statement evalutation
506 static Array stmtExprList;
508 tree makeStmtExpr(Statement * statement);
509 static void retrieveStmtExpr(tree t, Statement ** s_out, IRState ** i_out);
511 static void doLineNote(const Loc & loc) { ObjectFile::doLineNote(loc); }
514 struct GlobalValues {
515 ObjectFile * ofile;
516 IRState * irs;
517 Module * mod;
518 ModuleInfo * mi() { return ofile->moduleInfo; }
521 extern GlobalValues g;
523 extern IRState gen;
525 // Various helpers that need extra state
527 struct WrappedExp : Expression
529 tree exp_node;
530 WrappedExp(Loc loc, enum TOK op, tree exp_node, Type * type);
531 void toCBuffer(OutBuffer *buf);
532 elem *toElem(IRState *irs);
535 struct ListMaker {
536 tree head;
537 tree * ptail;
538 ListMaker() : head(NULL_TREE), ptail( & head ) { }
539 ListMaker(tree * alt_head) : head(NULL_TREE), ptail( alt_head ) { }
540 void reserve(int i) { }
541 void chain(tree t) { *ptail = t; ptail = & TREE_CHAIN(t); }
542 void cons(tree p, tree v) {
543 *ptail = tree_cons(p,v,NULL_TREE);
544 ptail = & TREE_CHAIN(*ptail);
546 void cons(tree v) { cons(NULL_TREE, v); }
549 #if D_GCC_VER < 41
550 typedef ListMaker CtorEltMaker;
551 #else
553 struct CtorEltMaker {
554 VEC(constructor_elt,gc) *head;
555 CtorEltMaker() : head(NULL) { }
556 void reserve(int i) { VEC_reserve(constructor_elt,gc,head,i); }
557 void cons(tree p, tree v) {
558 constructor_elt * ce;
559 ce = VEC_safe_push(constructor_elt,gc,head,NULL);
560 ce->index = p;
561 ce->value = v;
563 void cons(tree v) { cons(NULL_TREE, v); }
566 #endif
568 class FieldVisitor {
569 public:
570 AggregateDeclaration * aggDecl;
571 FieldVisitor(AggregateDeclaration * decl) : aggDecl(decl) { }
572 //virtual doField(VarDeclaration * field) = 0;
573 virtual void doFields(Array * fields, AggregateDeclaration * agg) = 0;
574 virtual void doInterfaces(Array * bases, AggregateDeclaration * agg) = 0;
575 void go() { visit(aggDecl); }
576 void visit(AggregateDeclaration * decl);
579 class AggLayout : public FieldVisitor {
580 public:
581 tree aggType;
582 ListMaker fieldList;
583 AggLayout(AggregateDeclaration * ini_agg_decl, tree ini_agg_type) :
584 FieldVisitor(ini_agg_decl),
585 aggType(ini_agg_type),
586 fieldList(& TYPE_FIELDS( aggType )) { }
587 void doFields(Array * fields, AggregateDeclaration * agg);
588 void doInterfaces(Array * bases, AggregateDeclaration * agg);
589 void addField(tree field_decl, target_size_t offset);
590 void finish(Expressions * attrs);
593 class ArrayScope {
594 VarDeclaration * v;
595 IRState * irs;
596 public:
597 ArrayScope(IRState * ini_irs, VarDeclaration * ini_v, const Loc & loc);
598 tree setArrayExp(tree e, Type * t);
599 tree finish(tree e);
602 class AddrOfExpr {
603 public:
604 tree var;
605 AddrOfExpr() { var = NULL_TREE; }
606 tree set(IRState * irs, tree exp) {
607 return irs->addressOf( irs->maybeExprVar(exp, & var) );
609 tree finish(IRState * irs, tree e2) {
610 return var ? irs->binding(var, e2) : e2;
614 #endif