annotate dmd/FuncDeclaration.d @ 178:e3afd1303184

Many small bugs fixed Made all classes derive from TObject to detect memory leaks (functionality is disabled for now) Began work on overriding backend memory allocations (to avoid memory leaks)
author korDen
date Sun, 17 Oct 2010 07:42:00 +0400
parents 1475fd394c9e
children cd48cb899aee
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1 module dmd.FuncDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2
114
e28b18c23469 added a module dmd.common for commonly used stuff
Trass3r
parents: 110
diff changeset
3 import dmd.common;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
4 import dmd.Declaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
5 import dmd.DotIdExp;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
6 import dmd.AddrExp;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
7 import dmd.TryFinallyStatement;
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
8 import dmd.TryCatchStatement;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
9 import dmd.Catch;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
10 import dmd.DeclarationStatement;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
11 import dmd.StaticDtorDeclaration;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
12 import dmd.GlobalExpressions;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
13 import dmd.PeelStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
14 import dmd.SynchronizedStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
15 import dmd.TOK;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
16 import dmd.SymOffExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
17 import dmd.AssignExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
18 import dmd.ExpInitializer;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
19 import dmd.BE;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
20 import dmd.Id;
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
21 import dmd.StorageClassDeclaration;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
22 import dmd.StringExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
23 import dmd.DsymbolExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
24 import dmd.HaltExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
25 import dmd.CommaExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
26 import dmd.ReturnStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
27 import dmd.IntegerExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
28 import dmd.ExpStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
29 import dmd.CSX;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
30 import dmd.CompoundStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
31 import dmd.LabelStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
32 import dmd.ThisExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
33 import dmd.SuperExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
34 import dmd.IdentifierExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
35 import dmd.AssertExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
36 import dmd.CallExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
37 import dmd.RET;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
38 import dmd.VarExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
39 import dmd.TupleDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
40 import dmd.ThisDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
41 import dmd.TypeTuple;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
42 import dmd.TemplateInstance;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
43 import dmd.ScopeDsymbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
44 import dmd.AliasDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
45 import dmd.MOD;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
46 import dmd.PROT;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
47 import dmd.Lexer;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
48 import dmd.LINK;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
49 import dmd.CtorDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
50 import dmd.Global;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
51 import dmd.DtorDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
52 import dmd.InvariantDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
53 import dmd.TY;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
54 import dmd.PtrExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
55 import dmd.DeclarationExp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
56 import dmd.InlineDoState;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
57 import dmd.Parameter;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
58 import dmd.StructDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
59 import dmd.ClassDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
60 import dmd.InterfaceDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
61 import dmd.Array;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
62 import dmd.Statement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
63 import dmd.Identifier;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
64 import dmd.VarDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
65 import dmd.LabelDsymbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
66 import dmd.DsymbolTable;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
67 import dmd.ArrayTypes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
68 import dmd.Loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
69 import dmd.ILS;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
70 import dmd.ForeachStatement;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
71 import dmd.Type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
72 import dmd.BUILTIN;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
73 import dmd.TypeFunction;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
74 import dmd.Expression;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
75 import dmd.STC;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
76 import dmd.TRUST;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
77 import dmd.Dsymbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
78 import dmd.Scope;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
79 import dmd.OutBuffer;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
80 import dmd.HdrGenState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
81 import dmd.MATCH;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
82 import dmd.AggregateDeclaration;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
83 import dmd.InterState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
84 import dmd.InlineScanState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
85 import dmd.IRState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
86 import dmd.Util;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
87 import dmd.BaseClass;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
88 import dmd.Module;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
89 import dmd.InlineCostState;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
90
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
91 import dmd.expression.Util;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
92
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
93 import dmd.declaration.Match;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
94
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
95 import dmd.backend.Symbol;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
96 import dmd.backend.func_t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
97 import dmd.backend.Util;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
98 import dmd.backend.glue;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
99 import dmd.backend.SC;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
100 import dmd.backend.F;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
101 import dmd.backend.Cstate;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
102 import dmd.backend.TYM;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
103 import dmd.backend.OPER;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
104 import dmd.backend.TYFL;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
105 import dmd.backend.TYPE;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
106 import dmd.backend.SFL;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
107 import dmd.backend.mTY;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
108 import dmd.backend.FL;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
109 import dmd.backend.REG;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
110 import dmd.backend.block;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
111 import dmd.backend.Blockx;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
112 import dmd.backend.Config;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
113 import dmd.backend.BC;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
114 import dmd.backend.elem;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
115 import dmd.backend.targ_types;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
116 import dmd.backend.mTYman;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
117 import dmd.backend.RTLSYM;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
118 import dmd.backend.LIST;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
119
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
120 import core.stdc.stdio;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
121 import core.stdc.string;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
122 version (Bug4054) import core.memory;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
123
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
124 import dmd.interpret.Util;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
125
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
126 import std.string;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
127
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
128 class FuncDeclaration : Declaration
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
129 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
130 Array fthrows; // Array of Type's of exceptions (not used)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
131 Statement frequire;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
132 Statement fensure;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
133 Statement fbody;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
134
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
135 FuncDeclarations foverrides; // functions this function overrides
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
136 FuncDeclaration fdrequire; // function that does the in contract
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
137 FuncDeclaration fdensure; // function that does the out contract
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
138
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
139 Identifier outId; // identifier for out statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
140 VarDeclaration vresult; // variable corresponding to outId
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
141 LabelDsymbol returnLabel; // where the return goes
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
142
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
143 DsymbolTable localsymtab; // used to prevent symbols in different
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
144 // scopes from having the same name
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
145 VarDeclaration vthis; // 'this' parameter (member and nested)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
146 VarDeclaration v_arguments; // '_arguments' parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
147 version (IN_GCC) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
148 VarDeclaration v_argptr; // '_argptr' variable
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
149 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
150 Dsymbols parameters; // Array of VarDeclaration's for parameters
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
151 DsymbolTable labtab; // statement label symbol table
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
152 Declaration overnext; // next in overload list
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
153 Loc endloc; // location of closing curly bracket
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
154 int vtblIndex; // for member functions, index into vtbl[]
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
155 int naked; // !=0 if naked
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
156 int inlineAsm; // !=0 if has inline assembler
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
157 ILS inlineStatus;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
158 int inlineNest; // !=0 if nested inline
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
159 int cantInterpret; // !=0 if cannot interpret function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
160 int semanticRun; // 1 semantic() run
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
161 // 2 semantic2() run
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
162 // 3 semantic3() started
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
163 // 4 semantic3() done
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
164 // 5 toObjFile() run
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
165 // this function's frame ptr
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
166 ForeachStatement fes; // if foreach body, this is the foreach
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
167 int introducing; // !=0 if 'introducing' function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
168 Type tintro; // if !=null, then this is the type
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
169 // of the 'introducing' function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
170 // this one is overriding
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
171 int inferRetType; // !=0 if return type is to be inferred
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
172
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
173 // Things that should really go into Scope
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
174 int hasReturnExp; // 1 if there's a return exp; statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
175 // 2 if there's a throw statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
176 // 4 if there's an assert(0)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
177 // 8 if there's inline asm
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
178
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
179 // Support for NRVO (named return value optimization)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
180 bool nrvo_can = true; // !=0 means we can do it
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
181 VarDeclaration nrvo_var; // variable to replace with shidden
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
182 Symbol* shidden; // hidden pointer passed to function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
183
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
184 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
185 BUILTIN builtin; // set if this is a known, builtin
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
186 // function we can evaluate at compile
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
187 // time
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
188
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
189 int tookAddressOf; // set if someone took the address of
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
190 // this function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
191 Dsymbols closureVars; // local variables in this function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
192 // which are referenced by nested
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
193 // functions
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
194 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
195 int nestedFrameRef; // !=0 if nested variables referenced
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
196 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
197
131
206db751bd4c dmdfe 2.037 compiles now
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 130
diff changeset
198 this(Loc loc, Loc endloc, Identifier id, StorageClass storage_class, Type type)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
199 {
178
e3afd1303184 Many small bugs fixed
korDen
parents: 177
diff changeset
200 register();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
201 super(id);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
202
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
203 //printf("FuncDeclaration(id = '%s', type = %p)\n", id.toChars(), type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
204 //printf("storage_class = x%x\n", storage_class);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
205 this.storage_class = storage_class;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
206 this.type = type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
207 this.loc = loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
208 this.endloc = endloc;
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
209 fthrows = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
210 frequire = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
211 fdrequire = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
212 fdensure = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
213 outId = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
214 vresult = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
215 returnLabel = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
216 fensure = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
217 fbody = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
218 localsymtab = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
219 vthis = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
220 v_arguments = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
221 version (IN_GCC) {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
222 v_argptr = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
223 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
224 parameters = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
225 labtab = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
226 overnext = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
227 vtblIndex = -1;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
228 hasReturnExp = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
229 naked = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
230 inlineStatus = ILS.ILSuninitialized;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
231 inlineNest = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
232 inlineAsm = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
233 cantInterpret = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
234 semanticRun = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
235 version (DMDV1) {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
236 nestedFrameRef = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
237 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
238 fes = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
239 introducing = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
240 tintro = null;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
241 /* The type given for "infer the return type" is a TypeFunction with
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
242 * null for the return type.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
243 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
244 inferRetType = (type && type.nextOf() is null);
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
245 hasReturnExp = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
246 nrvo_can = 1;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
247 nrvo_var = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
248 shidden = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
249 version (DMDV2) {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
250 builtin = BUILTINunknown;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
251 tookAddressOf = 0;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
252 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
253 foverrides = new FuncDeclarations();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
254 closureVars = new Dsymbols();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
255 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
256
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
257 override Dsymbol syntaxCopy(Dsymbol s)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
258 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
259 FuncDeclaration f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
260
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
261 //printf("FuncDeclaration::syntaxCopy('%s')\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
262 if (s)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
263 f = cast(FuncDeclaration)s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
264 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
265 f = new FuncDeclaration(loc, endloc, ident, storage_class, type.syntaxCopy());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
266
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
267 f.outId = outId;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
268 f.frequire = frequire ? frequire.syntaxCopy() : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
269 f.fensure = fensure ? fensure.syntaxCopy() : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
270 f.fbody = fbody ? fbody.syntaxCopy() : null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
271 assert(!fthrows); // deprecated
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
272
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
273 return f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
274 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
275
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
276 // Do the semantic analysis on the external interface to the function.
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
277 override void semantic(Scope sc)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
278 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
279 TypeFunction f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
280 StructDeclaration sd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
281 ClassDeclaration cd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
282 InterfaceDeclaration id;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
283 Dsymbol pd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
284
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
285 static if (false)
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
286 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
287 printf("FuncDeclaration.semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc.linkage);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
288 if (isFuncLiteralDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
289 printf("\tFuncLiteralDeclaration()\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
290 printf("sc.parent = %s, parent = %s\n", sc.parent.toChars(), parent ? parent.toChars() : "");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
291 printf("type: %p, %s\n", type, type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
292 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
293
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
294 if (semanticRun && isFuncLiteralDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
295 {
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
296 /* Member functions that have return types that are
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
297 * forward references can have semantic() run more than
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
298 * once on them.
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
299 * See test\interface2.d, test20
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
300 */
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
301 return;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
302 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
303 assert(semanticRun <= 1);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
304 semanticRun = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
305
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
306 storage_class |= sc.stc & ~STC.STCref;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
307 //printf("function storage_class = x%x\n", storage_class);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
308
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
309 if (!originalType)
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
310 originalType = type;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
311 if (!type.deco)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
312 {
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
313 sc = sc.push();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
314 sc.stc |= storage_class & STC.STCref; // forward refness to function type
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
315 type = type.semantic(loc, sc);
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
316 sc = sc.pop();
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
317
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
318 /* Apply const, immutable and shared storage class
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
319 * to the function type
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
320 */
131
206db751bd4c dmdfe 2.037 compiles now
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 130
diff changeset
321 StorageClass stc = storage_class;
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
322 if (type.isImmutable())
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
323 stc |= STC.STCimmutable;
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
324 if (type.isConst())
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
325 stc |= STC.STCconst;
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
326 if (type.isShared() || storage_class & STC.STCsynchronized)
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
327 stc |= STC.STCshared;
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
328 if (type.isWild())
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
329 stc |= STC.STCwild;
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
330 switch (stc & STC.STC_TYPECTOR)
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
331 {
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
332 case STC.STCimmutable:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
333 case STC.STCimmutable | STC.STCconst:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
334 case STC.STCimmutable | STC.STCconst | STC.STCshared:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
335 case STC.STCimmutable | STC.STCshared:
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
336 case STC.STCimmutable | STC.STCwild:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
337 case STC.STCimmutable | STC.STCconst | STC.STCwild:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
338 case STC.STCimmutable | STC.STCconst | STC.STCshared | STC.STCwild:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
339 case STC.STCimmutable | STC.STCshared | STC.STCwild:
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
340 // Don't use toInvariant(), as that will do a merge()
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
341 type = type.makeInvariant();
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
342 goto Lmerge;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
343
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
344 case STC.STCconst:
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
345 case STC.STCconst | STC.STCwild:
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
346 type = type.makeConst();
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
347 goto Lmerge;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
348
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
349 case STC.STCshared | STC.STCconst:
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
350 case STC.STCshared | STC.STCconst | STC.STCwild:
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
351 type = type.makeSharedConst();
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
352 goto Lmerge;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
353
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
354 case STC.STCshared:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
355 type = type.makeShared();
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
356 goto Lmerge;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
357
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
358 case STC.STCwild:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
359 type = type.makeWild();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
360 goto Lmerge;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
361
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
362 case STC.STCshared | STC.STCwild:
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
363 type = type.makeSharedWild();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
364 goto Lmerge;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
365
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
366 Lmerge:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
367 if (!(type.ty == Tfunction && !type.nextOf()))
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
368 /* Can't do merge if return type is not known yet
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
369 */
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
370 type.deco = type.merge().deco;
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
371 break;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
372
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
373 case STC.STCundefined:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
374 break;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
375
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
376 default:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
377 assert(0);
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
378 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
379 }
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
380 storage_class &= ~STC.STCref;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
381 if (type.ty != TY.Tfunction)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
382 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
383 error("%s must be a function", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
384 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
385 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
386 f = cast(TypeFunction)type;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
387 size_t nparams = Parameter.dim(f.parameters);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
388
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
389 linkage = sc.linkage;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
390 // if (!parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
391 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
392 //parent = sc.scopesym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
393 parent = sc.parent;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
394 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
395 protection = sc.protection;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
396 Dsymbol parent = toParent();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
397
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
398 if (storage_class & STC.STCscope)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
399 error("functions cannot be scope");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
400
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
401 if (isAbstract() && !isVirtual())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
402 error("non-virtual functions cannot be abstract");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
403
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
404 if ((f.isConst() || f.isImmutable()) && !isThis())
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
405 error("without 'this' cannot be const/immutable");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
406
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
407 if (isAbstract() && isFinal())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
408 error("cannot be both final and abstract");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
409 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
410 if (isAbstract() && fbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
411 error("abstract functions cannot have bodies");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
412 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
413
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
414 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
415 if (isStaticConstructor() || isStaticDestructor())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
416 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
417 if (!isStatic() || type.nextOf().ty != Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
418 error("static constructors / destructors must be static void");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
419 if (f.arguments && f.arguments.dim)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
420 error("static constructors / destructors must have empty parameter list");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
421 // BUG: check for invalid storage classes
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
422 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
423 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
424
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
425 version (IN_GCC) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
426 AggregateDeclaration ad;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
427
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
428 ad = parent.isAggregateDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
429 if (ad)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
430 ad.methods.push(cast(void*)this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
431 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
432 sd = parent.isStructDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
433 if (sd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
434 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
435 if (isCtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
436 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
437 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
438 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
439 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
440 // Verify no constructors, destructors, etc.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
441 if (isCtorDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
442 //||isDtorDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
443 //|| isInvariantDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
444 //|| isUnitTestDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
445 )
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
446 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
447 error("special member functions not allowed for %ss", sd.kind());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
448 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
449
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
450 if (!sd.inv)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
451 sd.inv = isInvariantDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
452
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
453 if (!sd.aggNew)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
454 sd.aggNew = isNewDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
455
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
456 if (isDelete())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
457 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
458 if (sd.aggDelete)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
459 error("multiple delete's for struct %s", sd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
460 sd.aggDelete = cast(DeleteDeclaration)this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
461 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
462 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
463 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
464
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
465 id = parent.isInterfaceDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
466 if (id)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
467 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
468 storage_class |= STC.STCabstract;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
469
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
470 if (isCtorDeclaration() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
471 ///static if (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
472 isPostBlitDeclaration() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
473 ///}
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
474 isDtorDeclaration() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
475 isInvariantDeclaration() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
476 isUnitTestDeclaration() || isNewDeclaration() || isDelete())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
477 error("special function not allowed in interface %s", id.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
478 if (fbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
479 error("function body is not abstract in interface %s", id.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
480 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
481
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
482 /* Template member functions aren't virtual:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
483 * interface TestInterface { void tpl(T)(); }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
484 * and so won't work in interfaces
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
485 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
486 if ((pd = toParent()) !is null &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
487 pd.isTemplateInstance() &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
488 (pd = toParent2()) !is null &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
489 (id = pd.isInterfaceDeclaration()) !is null)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
490 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
491 error("template member function not allowed in interface %s", id.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
492 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
493
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
494 cd = parent.isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
495 if (cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
496 { int vi;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
497 CtorDeclaration ctor;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
498 DtorDeclaration dtor;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
499 InvariantDeclaration inv;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
500
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
501 if (isCtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
502 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
503 // ctor = cast(CtorDeclaration)this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
504 // if (!cd.ctor)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
505 // cd.ctor = ctor;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
506 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
507 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
508
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
509 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
510 dtor = isDtorDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
511 if (dtor)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
512 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
513 if (cd.dtor)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
514 error("multiple destructors for class %s", cd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
515 cd.dtor = dtor;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
516 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
517
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
518 inv = isInvariantDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
519 if (inv)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
520 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
521 cd.inv = inv;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
522 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
523
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
524 if (isNewDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
525 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
526 if (!cd.aggNew)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
527 cd.aggNew = cast(NewDeclaration)this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
528 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
529
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
530 if (isDelete())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
531 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
532 if (cd.aggDelete)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
533 error("multiple delete's for class %s", cd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
534 cd.aggDelete = cast(DeleteDeclaration)this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
535 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
536 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
537
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
538 if (storage_class & STC.STCabstract)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
539 cd.isabstract = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
540
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
541 // if static function, do not put in vtbl[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
542 if (!isVirtual())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
543 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
544 //printf("\tnot virtual\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
545 goto Ldone;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
546 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
547
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
548 // Find index of existing function in vtbl[] to override
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
549 vi = findVtblIndex(cd.vtbl, cd.baseClass ? cd.baseClass.vtbl.dim : 0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
550 switch (vi)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
551 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
552 case -1:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
553 /* Didn't find one, so
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
554 * This is an 'introducing' function which gets a new
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
555 * slot in the vtbl[].
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
556 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
557
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
558 // Verify this doesn't override previous final function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
559 if (cd.baseClass)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
560 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
561 Dsymbol s = cd.baseClass.search(loc, ident, 0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
562 if (s)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
563 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
564 FuncDeclaration ff = s.isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
565 ff = ff.overloadExactMatch(type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
566 if (ff && ff.isFinal() && ff.prot() != PROT.PROTprivate)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
567 error("cannot override final function %s", ff.toPrettyChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
568 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
569 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
570
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
571 if (isFinal())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
572 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
573 if (isOverride())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
574 error("does not override any function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
575 cd.vtblFinal.push(cast(void*)this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
576 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
577 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
578 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
579 // Append to end of vtbl[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
580 //printf("\tintroducing function\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
581 introducing = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
582 vi = cd.vtbl.dim;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
583 cd.vtbl.push(cast(void*)this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
584 vtblIndex = vi;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
585 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
586 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
587
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
588 case -2: // can't determine because of fwd refs
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
589 cd.sizeok = 2; // can't finish due to forward reference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
590 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
591
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
592 default:
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
593 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
594 FuncDeclaration fdv = cast(FuncDeclaration)cd.vtbl.data[vi];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
595 // This function is covariant with fdv
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
596 if (fdv.isFinal())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
597 error("cannot override final function %s", fdv.toPrettyChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
598
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
599 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
600 if (!isOverride())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
601 warning(loc, "overrides base class function %s, but is not marked with 'override'", fdv.toPrettyChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
602 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
603
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
604 if (fdv.toParent() == parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
605 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
606 // If both are mixins, then error.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
607 // If either is not, the one that is not overrides
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
608 // the other.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
609 if (fdv.parent.isClassDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
610 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
611 if (!this.parent.isClassDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
612 ///static if (!BREAKABI) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
613 && !isDtorDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
614 ///}
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
615 ///version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
616 && !isPostBlitDeclaration()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
617 ///}
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
618 )
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
619 error("multiple overrides of same function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
620 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
621 cd.vtbl.data[vi] = cast(void*)this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
622 vtblIndex = vi;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
623
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
624 /* Remember which functions this overrides
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
625 */
74
7e0d548de9e6 Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 73
diff changeset
626 foverrides.push(fdv);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
627
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
628 /* This works by whenever this function is called,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
629 * it actually returns tintro, which gets dynamically
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
630 * cast to type. But we know that tintro is a base
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
631 * of type, so we could optimize it by not doing a
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
632 * dynamic cast, but just subtracting the isBaseOf()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
633 * offset if the value is != null.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
634 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
635
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
636 if (fdv.tintro)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
637 tintro = fdv.tintro;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
638 else if (!type.equals(fdv.type))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
639 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
640 /* Only need to have a tintro if the vptr
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
641 * offsets differ
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
642 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
643 int offset;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
644 if (fdv.type.nextOf().isBaseOf(type.nextOf(), &offset))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
645 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
646 tintro = fdv.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
647 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
648 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
649 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
650 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
651 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
652
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
653 /* Go through all the interface bases.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
654 * If this function is covariant with any members of those interface
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
655 * functions, set the tintro.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
656 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
657 for (int i = 0; i < cd.interfaces_dim; i++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
658 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
659 BaseClass b = cd.interfaces[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
660 vi = findVtblIndex(b.base.vtbl, b.base.vtbl.dim);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
661 switch (vi)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
662 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
663 case -1:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
664 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
665
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
666 case -2:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
667 cd.sizeok = 2; // can't finish due to forward reference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
668 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
669
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
670 default:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
671 { FuncDeclaration fdv = cast(FuncDeclaration)b.base.vtbl.data[vi];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
672 Type ti = null;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
673
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
674 /* Remember which functions this overrides
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
675 */
74
7e0d548de9e6 Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 73
diff changeset
676 foverrides.push(fdv);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
677
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
678 if (fdv.tintro)
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
679 ti = fdv.tintro;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
680 else if (!type.equals(fdv.type))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
681 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
682 /* Only need to have a tintro if the vptr
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
683 * offsets differ
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
684 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
685 int offset;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
686 if (fdv.type.nextOf().isBaseOf(type.nextOf(), &offset))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
687 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
688 ti = fdv.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
689 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
690 if (offset)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
691 ti = fdv.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
692 else if (type.nextOf().ty == Tclass)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
693 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
694 ClassDeclaration cdn = (cast(TypeClass)type.nextOf()).sym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
695 if (cdn && cdn.sizeok != 1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
696 ti = fdv.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
697 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
698 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
699 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
700 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
701 if (ti)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
702 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
703 if (tintro && !tintro.equals(ti))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
704 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
705 error("incompatible covariant types %s and %s", tintro.toChars(), ti.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
706 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
707 tintro = ti;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
708 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
709 goto L2;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
710 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
711 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
712 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
713
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
714 if (introducing && isOverride())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
715 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
716 error("does not override any function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
717 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
718
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
719 L2: ;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
720 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
721 else if (isOverride() && !parent.isTemplateInstance())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
722 error("override only applies to class member functions");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
723
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
724 /* Do not allow template instances to add virtual functions
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
725 * to a class.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
726 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
727 if (isVirtual())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
728 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
729 TemplateInstance ti = parent.isTemplateInstance();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
730 if (ti)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
731 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
732 // Take care of nested templates
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
733 while (1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
734 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
735 TemplateInstance ti2 = ti.tempdecl.parent.isTemplateInstance();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
736 if (!ti2)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
737 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
738 ti = ti2;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
739 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
740
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
741 // If it's a member template
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
742 ClassDeclaration cdd = ti.tempdecl.isClassMember();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
743 if (cdd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
744 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
745 error("cannot use template to add virtual function to class '%s'", cdd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
746 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
747 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
748 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
749
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
750 if (isMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
751 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
752 // Check parameters to see if they are either () or (char[][] args)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
753 switch (nparams)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
754 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
755 case 0:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
756 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
757
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
758 case 1:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
759 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
760 auto arg0 = Parameter.getNth(f.parameters, 0);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
761 if (arg0.type.ty != TY.Tarray ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
762 arg0.type.nextOf().ty != TY.Tarray ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
763 arg0.type.nextOf().nextOf().ty != TY.Tchar ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
764 arg0.storageClass & (STC.STCout | STC.STCref | STC.STClazy))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
765 goto Lmainerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
766 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
767 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
768
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
769 default:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
770 goto Lmainerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
771 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
772
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
773 if (!f.nextOf())
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
774 error("must return int or void");
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
775 else if (f.nextOf().ty != TY.Tint32 && f.nextOf().ty != TY.Tvoid)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
776 error("must return int or void, not %s", f.nextOf().toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
777 if (f.varargs)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
778 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
779 Lmainerr:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
780 error("parameters must be main() or main(char[][] args)");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
781 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
782 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
783
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
784 if (ident == Id.assign && (sd || cd))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
785 { // Disallow identity assignment operator.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
786
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
787 // opAssign(...)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
788 if (nparams == 0)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
789 { if (f.varargs == 1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
790 goto Lassignerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
791 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
792 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
793 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
794 auto arg0 = Parameter.getNth(f.parameters, 0);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
795 Type t0 = arg0.type.toBasetype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
796 Type tb = sd ? sd.type : cd.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
797 if (arg0.type.implicitConvTo(tb) ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
798 (sd && t0.ty == TY.Tpointer && t0.nextOf().implicitConvTo(tb))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
799 )
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
800 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
801 if (nparams == 1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
802 goto Lassignerr;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
803 auto arg1 = Parameter.getNth(f.parameters, 1);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
804 if (arg1.defaultArg)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
805 goto Lassignerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
806 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
807 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
808 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
809
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
810 if (isVirtual())
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
811 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
812 /* Rewrite contracts as nested functions, then call them.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
813 * Doing it as nested functions means that overriding functions
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
814 * can call them.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
815 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
816 if (frequire)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
817 {
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
818 /* in { ... }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
819 * becomes:
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
820 * void __require() { ... }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
821 * __require();
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
822 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
823 Loc loc = frequire.loc;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
824 TypeFunction tf = new TypeFunction(null, Type.tvoid, 0, LINKd);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
825 FuncDeclaration fd = new FuncDeclaration(loc, loc, Id.require, STCundefined, tf);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
826 fd.fbody = frequire;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
827 Statement s1 = new DeclarationStatement(loc, fd);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
828 Expression e = new CallExp(loc, new VarExp(loc, fd, 0), cast(Expressions)null);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
829 Statement s2 = new ExpStatement(loc, e);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
830 frequire = new CompoundStatement(loc, s1, s2);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
831 fdrequire = fd;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
832 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
833
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
834 if (fensure)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
835 { /* out (result) { ... }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
836 * becomes:
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
837 * tret __ensure(ref tret result) { ... }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
838 * __ensure(result);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
839 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
840 if (!outId && f.nextOf().toBasetype().ty != Tvoid)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
841 outId = Id.result; // provide a default
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
842
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
843 Loc loc = fensure.loc;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
844 auto arguments = new Parameters();
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
845 Parameter a = null;
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
846 if (outId)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
847 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
848 a = new Parameter(STCref, f.nextOf(), outId, null);
126
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
849 arguments.push(a);
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
850 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
851 TypeFunction tf = new TypeFunction(arguments, Type.tvoid, 0, LINKd);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
852 FuncDeclaration fd = new FuncDeclaration(loc, loc, Id.ensure, STCundefined, tf);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
853 fd.fbody = fensure;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
854 Statement s1 = new DeclarationStatement(loc, fd);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
855 Expression eresult = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
856 if (outId)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
857 eresult = new IdentifierExp(loc, outId);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
858 Expression e = new CallExp(loc, new VarExp(loc, fd, 0), eresult);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
859 Statement s2 = new ExpStatement(loc, e);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
860 fensure = new CompoundStatement(loc, s1, s2);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
861 fdensure = fd;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
862 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
863 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
864
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
865 Ldone:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
866 /* Save scope for possible later use (if we need the
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
867 * function internals)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
868 */
87
b17640f0e4e8 Fixed a bug with a Scope.this(Scope enclosing) being called instead of Scope.clone() method (as a copy ctor replacement)
korDen
parents: 79
diff changeset
869 scope_ = sc.clone();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
870 scope_.setNoFree();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
871 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
872
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
873 Lassignerr:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
874 if (sd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
875 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
876 sd.hasIdentityAssign = 1; // don't need to generate it
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
877 goto Ldone;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
878 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
879 error("identity assignment operator overload is illegal");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
880 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
881
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
882 override void semantic2(Scope sc)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
883 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
884 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
885
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
886 // Do the semantic analysis on the internals of the function.
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
887 override void semantic3(Scope sc)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
888 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
889 TypeFunction f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
890 VarDeclaration argptr = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
891 VarDeclaration _arguments = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
892
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
893 if (!parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
894 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
895 if (global.errors)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
896 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
897 //printf("FuncDeclaration.semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
898 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
899 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
900 //printf("FuncDeclaration.semantic3('%s.%s', sc = %p, loc = %s)\n", parent.toChars(), toChars(), sc, loc.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
901 //fflush(stdout);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
902 //printf("storage class = x%x %x\n", sc.stc, storage_class);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
903 //{ static int x; if (++x == 2) *(char*)0=0; }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
904 //printf("\tlinkage = %d\n", sc.linkage);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
905
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
906 //printf(" sc.incontract = %d\n", sc.incontract);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
907 if (semanticRun >= 3)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
908 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
909 semanticRun = 3;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
910
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
911 if (!type || type.ty != TY.Tfunction)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
912 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
913 f = cast(TypeFunction)(type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
914
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
915 // Check the 'throws' clause
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
916 if (fthrows)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
917 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
918 for (int i = 0; i < fthrows.dim; i++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
919 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
920 Type t = cast(Type)fthrows.data[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
921
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
922 t = t.semantic(loc, sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
923 if (!t.isClassHandle())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
924 error("can only throw classes, not %s", t.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
925 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
926 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
927
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
928 frequire = mergeFrequire(frequire);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
929 fensure = mergeFensure(fensure);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
930
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
931 if (fbody || frequire)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
932 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
933 /* Symbol table into which we place parameters and nested functions,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
934 * solely to diagnose name collisions.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
935 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
936 localsymtab = new DsymbolTable();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
937
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
938 // Establish function scope
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
939 ScopeDsymbol ss = new ScopeDsymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
940 ss.parent = sc.scopesym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
941 Scope sc2 = sc.push(ss);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
942 sc2.func = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
943 sc2.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
944 sc2.callSuper = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
945 sc2.sbreak = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
946 sc2.scontinue = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
947 sc2.sw = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
948 sc2.fes = fes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
949 sc2.linkage = LINK.LINKd;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
950 sc2.stc &= ~(STC.STCauto | STC.STCscope | STC.STCstatic | STC.STCabstract | STC.STCdeprecated |
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
951 STC.STC_TYPECTOR | STC.STCfinal | STC.STCtls | STC.STCgshared | STC.STCref |
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
952 STCproperty | STCsafe | STCtrusted | STCsystem);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
953 sc2.protection = PROT.PROTpublic;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
954 sc2.explicitProtection = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
955 sc2.structalign = 8;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
956 sc2.incontract = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
957 sc2.tf = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
958 sc2.noctor = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
959
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
960 // Declare 'this'
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
961 AggregateDeclaration ad = isThis();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
962 if (ad)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
963 { VarDeclaration v;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
964
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
965 if (isFuncLiteralDeclaration() && isNested())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
966 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
967 error("literals cannot be class members");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
968 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
969 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
970 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
971 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
972 assert(!isNested()); // can't be both member and nested
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
973 assert(ad.handle);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
974 Type thandle = ad.handle;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
975 version (STRUCTTHISREF) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
976 thandle = thandle.addMod(type.mod);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
977 thandle = thandle.addStorageClass(storage_class);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
978 if (isPure())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
979 thandle = thandle.addMod(MOD.MODconst);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
980 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
981 if (storage_class & STC.STCconst || type.isConst())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
982 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
983 assert(0); // BUG: shared not handled
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
984 if (thandle.ty == TY.Tclass)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
985 thandle = thandle.constOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
986 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
987 { assert(thandle.ty == TY.Tpointer);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
988 thandle = thandle.nextOf().constOf().pointerTo();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
989 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
990 }
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
991 else if (storage_class & STC.STCimmutable || type.isImmutable())
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
992 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
993 if (thandle.ty == TY.Tclass)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
994 thandle = thandle.invariantOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
995 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
996 { assert(thandle.ty == TY.Tpointer);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
997 thandle = thandle.nextOf().invariantOf().pointerTo();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
998 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
999 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1000 else if (storage_class & STC.STCshared || type.isShared())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1001 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1002 assert(0); // not implemented
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1003 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1004 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1005 v = new ThisDeclaration(loc, thandle);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1006 v.storage_class |= STC.STCparameter;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1007 version (STRUCTTHISREF) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1008 if (thandle.ty == TY.Tstruct)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1009 v.storage_class |= STC.STCref;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1010 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1011 v.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1012 if (!sc2.insert(v))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1013 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1014 v.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1015 vthis = v;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1016 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1017 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1018 else if (isNested())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1019 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1020 /* The 'this' for a nested function is the link to the
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1021 * enclosing function's stack frame.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1022 * Note that nested functions and member functions are disjoint.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1023 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1024 VarDeclaration v = new ThisDeclaration(loc, Type.tvoid.pointerTo());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1025 v.storage_class |= STC.STCparameter;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1026 v.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1027 if (!sc2.insert(v))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1028 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1029 v.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1030 vthis = v;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1031 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1032
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1033 // Declare hidden variable _arguments[] and _argptr
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1034 if (f.varargs == 1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1035 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1036 version (TARGET_NET) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1037 varArgs(sc2, f, argptr, _arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1038 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1039 Type t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1040
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1041 if (f.linkage == LINK.LINKd)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1042 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1043 // Declare _arguments[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1044 version (BREAKABI) {
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1045 v_arguments = new VarDeclaration(Loc(0), global.typeinfotypelist.type, Id._arguments_typeinfo, null);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1046 v_arguments.storage_class = STCparameter;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1047 v_arguments.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1048 sc2.insert(v_arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1049 v_arguments.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1050
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1051 //t = Type.typeinfo.type.constOf().arrayOf();
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1052 t = global.typeinfo.type.arrayOf();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1053 _arguments = new VarDeclaration(Loc(0), t, Id._arguments, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1054 _arguments.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1055 sc2.insert(_arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1056 _arguments.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1057 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1058 t = Type.typeinfo.type.arrayOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1059 v_arguments = new VarDeclaration(Loc(0), t, Id._arguments, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1060 v_arguments.storage_class = STC.STCparameter | STC.STCin;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1061 v_arguments.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1062 sc2.insert(v_arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1063 v_arguments.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1064 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1065 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1066 if (f.linkage == LINK.LINKd || (parameters && parameters.dim))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1067 { // Declare _argptr
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1068 version (IN_GCC) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1069 t = d_gcc_builtin_va_list_d_type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1070 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1071 t = Type.tvoid.pointerTo();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1072 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1073 argptr = new VarDeclaration(Loc(0), t, Id._argptr, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1074 argptr.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1075 sc2.insert(argptr);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1076 argptr.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1077 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1078 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1079 }
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
1080 static if(false) {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1081 // Propagate storage class from tuple parameters to their element-parameters.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1082 if (f.parameters)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1083 {
126
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
1084 foreach (arg; f.parameters)
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
1085 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1086 //printf("[%d] arg.type.ty = %d %s\n", i, arg.type.ty, arg.type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1087 if (arg.type.ty == TY.Ttuple)
126
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
1088 { auto t = cast(TypeTuple)arg.type;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1089 size_t dim = Parameter.dim(t.arguments);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1090 for (size_t j = 0; j < dim; j++)
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1091 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1092 auto narg = Parameter.getNth(t.arguments, j);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1093 narg.storageClass = arg.storageClass;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1094 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1095 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1096 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1097 }
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
1098 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1099 /* Declare all the function parameters as variables
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1100 * and install them in parameters[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1101 */
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1102 size_t nparams = Parameter.dim(f.parameters);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1103 if (nparams)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1104 { /* parameters[] has all the tuples removed, as the back end
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1105 * doesn't know about tuples
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1106 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1107 parameters = new Dsymbols();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1108 parameters.reserve(nparams);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1109 for (size_t i = 0; i < nparams; i++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1110 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1111 auto arg = Parameter.getNth(f.parameters, i);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1112 Identifier id = arg.ident;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1113 if (!id)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1114 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1115 /* Generate identifier for un-named parameter,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1116 * because we need it later on.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1117 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1118 arg.ident = id = Identifier.generateId("_param_", i);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1119 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1120 Type vtype = arg.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1121 if (isPure())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1122 vtype = vtype.addMod(MOD.MODconst);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1123 VarDeclaration v = new VarDeclaration(loc, vtype, id, null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1124 //printf("declaring parameter %s of type %s\n", v.toChars(), v.type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1125 v.storage_class |= STC.STCparameter;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1126 if (f.varargs == 2 && i + 1 == nparams)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1127 v.storage_class |= STC.STCvariadic;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1128 v.storage_class |= arg.storageClass & (STC.STCin | STC.STCout | STC.STCref | STC.STClazy | STC.STCfinal | STC.STC_TYPECTOR | STC.STCnodtor);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1129 v.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1130 if (!sc2.insert(v))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1131 error("parameter %s.%s is already defined", toChars(), v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1132 else
74
7e0d548de9e6 Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 73
diff changeset
1133 parameters.push(v);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1134 localsymtab.insert(v);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1135 v.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1136 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1137 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1138
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1139 // Declare the tuple symbols and put them in the symbol table,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1140 // but not in parameters[].
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1141 if (f.parameters)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1142 {
126
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
1143 foreach (arg; f.parameters)
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
1144 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1145 if (!arg.ident)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1146 continue; // never used, so ignore
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1147 if (arg.type.ty == TY.Ttuple)
126
1765f3ef917d ClassDeclarations, Arguments -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 122
diff changeset
1148 { auto t = cast(TypeTuple)arg.type;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1149 size_t dim = Parameter.dim(t.arguments);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1150 Objects exps = new Objects();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1151 exps.setDim(dim);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1152 for (size_t j = 0; j < dim; j++)
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1153 { auto narg = Parameter.getNth(t.arguments, j);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1154 assert(narg.ident);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1155 VarDeclaration v = sc2.search(Loc(0), narg.ident, null).isVarDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1156 assert(v);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1157 Expression e = new VarExp(v.loc, v);
94
3a0b150c9841 Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 93
diff changeset
1158 exps[j] = e;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1159 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1160 assert(arg.ident);
94
3a0b150c9841 Objects -> Vector!Object iteration 1
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 93
diff changeset
1161 auto v = new TupleDeclaration(loc, arg.ident, exps);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1162 //printf("declaring tuple %s\n", v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1163 v.isexp = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1164 if (!sc2.insert(v))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1165 error("parameter %s.%s is already defined", toChars(), v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1166 localsymtab.insert(v);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1167 v.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1168 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1169 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1170 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1171
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1172 /* Do the semantic analysis on the [in] preconditions and
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1173 * [out] postconditions.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1174 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1175 sc2.incontract++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1176
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1177 if (frequire)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1178 { /* frequire is composed of the [in] contracts
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1179 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1180 // BUG: need to error if accessing out parameters
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1181 // BUG: need to treat parameters as const
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1182 // BUG: need to disallow returns and throws
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1183 // BUG: verify that all in and ref parameters are read
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1184 frequire = frequire.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1185 labtab = null; // so body can't refer to labels
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1186 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1187
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1188 if (fensure || addPostInvariant())
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1189 {
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1190 /* fensure is composed of the [out] contracts
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1191 */
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1192 if (!type.nextOf()) // if return type is inferred
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1193 {
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1194 /* This case:
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1195 * auto fp = function() out { } body { };
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1196 * Can fix by doing semantic() onf fbody first.
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1197 */
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1198 error("post conditions are not supported if the return type is inferred");
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1199 return;
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1200 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1201
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1202 ScopeDsymbol sym = new ScopeDsymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1203 sym.parent = sc2.scopesym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1204 sc2 = sc2.push(sym);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1205
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1206 assert(type.nextOf());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1207 if (type.nextOf().ty == TY.Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1208 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1209 if (outId)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1210 error("void functions have no result");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1211 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1212 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1213 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1214 if (!outId)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1215 outId = Id.result; // provide a default
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1216 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1217
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1218 if (outId)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1219 { // Declare result variable
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1220 Loc loc = this.loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1221
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1222 if (fensure)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1223 loc = fensure.loc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1224
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1225 auto v = new VarDeclaration(loc, type.nextOf(), outId, null);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1226 v.noauto = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1227 version (DMDV2) {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1228 if (!isVirtual())
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1229 v.storage_class |= STC.STCconst;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1230 if (f.isref)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1231 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1232 v.storage_class |= STC.STCref | STC.STCforeach;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1233 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1234 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1235 sc2.incontract--;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1236 v.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1237 sc2.incontract++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1238 if (!sc2.insert(v))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1239 error("out result %s is already defined", v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1240 v.parent = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1241 vresult = v;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1242
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1243 // vresult gets initialized with the function return value
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1244 // in ReturnStatement.semantic()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1245 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1246
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1247 // BUG: need to treat parameters as const
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1248 // BUG: need to disallow returns and throws
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1249 if (fensure)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1250 { fensure = fensure.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1251 labtab = null; // so body can't refer to labels
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1252 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1253
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1254 if (!global.params.useOut)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1255 { fensure = null; // discard
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1256 vresult = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1257 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1258
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1259 // Postcondition invariant
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1260 if (addPostInvariant())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1261 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1262 Expression e = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1263 if (isCtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1264 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1265 // Call invariant directly only if it exists
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1266 InvariantDeclaration inv = ad.inv;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1267 ClassDeclaration cd = ad.isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1268
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1269 while (!inv && cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1270 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1271 cd = cd.baseClass;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1272 if (!cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1273 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1274 inv = cd.inv;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1275 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1276 if (inv)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1277 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1278 e = new DsymbolExp(Loc(0), inv);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1279 e = new CallExp(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1280 e = e.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1281 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1282 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1283 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1284 { // Call invariant virtually
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1285 Expression v = new ThisExp(Loc(0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1286 v.type = vthis.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1287 version (STRUCTTHISREF) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1288 if (ad.isStructDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1289 v = v.addressOf(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1290 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1291 e = new AssertExp(Loc(0), v);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1292 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1293 if (e)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1294 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1295 ExpStatement s = new ExpStatement(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1296 if (fensure)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1297 fensure = new CompoundStatement(Loc(0), s, fensure);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1298 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1299 fensure = s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1300 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1301 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1302
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1303 if (fensure)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1304 { returnLabel = new LabelDsymbol(Id.returnLabel);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1305 LabelStatement ls = new LabelStatement(Loc(0), Id.returnLabel, fensure);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1306 ls.isReturnLabel = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1307 returnLabel.statement = ls;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1308 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1309 sc2 = sc2.pop();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1310 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1311
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1312 sc2.incontract--;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1313
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1314 if (fbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1315 { ClassDeclaration cd = isClassMember();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1316
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1317 /* If this is a class constructor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1318 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1319 if (isCtorDeclaration() && cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1320 {
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1321 for (int i = 0; i < cd.fields.dim; i++)
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1322 { VarDeclaration v = cast(VarDeclaration)cd.fields[i];
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1323
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1324 v.ctorinit = 0;
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1325 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1326 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1327
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1328 if (inferRetType || f.retStyle() != RET.RETstack)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1329 nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1330
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1331 fbody = fbody.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1332 if (!fbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1333 fbody = new CompoundStatement(Loc(0), new Statements());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1334
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1335 if (inferRetType)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1336 { // If no return type inferred yet, then infer a void
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1337 if (!type.nextOf())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1338 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1339 (cast(TypeFunction)type).next = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1340 type = type.semantic(loc, sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1341 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1342 f = cast(TypeFunction)type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1343 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1344
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1345 if (isStaticCtorDeclaration())
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1346 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1347 /* It's a static constructor. Ensure that all
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1348 * ctor consts were initialized.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1349 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1350
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1351 Dsymbol p = toParent();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1352 ScopeDsymbol add = p.isScopeDsymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1353 if (!add)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1354 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1355 error("static constructor can only be member of struct/class/module, not %s %s", p.kind(), p.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1356 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1357 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1358 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1359 foreach (Dsymbol s; add.members)
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1360 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1361 s.checkCtorConstInit();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1362 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1363 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1364 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1365
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1366 if (isCtorDeclaration() && cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1367 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1368 //printf("callSuper = x%x\n", sc2.callSuper);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1369
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1370 // Verify that all the ctorinit fields got initialized
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1371 if (!(sc2.callSuper & CSX.CSXthis_ctor))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1372 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1373 for (int i = 0; i < cd.fields.dim; i++)
79
43073c7c7769 updated to 2.035
Trass3r
parents: 77
diff changeset
1374 { VarDeclaration v = cast(VarDeclaration)cd.fields[i];
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1375
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1376 if (v.ctorinit == 0 && v.isCtorinit())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1377 error("missing initializer for final field %s", v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1378 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1379 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1380
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1381 if (!(sc2.callSuper & CSX.CSXany_ctor) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1382 cd.baseClass && cd.baseClass.ctor)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1383 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1384 sc2.callSuper = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1385
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1386 // Insert implicit super() at start of fbody
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1387 Expression e1 = new SuperExp(Loc(0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1388 Expression e = new CallExp(Loc(0), e1);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1389
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1390 e = e.trySemantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1391 if (!e)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1392 error("no match for implicit super() call in constructor");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1393 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1394 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1395 Statement s = new ExpStatement(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1396 fbody = new CompoundStatement(Loc(0), s, fbody);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1397 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1398 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1399 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1400 else if (fes)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1401 { // For foreach(){} body, append a return 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1402 Expression e = new IntegerExp(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1403 Statement s = new ReturnStatement(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1404 fbody = new CompoundStatement(Loc(0), fbody, s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1405 assert(!returnLabel);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1406 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1407 else if (!hasReturnExp && type.nextOf().ty != TY.Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1408 error("expected to return a value of type %s", type.nextOf().toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1409 else if (!inlineAsm)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1410 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1411 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1412 BE blockexit = fbody ? fbody.blockExit() : BE.BEfallthru;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1413 if (f.isnothrow && blockexit & BE.BEthrow)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1414 error("'%s' is nothrow yet may throw", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1415
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1416 int offend = blockexit & BE.BEfallthru;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1417 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1418 if (type.nextOf().ty == TY.Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1419 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1420 if (offend && isMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1421 { // Add a return 0; statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1422 Statement s = new ReturnStatement(Loc(0), new IntegerExp(0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1423 fbody = new CompoundStatement(Loc(0), fbody, s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1424 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1425 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1426 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1427 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1428 if (offend)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1429 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1430 Expression e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1431 version (DMDV1) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1432 warning(loc, "no return exp; or assert(0); at end of function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1433 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1434 error("no return exp; or assert(0); at end of function");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1435 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1436 if (global.params.useAssert &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1437 !global.params.useInline)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1438 { /* Add an assert(0, msg); where the missing return
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1439 * should be.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1440 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1441 e = new AssertExp(
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1442 endloc,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1443 new IntegerExp(0),
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1444 new StringExp(loc, "missing return expression")
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1445 );
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1446 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1447 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1448 e = new HaltExp(endloc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1449
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1450 e = new CommaExp(Loc(0), e, type.nextOf().defaultInit(Loc(0)));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1451 e = e.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1452 Statement s = new ExpStatement(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1453 fbody = new CompoundStatement(Loc(0), fbody, s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1454 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1455 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1456 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1457 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1458
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1459 {
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1460 auto a = new Statements();
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1461
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1462 // Merge in initialization of 'out' parameters
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1463 if (parameters)
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1464 { foreach (Dsymbol s; parameters)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1465 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1466 auto v = cast(VarDeclaration)s;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1467 if (v.storage_class & STC.STCout)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1468 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1469 assert(v.init);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1470 ExpInitializer ie = v.init.isExpInitializer();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1471 assert(ie);
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1472 a.push(new ExpStatement(Loc(0), ie.exp));
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1473 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1474 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1475 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1476
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1477 if (argptr)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1478 { // Initialize _argptr to point past non-variadic arg
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1479 version (IN_GCC) {
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1480 // Handled in FuncDeclaration.toObjFile
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1481 v_argptr = argptr;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1482 v_argptr.init = new VoidInitializer(loc);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1483 } else {
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1484 Type t = argptr.type;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1485 VarDeclaration p;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1486 uint offset;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1487
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1488 Expression e1 = new VarExp(Loc(0), argptr);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1489 if (parameters && parameters.dim)
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1490 p = cast(VarDeclaration)parameters[parameters.length - 1];
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1491 else
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1492 p = v_arguments; // last parameter is _arguments[]
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1493 if (p.storage_class & STClazy)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1494 // If the last parameter is lazy, it's the size of a delegate
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1495 offset = PTRSIZE * 2;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1496 else
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1497 offset = cast(size_t)p.type.size();
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1498 offset = (offset + 3) & ~3; // assume stack aligns on 4
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1499 Expression e = new SymOffExp(Loc(0), p, offset);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1500 e = new AssignExp(Loc(0), e1, e);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
1501 e.type = t;
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1502 a.push(new ExpStatement(Loc(0), e));
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
1503 p.isargptr = true;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1504 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1505 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1506
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1507 if (_arguments)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1508 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1509 /* Advance to elements[] member of TypeInfo_Tuple with:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1510 * _arguments = v_arguments.elements;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1511 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1512 Expression e = new VarExp(Loc(0), v_arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1513 e = new DotIdExp(Loc(0), e, Id.elements);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1514 Expression e1 = new VarExp(Loc(0), _arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1515 e = new AssignExp(Loc(0), e1, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1516 e.op = TOK.TOKconstruct;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1517 e = e.semantic(sc2);
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1518 a.push(new ExpStatement(Loc(0), e));
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1519 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1520
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1521 // Merge contracts together with body into one compound statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1522
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1523 version (_DH) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1524 if (frequire && global.params.useIn)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1525 { frequire.incontract = 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1526 a.push(frequire);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1527 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1528 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1529 if (frequire && global.params.useIn)
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1530 a.push(frequire);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1531 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1532
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1533 // Precondition invariant
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1534 if (addPreInvariant())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1535 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1536 Expression e = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1537 if (isDtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1538 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1539 // Call invariant directly only if it exists
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1540 InvariantDeclaration inv = ad.inv;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1541 ClassDeclaration cd = ad.isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1542
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1543 while (!inv && cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1544 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1545 cd = cd.baseClass;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1546 if (!cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1547 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1548 inv = cd.inv;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1549 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1550 if (inv)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1551 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1552 e = new DsymbolExp(Loc(0), inv);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1553 e = new CallExp(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1554 e = e.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1555 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1556 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1557 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1558 { // Call invariant virtually
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1559 Expression v = new ThisExp(Loc(0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1560 v.type = vthis.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1561 version (STRUCTTHISREF) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1562 if (ad.isStructDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1563 v = v.addressOf(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1564 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1565 Expression se = new StringExp(Loc(0), "null this");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1566 se = se.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1567 se.type = Type.tchar.arrayOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1568 e = new AssertExp(loc, v, se);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1569 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1570 if (e)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1571 {
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1572 auto s = new ExpStatement(Loc(0), e);
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1573 a.push(s);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1574 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1575 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1576
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1577 if (fbody)
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1578 a.push(fbody);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1579
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1580 if (fensure)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1581 {
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1582 a.push(returnLabel.statement);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1583
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1584 if (type.nextOf().ty != TY.Tvoid)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1585 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1586 // Create: return vresult;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1587 assert(vresult);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1588 Expression e = new VarExp(Loc(0), vresult);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1589 if (tintro)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1590 { e = e.implicitCastTo(sc, tintro.nextOf());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1591 e = e.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1592 }
122
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1593 auto s = new ReturnStatement(Loc(0), e);
c77e9f4f1793 Statements -> Vector
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 114
diff changeset
1594 a.push(s);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1595 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1596 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1597
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1598 fbody = new CompoundStatement(Loc(0), a);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1599 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1600 /* Append destructor calls for parameters as finally blocks.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1601 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1602 if (parameters)
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1603 { foreach(Dsymbol symb; parameters)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1604 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
1605 auto v = cast(VarDeclaration)symb;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1606
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1607 if (v.storage_class & (STC.STCref | STC.STCout))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1608 continue;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1609
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1610 /* Don't do this for static arrays, since static
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1611 * arrays are called by reference. Remove this
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1612 * when we change them to call by value.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1613 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1614 if (v.type.toBasetype().ty == TY.Tsarray)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1615 continue;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1616
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1617 Expression e = v.callAutoDtor(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1618 if (e)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1619 { Statement s = new ExpStatement(Loc(0), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1620 s = s.semantic(sc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1621 if (fbody.blockExit() == BE.BEfallthru)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1622 fbody = new CompoundStatement(Loc(0), fbody, s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1623 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1624 fbody = new TryFinallyStatement(Loc(0), fbody, s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1625 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1626 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1627 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1628 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1629
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1630 static if (true) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1631 if (isSynchronized())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1632 { /* Wrap the entire function body in a synchronized statement
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1633 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1634 ClassDeclaration cd = parent.isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1635 if (cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1636 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1637 ///version (TARGET_WINDOS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1638 if (/*config.flags2 & CFG2.CFG2seh &&*/ // always on for WINDOS
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1639 !isStatic() && !fbody.usesEH())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1640 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1641 /* The back end uses the "jmonitor" hack for syncing;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1642 * no need to do the sync at this level.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1643 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1644 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1645 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1646 ///}
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1647 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1648 Expression vsync;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1649 if (isStatic())
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1650 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1651 // The monitor is in the ClassInfo
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1652 vsync = new DotIdExp(loc, new DsymbolExp(loc, cd), Id.classinfo_);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1653 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1654 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1655 { // 'this' is the monitor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1656 vsync = new VarExp(loc, vthis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1657 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1658 fbody = new PeelStatement(fbody); // don't redo semantic()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1659 fbody = new SynchronizedStatement(loc, vsync, fbody);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1660 fbody = fbody.semantic(sc2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1661 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1662 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1663 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1664 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1665 error("synchronized function %s must be a member of a class", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1666 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1667 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1668 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1669 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1670
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1671 sc2.callSuper = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1672 sc2.pop();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1673 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1674 semanticRun = 4;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1675 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1676
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1677 // called from semantic3
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1678 void varArgs(Scope sc, TypeFunction, ref VarDeclaration, ref VarDeclaration)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1679 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1680 assert(false);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1681 }
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1682
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1683 override void toCBuffer(OutBuffer buf, HdrGenState* hgs)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1684 {
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1685 // writef("FuncDeclaration.toCBuffer() '%s'\n", toChars());
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1686
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1687 StorageClassDeclaration.stcToCBuffer(buf, storage_class);
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1688 type.toCBuffer(buf, ident, hgs);
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1689 bodyToCBuffer(buf, hgs);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1690 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1691
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1692 void bodyToCBuffer(OutBuffer buf, HdrGenState* hgs)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1693 {
93
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1694 if (fbody &&
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1695 (!hgs.hdrgen || hgs.tpltMember || canInline(1,1))
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1696 )
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1697 {
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1698 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1699
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1700 // in{}
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1701 if (frequire)
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1702 {
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1703 buf.writestring("in");
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1704 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1705 frequire.toCBuffer(buf, hgs);
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1706 }
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1707
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1708 // out{}
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1709 if (fensure)
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1710 {
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1711 buf.writestring("out");
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1712 if (outId)
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1713 {
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1714 buf.writebyte('(');
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1715 buf.writestring(outId.toChars());
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1716 buf.writebyte(')');
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1717 }
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1718 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1719 fensure.toCBuffer(buf, hgs);
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1720 }
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1721
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1722 if (frequire || fensure)
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1723 {
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1724 buf.writestring("body");
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1725 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1726 }
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1727
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1728 buf.writebyte('{');
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1729 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1730 fbody.toCBuffer(buf, hgs);
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1731 buf.writebyte('}');
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1732 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1733 }
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1734 else
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1735 { buf.writeByte(';');
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1736 buf.writenl();
df6d0f967680 implemented a whole bunch of methods to make phobos 2.035 compile
Trass3r
parents: 91
diff changeset
1737 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1738 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1739
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1740 /****************************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1741 * Determine if 'this' overrides fd.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1742 * Return true if it does.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1743 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1744 bool overrides(FuncDeclaration fd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1745 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1746 bool result = false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1747
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1748 if (fd.ident == ident)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1749 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1750 int cov = type.covariant(fd.type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1751 if (cov)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1752 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1753 ClassDeclaration cd1 = toParent().isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1754 ClassDeclaration cd2 = fd.toParent().isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1755
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1756 if (cd1 && cd2 && cd2.isBaseOf(cd1, null))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1757 result = true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1758 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1759 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1760 return result;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1761 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1762
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1763 /*************************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1764 * Find index of function in vtbl[0..dim] that
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1765 * this function overrides.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1766 * Returns:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1767 * -1 didn't find one
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1768 * -2 can't determine because of forward references
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1769 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1770 int findVtblIndex(Array vtbl, int dim)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1771 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1772 for (int vi = 0; vi < dim; vi++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1773 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1774 FuncDeclaration fdv = (cast(Dsymbol)vtbl.data[vi]).isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1775 if (fdv && fdv.ident is ident)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1776 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1777 int cov = type.covariant(fdv.type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1778 //printf("\tbaseclass cov = %d\n", cov);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1779 switch (cov)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1780 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1781 case 0: // types are distinct
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1782 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1783
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1784 case 1:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1785 return vi;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1786
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1787 case 2:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1788 //type.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1789 //fdv.type.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1790 //printf("%s %s\n", type.deco, fdv.type.deco);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1791 error("of type %s overrides but is not covariant with %s of type %s",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1792 type.toChars(), fdv.toPrettyChars(), fdv.type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1793 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1794
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1795 case 3:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1796 return -2; // forward references
157
b7b61140701d * added all missing default cases in switch statements
trass3r
parents: 156
diff changeset
1797
b7b61140701d * added all missing default cases in switch statements
trass3r
parents: 156
diff changeset
1798 default:
b7b61140701d * added all missing default cases in switch statements
trass3r
parents: 156
diff changeset
1799 writef("cov = %d\n", cov);
b7b61140701d * added all missing default cases in switch statements
trass3r
parents: 156
diff changeset
1800 assert(false);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1801 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1802 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1803 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1804 return -1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1805 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1806
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1807 /****************************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1808 * Overload this FuncDeclaration with the new one f.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1809 * Return !=0 if successful; i.e. no conflict.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1810 */
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
1811 override bool overloadInsert(Dsymbol s)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1812 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1813 FuncDeclaration f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1814 AliasDeclaration a;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1815
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1816 //writef("FuncDeclaration.overloadInsert(%s)\n", s.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1817 a = s.isAliasDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1818 if (a)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1819 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1820 if (overnext)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1821 return overnext.overloadInsert(a);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1822
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1823 if (!a.aliassym && a.type.ty != TY.Tident && a.type.ty != TY.Tinstance)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1824 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1825 //writef("\ta = '%s'\n", a.type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1826 return false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1827 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1828 overnext = a;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1829 //printf("\ttrue: no conflict\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1830 return true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1831 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1832 f = s.isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1833 if (!f)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1834 return false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1835
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1836 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1837 /* Disable this check because:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1838 * const void foo();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1839 * semantic() isn't run yet on foo(), so the const hasn't been
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1840 * applied yet.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1841 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1842 if (type)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1843 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1844 printf("type = %s\n", type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1845 printf("f.type = %s\n", f.type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1846 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1847 if (type && f.type && // can be null for overloaded constructors
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1848 f.type.covariant(type) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1849 f.type.mod == type.mod &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1850 !isFuncAliasDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1851 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1852 //printf("\tfalse: conflict %s\n", kind());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1853 return false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1854 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1855 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1856
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1857 if (overnext)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1858 return overnext.overloadInsert(f);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1859 overnext = f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1860 //printf("\ttrue: no conflict\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1861 return true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1862 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1863
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1864 FuncDeclaration overloadExactMatch(Type t)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1865 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1866 Param1 p;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1867 p.t = t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1868 p.f = null;
158
80f4806ffa13 overloadApply fixes
korDen
parents: 157
diff changeset
1869 overloadApply(this, p);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1870 return p.f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1871 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1872
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1873 FuncDeclaration overloadResolve(Loc loc, Expression ethis, Expressions arguments, int flags = 0)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1874 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1875 TypeFunction tf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1876 Match m;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1877
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1878 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1879 printf("FuncDeclaration.overloadResolve('%s')\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1880 if (arguments)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1881 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1882 int i;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1883
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1884 for (i = 0; i < arguments.dim; i++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1885 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1886 Expression arg;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1887
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1888 arg = cast(Expression)arguments.data[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1889 assert(arg.type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1890 printf("\t%s: ", arg.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1891 arg.type.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1892 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1893 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1894 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1895
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1896 m.last = MATCH.MATCHnomatch;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1897 overloadResolveX(&m, this, ethis, arguments);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1898
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1899 if (m.count == 1) // exactly one match
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1900 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1901 return m.lastf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1902 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1903 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1904 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1905 scope OutBuffer buf = new OutBuffer();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1906
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1907 buf.writeByte('(');
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1908 if (arguments)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1909 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1910 HdrGenState hgs;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1911
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1912 argExpTypesToCBuffer(buf, arguments, &hgs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1913 buf.writeByte(')');
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1914 if (ethis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1915 ethis.type.modToBuffer(buf);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1916 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1917 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1918 buf.writeByte(')');
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1919
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1920 if (m.last == MATCH.MATCHnomatch)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1921 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1922 if (flags & 1) // if do not print error messages
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1923 return null; // no match
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1924
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1925 tf = cast(TypeFunction)type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1926
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1927 scope OutBuffer buf2 = new OutBuffer();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1928 tf.modToBuffer(buf2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1929
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1930 //printf("tf = %s, args = %s\n", tf.deco, ((Expression *)arguments.data[0]).type.deco);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1931 error(loc, "%s%s is not callable using argument types %s",
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1932 Parameter.argsTypesToChars(tf.parameters, tf.varargs),
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1933 buf2.toChars(),
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1934 buf.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1935 return m.anyf; // as long as it's not a FuncAliasDeclaration
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1936 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1937 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1938 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1939 static if (true) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1940 TypeFunction t1 = cast(TypeFunction)m.lastf.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1941 TypeFunction t2 = cast(TypeFunction)m.nextf.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1942
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1943 error(loc, "called with argument types:\n\t(%s)\nmatches both:\n\t%s%s\nand:\n\t%s%s",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1944 buf.toChars(),
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1945 m.lastf.toPrettyChars(), Parameter.argsTypesToChars(t1.parameters, t1.varargs),
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1946 m.nextf.toPrettyChars(), Parameter.argsTypesToChars(t2.parameters, t2.varargs));
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1947 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1948 error(loc, "overloads %s and %s both match argument list for %s",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1949 m.lastf.type.toChars(),
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1950 m.nextf.type.toChars(),
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1951 m.lastf.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1952 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1953 return m.lastf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1954 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1955 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1956 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
1957
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1958 /*************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1959 * Determine partial specialization order of 'this' vs g.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1960 * This is very similar to TemplateDeclaration.leastAsSpecialized().
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1961 * Returns:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1962 * match 'this' is at least as specialized as g
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1963 * 0 g is more specialized than 'this'
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1964 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1965 MATCH leastAsSpecialized(FuncDeclaration g)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1966 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1967 version (LOG_LEASTAS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1968 printf("%s.leastAsSpecialized(%s)\n", toChars(), g.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1969 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1970
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1971 /* This works by calling g() with f()'s parameters, and
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1972 * if that is possible, then f() is at least as specialized
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1973 * as g() is.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1974 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1975
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1976 TypeFunction tf = cast(TypeFunction)type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1977 TypeFunction tg = cast(TypeFunction)g.type;
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1978 size_t nfparams = Parameter.dim(tf.parameters);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
1979 size_t ngparams = Parameter.dim(tg.parameters);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1980 MATCH match = MATCHexact;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1981
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1982 /* If both functions have a 'this' pointer, and the mods are not
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1983 * the same and g's is not const, then this is less specialized.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1984 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1985 if (needThis() && g.needThis())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1986 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1987 if (tf.mod != tg.mod)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1988 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1989 if (tg.mod == MODconst)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1990 match = MATCHconst;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1991 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1992 return MATCHnomatch;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1993 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1994 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1995
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1996 /* Create a dummy array of arguments out of the parameters to f()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1997 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1998 scope Expressions args = new Expressions();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
1999 args.setDim(nfparams);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2000 for (int u = 0; u < nfparams; u++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2001 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2002 auto p = Parameter.getNth(tf.parameters, u);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2003 Expression e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2004 if (p.storageClass & (STCref | STCout))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2005 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2006 e = new IdentifierExp(Loc(0), p.ident);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2007 e.type = p.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2008 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2009 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2010 e = p.type.defaultInit(Loc(0));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2011
84
be2ab491772e Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 79
diff changeset
2012 args[u] = e;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2013 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2014
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2015 MATCH m = cast(MATCH) tg.callMatch(null, args);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2016 if (m)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2017 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2018 /* A variadic parameter list is less specialized than a
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2019 * non-variadic one.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2020 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2021 if (tf.varargs && !tg.varargs)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2022 goto L1; // less specialized
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2023
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2024 version (LOG_LEASTAS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2025 printf(" matches %d, so is least as specialized\n", m);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2026 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2027 return m;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2028 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2029 L1:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2030 version (LOG_LEASTAS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2031 printf(" doesn't match, so is not as specialized\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2032 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2033 return MATCHnomatch;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2034 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2035
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2036 /********************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2037 * Labels are in a separate scope, one per function.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2038 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2039 LabelDsymbol searchLabel(Identifier ident)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2040 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2041 Dsymbol s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2042
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2043 if (!labtab)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2044 labtab = new DsymbolTable(); // guess we need one
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2045
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2046 s = labtab.lookup(ident);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2047 if (!s)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2048 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2049 s = new LabelDsymbol(ident);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2050 labtab.insert(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2051 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2052
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2053 return cast(LabelDsymbol)s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2054 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2055
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2056 /****************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2057 * If non-static member function that has a 'this' pointer,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2058 * return the aggregate it is a member of.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2059 * Otherwise, return null.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2060 */
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2061 override AggregateDeclaration isThis()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2062 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2063 AggregateDeclaration ad = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2064
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2065 //printf("+FuncDeclaration.isThis() '%s'\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2066 if ((storage_class & STC.STCstatic) == 0)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2067 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2068 ad = isMember2();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2069 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2070 //printf("-FuncDeclaration.isThis() %p\n", ad);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2071 return ad;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2072 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2073
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2074 AggregateDeclaration isMember2()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2075 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2076 AggregateDeclaration ad = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2077
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2078 //printf("+FuncDeclaration.isMember2() '%s'\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2079 for (Dsymbol s = this; s; s = s.parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2080 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2081 //printf("\ts = '%s', parent = '%s', kind = %s\n", s.toChars(), s.parent.toChars(), s.parent.kind());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2082 ad = s.isMember();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2083 if (ad)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2084 { //printf("test4\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2085 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2086 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2087 if (!s.parent || (!s.parent.isTemplateInstance()))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2088 { //printf("test5\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2089 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2090 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2091 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2092 //printf("-FuncDeclaration.isMember2() %p\n", ad);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2093 return ad;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2094 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2095
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2096 /*****************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2097 * Determine lexical level difference from 'this' to nested function 'fd'.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2098 * Error if this cannot call fd.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2099 * Returns:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2100 * 0 same level
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2101 * -1 increase nesting by 1 (fd is nested within 'this')
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2102 * >0 decrease nesting by number
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2103 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2104 int getLevel(Loc loc, FuncDeclaration fd) // lexical nesting level difference
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2105 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2106 int level;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2107 Dsymbol s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2108 Dsymbol fdparent;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2109
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2110 //printf("FuncDeclaration.getLevel(fd = '%s')\n", fd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2111 fdparent = fd.toParent2();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2112 if (fdparent == this)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2113 return -1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2114 s = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2115 level = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2116 while (fd != s && fdparent != s.toParent2())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2117 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2118 //printf("\ts = '%s'\n", s.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2119 FuncDeclaration thisfd = s.isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2120 if (thisfd)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2121 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2122 if (!thisfd.isNested() && !thisfd.vthis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2123 goto Lerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2124 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2125 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2126 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2127 AggregateDeclaration thiscd = s.isAggregateDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2128 if (thiscd)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2129 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2130 if (!thiscd.isNested())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2131 goto Lerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2132 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2133 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2134 goto Lerr;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2135 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2136
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2137 s = s.toParent2();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2138 assert(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2139 level++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2140 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2141 return level;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2142
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2143 Lerr:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2144 error(loc, "cannot access frame of function %s", fd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2145 return 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2146 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2147
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2148 void appendExp(Expression e)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2149 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2150 assert(false);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2151 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2152
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2153 void appendState(Statement s)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2154 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2155 assert(false);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2156 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2157
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2158 override string mangle()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2159 out (result)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2160 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2161 assert(result.length > 0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2162 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2163 body
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2164 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2165 if (isMain()) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2166 return "_Dmain";
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2167 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2168
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2169 if (isWinMain() || isDllMain() || ident == Id.tls_get_addr)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2170 return ident.toChars();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2171
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2172 assert(this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2173
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2174 return Declaration.mangle();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2175 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2176
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2177 override string toPrettyChars()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2178 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2179 if (isMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2180 return "D main";
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2181 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2182 return Dsymbol.toPrettyChars();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2183 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2184
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2185 int isMain()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2186 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2187 return ident is Id.main && linkage != LINK.LINKc && !isMember() && !isNested();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2188 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2189
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2190 int isWinMain()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2191 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2192 //printf("FuncDeclaration::isWinMain() %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2193 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2194 int x = ident == Id.WinMain &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2195 linkage != LINK.LINKc && !isMember();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2196 printf("%s\n", x ? "yes" : "no");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2197 return x;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2198 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2199 return ident == Id.WinMain && linkage != LINK.LINKc && !isMember();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2200 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2201 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2202
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2203 int isDllMain()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2204 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2205 return ident == Id.DllMain && linkage != LINK.LINKc && !isMember();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2206 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2207
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2208 /**********************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2209 * Determine if function is a builtin one that we can
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2210 * evaluate at compile time.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2211 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2212 BUILTIN isBuiltin()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2213 {
167
50a6d232176c rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents: 158
diff changeset
2214 enum FeZe = "FNaNbeZe"; // pure nothrow real function(real)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2215
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2216 //printf("FuncDeclaration::isBuiltin() %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2217 if (builtin == BUILTIN.BUILTINunknown)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2218 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2219 builtin = BUILTIN.BUILTINnot;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2220 if (parent && parent.isModule())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2221 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2222 // If it's in the std.math package
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2223 if (parent.ident == Id.math && parent.parent && parent.parent.ident == Id.std && !parent.parent.parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2224 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2225 //printf("deco = %s\n", type.deco);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2226 if (type.deco == FeZe)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2227 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2228 if (ident == Id.sin)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2229 builtin = BUILTIN.BUILTINsin;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2230 else if (ident == Id.cos)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2231 builtin = BUILTIN.BUILTINcos;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2232 else if (ident == Id.tan)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2233 builtin = BUILTIN.BUILTINtan;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2234 else if (ident == Id._sqrt)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2235 builtin = BUILTIN.BUILTINsqrt;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2236 else if (ident == Id.fabs)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2237 builtin = BUILTIN.BUILTINfabs;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2238 //printf("builtin = %d\n", builtin);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2239 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2240 // if float or double versions
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2241 else if (type.deco == "FNaNbdZd" || type.deco == "FNaNbfZf")
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2242 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2243 if (ident == Id._sqrt)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2244 builtin = BUILTIN.BUILTINsqrt;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2245 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2246 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2247 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2248 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2249
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2250 return builtin;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2251 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2252
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2253 override bool isExport()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2254 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2255 return protection == PROT.PROTexport;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2256 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2257
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2258 override bool isImportedSymbol()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2259 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2260 //printf("isImportedSymbol()\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2261 //printf("protection = %d\n", protection);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2262 return (protection == PROT.PROTexport) && !fbody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2263 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2264
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2265 override bool isAbstract()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2266 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2267 return (storage_class & STC.STCabstract) != 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2268 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2269
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2270 override bool isCodeseg()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2271 {
68
ee3a9f34dc48 final bits of codegen implementation to compile Phobos
korDen
parents: 63
diff changeset
2272 return true; // functions are always in the code segment
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2273 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2274
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2275 override bool isOverloadable()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2276 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2277 return 1; // functions can be overloaded
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2278 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2279
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2280 bool isPure()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2281 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2282 //printf("FuncDeclaration::isPure() '%s'\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2283 assert(type.ty == TY.Tfunction);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2284 return (cast(TypeFunction)this.type).ispure;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2285 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2286
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2287 int isSafe()
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2288 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2289 assert(type.ty == TY.Tfunction);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2290 return (cast(TypeFunction)this.type).trust == TRUST.TRUSTsafe;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2291 }
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2292
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2293 int isTrusted()
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2294 {
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2295 assert(type.ty == TY.Tfunction);
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2296 return (cast(TypeFunction)this.type).trust == TRUST.TRUSTtrusted;
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2297 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2298
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2299 bool isNested()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2300 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2301 //if (!toParent())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2302 //printf("FuncDeclaration.isNested('%s') parent=%p\n", toChars(), parent);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2303 //printf("\ttoParent2() = '%s'\n", toParent2().toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2304 return ((storage_class & STC.STCstatic) == 0) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2305 (toParent2().isFuncDeclaration() !is null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2306 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2307
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2308 override bool needThis()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2309 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2310 //printf("FuncDeclaration.needThis() '%s'\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2311 bool needThis = isThis() !is null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2312
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2313 //printf("\t%d\n", i);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2314 if (!needThis) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2315 if (auto fa = isFuncAliasDeclaration()) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2316 needThis = fa.funcalias.needThis();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2317 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2318 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2319
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2320 return needThis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2321 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2322
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2323 bool isVirtual()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2324 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2325 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2326 printf("FuncDeclaration.isVirtual(%s)\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2327 printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROT.PROTprivate, isCtorDeclaration(), linkage != LINK.LINKd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2328 printf("result is %d\n",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2329 isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2330 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2331 return isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && toParent().isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2332 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2333
139
bc45b1c53019 made StorageClass type-safe
Trass3r
parents: 135
diff changeset
2334 override bool isFinal()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2335 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2336 ClassDeclaration cd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2337 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2338 printf("FuncDeclaration.isFinal(%s)\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2339 printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROT.PROTprivate, isCtorDeclaration(), linkage != LINK.LINKd);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2340 printf("result is %d\n",
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2341 isMember() && !(isStatic() || protection == PROT.PROTprivate || protection == PROT.PROTpackage) && (cd = toParent().isClassDeclaration()) !is null && cd.storage_class & STC.STCfinal);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2342 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2343 return isMember() && (Declaration.isFinal() || ((cd = toParent().isClassDeclaration()) !is null && cd.storage_class & STC.STCfinal));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2344 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2345
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2346 bool addPreInvariant()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2347 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2348 AggregateDeclaration ad = isThis();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2349 return (ad &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2350 //ad.isClassDeclaration() &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2351 global.params.useInvariants &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2352 (protection == PROT.PROTpublic || protection == PROT.PROTexport) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2353 !naked &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2354 ident !is Id.cpctor);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2355 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2356
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2357 bool addPostInvariant()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2358 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2359 AggregateDeclaration ad = isThis();
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2360 return (ad && ad.inv &&
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2361 //ad.isClassDeclaration() &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2362 global.params.useInvariants &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2363 (protection == PROT.PROTpublic || protection == PROT.PROTexport) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2364 !naked &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2365 ident !is Id.cpctor);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2366 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2367
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2368 /*************************************
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2369 * Attempt to interpret a function given the arguments.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2370 * Input:
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2371 * istate state for calling function (null if none)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2372 * arguments function arguments
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2373 * thisarg 'this', if a needThis() function, null if not.
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2374 *
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2375 * Return result expression if successful, null if not.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2376 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2377 Expression interpret(InterState istate, Expressions arguments, Expression thisarg = null)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2378 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2379 version (LOG) {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2380 printf("\n********\nFuncDeclaration.interpret(istate = %p) %s\n", istate, toChars());
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2381 printf("cantInterpret = %d, semanticRun = %d\n", cantInterpret, semanticRun);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2382 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2383 if (global.errors)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2384 return null;
107
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2385 version(DMDV1)
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2386 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2387 if (ident == Id.aaLen)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2388 return interpret_aaLen(istate, arguments);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2389 else if (ident == Id.aaKeys)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2390 return interpret_aaKeys(istate, arguments);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2391 else if (ident == Id.aaValues)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2392 return interpret_aaValues(istate, arguments);
107
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2393 }
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2394 else version(DMDV2)
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2395 {
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2396 if (thisarg && (!arguments || arguments.dim == 0))
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2397 {
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2398 if (ident == Id.length)
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2399 return interpret_length(istate, thisarg);
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2400 else if (ident == Id.keys)
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2401 return interpret_keys(istate, thisarg, this);
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2402 else if (ident == Id.values)
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2403 return interpret_values(istate, thisarg, this);
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2404 }
d8f19d85fadb changes from interpret.c
Trass3r
parents: 98
diff changeset
2405 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2406
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2407 if (cantInterpret || semanticRun == 3)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2408 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2409
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2410 if (!fbody)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2411 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2412 cantInterpret = 1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2413 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2414 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2415
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2416 if (semanticRun < 3 && scope_)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2417 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2418 semantic3(scope_);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2419 if (global.errors) // if errors compiling this function
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2420 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2421 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2422 if (semanticRun < 4)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2423 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2424
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2425 Type tb = type.toBasetype();
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2426 assert(tb.ty == Tfunction);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2427 TypeFunction tf = cast(TypeFunction)tb;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2428 Type tret = tf.next.toBasetype();
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
2429 if (tf.varargs && arguments && parameters && arguments.dim != parameters.dim)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2430 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2431 cantInterpret = 1;
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
2432 error("C-style variadic functions are not yet implemented in CTFE");
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2433 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2434 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2435
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2436 // Ensure there are no lazy parameters
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2437 if (tf.parameters)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2438 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2439 size_t dim = Parameter.dim(tf.parameters);
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2440 for (size_t i = 0; i < dim; i++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2441 {
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2442 auto arg = Parameter.getNth(tf.parameters, i);
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2443 if (arg.storageClass & STClazy)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2444 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2445 cantInterpret = 1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2446 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2447 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2448 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2449 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2450
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2451 scope InterState istatex = new InterState();
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2452 istatex.caller = istate;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2453 istatex.fd = this;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2454 istatex.localThis = thisarg;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2455
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2456 scope Expressions vsave = new Expressions(); // place to save previous parameter values
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2457 size_t dim = 0;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2458 if (needThis() && !thisarg)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2459 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2460 cantInterpret = 1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2461 // error, no this. Prevent segfault.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2462 error("need 'this' to access member %s", toChars());
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2463 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2464 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2465 if (arguments)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2466 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2467 dim = arguments.dim;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2468 assert(!dim || (parameters && (parameters.dim == dim)));
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2469 vsave.setDim(dim);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2470
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2471 /* Evaluate all the arguments to the function,
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2472 * store the results in eargs[]
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2473 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2474 scope Expressions eargs = new Expressions();
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2475 eargs.setDim(dim);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2476
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2477 for (size_t i = 0; i < dim; i++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2478 {
90
39648eb578f6 more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 88
diff changeset
2479 Expression earg = arguments[i];
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2480 auto arg = Parameter.getNth(tf.parameters, i);
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2481
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2482 if (arg.storageClass & (STCout | STCref))
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2483 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2484 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2485 else
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2486 { /* Value parameters
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2487 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2488 Type ta = arg.type.toBasetype();
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2489 if (ta.ty == Tsarray && earg.op == TOKaddress)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2490 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2491 /* Static arrays are passed by a simple pointer.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2492 * Skip past this to get at the actual arg.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2493 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2494 earg = (cast(AddrExp)earg).e1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2495 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2496 earg = earg.interpret(istate ? istate : istatex);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2497 if (earg is EXP_CANT_INTERPRET)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2498 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2499 cantInterpret = 1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2500 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2501 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2502 }
84
be2ab491772e Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 79
diff changeset
2503 eargs[i] = earg;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2504 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2505
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2506 for (size_t i = 0; i < dim; i++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2507 {
84
be2ab491772e Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 79
diff changeset
2508 auto earg = eargs[i];
130
60bb0fe4563e dmdfe 2.037 first main iteration
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 126
diff changeset
2509 auto arg = Parameter.getNth(tf.parameters, i);
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2510 auto v = cast(VarDeclaration)parameters[i];
84
be2ab491772e Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 79
diff changeset
2511 vsave[i] = v.value;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2512 version (LOG) {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2513 printf("arg[%d] = %s\n", i, earg.toChars());
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2514 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2515 if (arg.storageClass & (STCout | STCref) && earg.op==TOKvar)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2516 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2517 /* Bind out or ref parameter to the corresponding
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2518 * variable v2
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2519 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2520 if (!istate)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2521 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2522 cantInterpret = 1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2523 error("%s cannot be by passed by reference at compile time", earg.toChars());
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2524 return null; // can't bind to non-interpreted vars
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2525 }
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2526 // We need to chase down all of the the passed parameters until
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2527 // we find something that isn't a TOKvar, then create a variable
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2528 // containg that expression.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2529 VarDeclaration v2;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2530 while (1)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2531 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2532 VarExp ve = cast(VarExp)earg;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2533 v2 = ve.var.isVarDeclaration();
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2534 if (!v2)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2535 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2536 cantInterpret = 1;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2537 return null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2538 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2539 if (!v2.value || v2.value.op != TOKvar)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2540 break;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2541 if ((cast(VarExp)v2.value).var.isSymbolDeclaration())
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2542 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2543 // This can happen if v is a struct initialized to
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2544 // 0 using an __initZ SymbolDeclaration from
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2545 // TypeStruct.defaultInit()
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2546 break; // eg default-initialized variable
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2547 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2548 earg = v2.value;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2549 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2550
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2551 v.value = new VarExp(earg.loc, v2);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2552
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2553 /* Don't restore the value of v2 upon function return
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2554 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2555 assert(istate);
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2556 foreach(size_t j, Dsymbol s2; istate.vars)// (size_t j = 0; j < istate.vars.dim; j++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2557 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2558 auto vd = cast(VarDeclaration)s2;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2559 if (vd == v2)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2560 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2561 istate.vars[j] = null;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2562 break;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2563 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2564 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2565 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2566 else
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2567 {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2568 // Value parameters and non-trivial references
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2569 v.value = earg;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2570 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2571 version (LOG) {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2572 printf("interpreted arg[%d] = %s\n", i, earg.toChars());
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2573 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2574 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2575 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2576 // Don't restore the value of 'this' upon function return
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
2577 if (needThis() && thisarg.op == TOKvar && istate) {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2578 VarDeclaration thisvar = (cast(VarExp)thisarg).var.isVarDeclaration();
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2579 foreach (size_t i, Dsymbol s; istate.vars)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2580 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2581 auto v = cast(VarDeclaration)s;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2582 if (v == thisvar)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2583 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2584 istate.vars[i] = null;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2585 break;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2586 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2587 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2588 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2589
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2590 /* Save the values of the local variables used
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2591 */
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
2592 scope valueSaves = new Expressions();
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2593 if (istate && !isNested())
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2594 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2595 //printf("saving local variables...\n");
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2596 valueSaves.setDim(istate.vars.dim);
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2597 foreach (size_t i, Dsymbol s3; istate.vars)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2598 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2599 if (auto v = cast(VarDeclaration)s3)
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2600 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2601 //printf("\tsaving [%d] %s = %s\n", i, v.toChars(), v.value ? v.value.toChars() : "");
84
be2ab491772e Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 79
diff changeset
2602 valueSaves[i] = v.value;
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2603 v.value = null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2604 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2605 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2606 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2607
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2608 Expression e = null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2609 while (1)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2610 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2611 e = fbody.interpret(istatex);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2612 if (e is EXP_CANT_INTERPRET)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2613 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2614 version (LOG) {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2615 printf("function body failed to interpret\n");
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2616 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2617 e = null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2618 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2619
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2620 /* This is how we deal with a recursive statement AST
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2621 * that has arbitrary goto statements in it.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2622 * Bubble up a 'result' which is the target of the goto
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2623 * statement, then go recursively down the AST looking
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2624 * for that statement, then execute starting there.
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2625 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2626 if (e is EXP_GOTO_INTERPRET)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2627 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2628 istatex.start = istatex.gotoTarget; // set starting statement
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2629 istatex.gotoTarget = null;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2630 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2631 else
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2632 break;
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2633 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2634 /* Restore the parameter values
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2635 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2636 for (size_t i = 0; i < dim; i++)
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2637 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2638 auto v = cast(VarDeclaration)parameters[i];
90
39648eb578f6 more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 88
diff changeset
2639 v.value = vsave[i];
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2640 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2641
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2642 if (istate && !isNested())
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2643 {
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2644 /* Restore the variable values
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2645 */
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2646 //printf("restoring local variables...\n");
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2647 foreach (size_t i , Dsymbol s3; istate.vars)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2648 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2649 if (auto v = cast(VarDeclaration)s3)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2650 {
90
39648eb578f6 more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 88
diff changeset
2651 v.value = valueSaves[i];
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2652 //printf("\trestoring [%d] %s = %s\n", i, v.toChars(), v.value ? v.value.toChars() : "");
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2653 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2654 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2655 }
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
2656 return e;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2657 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2658
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2659 override void inlineScan()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2660 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2661 InlineScanState iss;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2662
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2663 version (LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2664 printf("FuncDeclaration.inlineScan('%s')\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2665 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2666 ///memset(&iss, 0, sizeof(iss));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2667 iss.fd = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2668 if (fbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2669 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2670 inlineNest++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2671 fbody = fbody.inlineScan(&iss);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2672 inlineNest--;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2673 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2674 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2675
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2676 int canInline(int hasthis, int hdrscan = 0)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2677 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2678 int cost;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2679
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2680 // #define CANINLINE_LOG 0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2681
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2682 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2683 printf("FuncDeclaration.canInline(hasthis = %d, '%s')\n", hasthis, toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2684 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2685
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2686 if (needThis() && !hasthis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2687 return 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2688
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2689 if (inlineNest || (semanticRun < 3 && !hdrscan))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2690 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2691 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2692 printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2693 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2694 return 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2695 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2696
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2697 switch (inlineStatus)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2698 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2699 case ILS.ILSyes:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2700 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2701 printf("\t1: yes %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2702 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2703 return 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2704
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2705 case ILS.ILSno:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2706 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2707 printf("\t1: no %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2708 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2709 return 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2710
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2711 case ILS.ILSuninitialized:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2712 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2713
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2714 default:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2715 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2716 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2717
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2718 if (type)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2719 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2720 assert(type.ty == Tfunction);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2721 TypeFunction tf = cast(TypeFunction)type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2722 if (tf.varargs == 1) // no variadic parameter lists
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2723 goto Lno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2724
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2725 /* Don't inline a function that returns non-void, but has
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2726 * no return expression.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2727 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2728 if (tf.next && tf.next.ty != Tvoid &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2729 !(hasReturnExp & 1) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2730 !hdrscan)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2731 goto Lno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2732 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2733 else
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2734 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2735 CtorDeclaration ctor = isCtorDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2736 if (ctor && ctor.varargs == 1)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2737 goto Lno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2738 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2739
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2740 if (
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2741 !fbody ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2742 !hdrscan &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2743 (
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2744 /// static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2745 /// isCtorDeclaration() || // cannot because need to convert:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2746 /// // return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2747 /// // to:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2748 /// // return this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2749 /// }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2750 isSynchronized() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2751 isImportedSymbol() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2752 /// version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2753 closureVars.dim || // no nested references to this frame
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2754 /// } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2755 /// nestedFrameRef || // no nested references to this frame
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2756 /// }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2757 (isVirtual() && !isFinal())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2758 ))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2759 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2760 goto Lno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2761 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2762
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2763 /* If any parameters are Tsarray's (which are passed by reference)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2764 * or out parameters (also passed by reference), don't do inlining.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2765 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2766 if (parameters)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2767 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2768 foreach (Dsymbol s3; parameters)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2769 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2770 auto v = cast(VarDeclaration)s3;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2771 if (v.isOut() || v.isRef() || v.type.toBasetype().ty == Tsarray)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2772 goto Lno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2773 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2774 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2775
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2776 InlineCostState ics;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2777 ///memset(&ics, 0, sizeof(ics));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2778 ics.hasthis = hasthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2779 ics.fd = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2780 ics.hdrscan = hdrscan;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2781 cost = fbody.inlineCost(&ics);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2782 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2783 printf("cost = %d\n", cost);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2784 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2785 if (cost >= COST_MAX)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2786 goto Lno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2787
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2788 if (!hdrscan) // Don't scan recursively for header content scan
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2789 inlineScan();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2790
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2791 Lyes:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2792 if (!hdrscan) // Don't modify inlineStatus for header content scan
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2793 inlineStatus = ILS.ILSyes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2794 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2795 printf("\t2: yes %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2796 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2797 return 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2798
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2799 Lno:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2800 if (!hdrscan) // Don't modify inlineStatus for header content scan
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2801 inlineStatus = ILS.ILSno;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2802 version (CANINLINE_LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2803 printf("\t2: no %s\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2804 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2805 return 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2806 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2807
84
be2ab491772e Expressions -> Vector!Expression
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 79
diff changeset
2808 Expression doInline(InlineScanState* iss, Expression ethis, Expressions arguments)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2809 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2810 InlineDoState ids = new InlineDoState();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2811 DeclarationExp de;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2812 Expression e = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2813
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2814 version (LOG) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2815 printf("FuncDeclaration.doInline('%s')\n", toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2816 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2817
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2818 ///memset(&ids, 0, sizeof(ids));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2819 ids.parent = iss.fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2820
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2821 // Set up vthis
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2822 if (ethis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2823 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2824 VarDeclaration vthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2825 ExpInitializer ei;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2826 VarExp ve;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2827
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2828 version (STRUCTTHISREF) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2829 if (ethis.type.ty == Tpointer)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2830 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2831 Type t = ethis.type.nextOf();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2832 ethis = new PtrExp(ethis.loc, ethis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2833 ethis.type = t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2834 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2835 ei = new ExpInitializer(ethis.loc, ethis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2836
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2837 vthis = new VarDeclaration(ethis.loc, ethis.type, Id.This, ei);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2838 if (ethis.type.ty != Tclass)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2839 vthis.storage_class = STCref;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2840 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2841 vthis.storage_class = STCin;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2842 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2843 if (ethis.type.ty != Tclass && ethis.type.ty != Tpointer)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2844 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2845 ethis = ethis.addressOf(null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2846 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2847
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2848 ei = new ExpInitializer(ethis.loc, ethis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2849
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2850 vthis = new VarDeclaration(ethis.loc, ethis.type, Id.This, ei);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2851 vthis.storage_class = STCin;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2852 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2853 vthis.linkage = LINKd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2854 vthis.parent = iss.fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2855
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2856 ve = new VarExp(vthis.loc, vthis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2857 ve.type = vthis.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2858
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2859 ei.exp = new AssignExp(vthis.loc, ve, ethis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2860 ei.exp.type = ve.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2861 version (STRUCTTHISREF) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2862 if (ethis.type.ty != Tclass)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2863 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2864 /* This is a reference initialization, not a simple assignment.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2865 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2866 ei.exp.op = TOKconstruct;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2867 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2868 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2869
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2870 ids.vthis = vthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2871 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2872
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2873 // Set up parameters
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2874 if (ethis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2875 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2876 e = new DeclarationExp(Loc(0), ids.vthis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2877 e.type = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2878 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2879
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2880 if (arguments && arguments.dim)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2881 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2882 assert(parameters.dim == arguments.dim);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2883
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2884 for (int i = 0; i < arguments.dim; i++)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2885 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2886 auto vfrom = cast(VarDeclaration)parameters[i];
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2887 VarDeclaration vto;
90
39648eb578f6 more Expressions work
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 88
diff changeset
2888 Expression arg = arguments[i];
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2889 ExpInitializer ei;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2890 VarExp ve;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2891
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2892 ei = new ExpInitializer(arg.loc, arg);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2893
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2894 vto = new VarDeclaration(vfrom.loc, vfrom.type, vfrom.ident, ei);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2895 vto.storage_class |= vfrom.storage_class & (STCin | STCout | STClazy | STCref);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2896 vto.linkage = vfrom.linkage;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2897 vto.parent = iss.fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2898 //printf("vto = '%s', vto.storage_class = x%x\n", vto.toChars(), vto.storage_class);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2899 //printf("vto.parent = '%s'\n", iss.fd.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2900
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2901 ve = new VarExp(vto.loc, vto);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2902 //ve.type = vto.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2903 ve.type = arg.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2904
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2905 ei.exp = new AssignExp(vto.loc, ve, arg);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2906 ei.exp.type = ve.type;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2907 //ve.type.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2908 //arg.type.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2909 //ei.exp.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2910
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2911 ids.from.push(cast(void*)vfrom);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2912 ids.to.push(cast(void*)vto);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2913
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2914 de = new DeclarationExp(Loc(0), vto);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2915 de.type = Type.tvoid;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2916
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2917 e = Expression.combine(e, de);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2918 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2919 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2920
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2921 inlineNest++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2922 Expression eb = fbody.doInline(ids);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2923 inlineNest--;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2924 //eb.type.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2925 //eb.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2926 //eb.dump(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2927 return Expression.combine(e, eb);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2928 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2929
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2930 override string kind()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2931 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2932 return "function";
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2933 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2934
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
2935 override void toDocBuffer(OutBuffer buf)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2936 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2937 assert(false);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2938 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2939
156
0c8cc2a10f99 + ArrayInitializer.toAssocArrayLiteral()
trass3r
parents: 139
diff changeset
2940 FuncDeclaration isUnique()
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2941 {
158
80f4806ffa13 overloadApply fixes
korDen
parents: 157
diff changeset
2942 Unique unique;
80f4806ffa13 overloadApply fixes
korDen
parents: 157
diff changeset
2943 overloadApply(this, unique);
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2944
158
80f4806ffa13 overloadApply fixes
korDen
parents: 157
diff changeset
2945 return unique.f;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2946 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2947
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2948 /*******************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2949 * Look at all the variables in this function that are referenced
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2950 * by nested functions, and determine if a closure needs to be
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2951 * created for them.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2952 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2953 bool needsClosure()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2954 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2955 /* Need a closure for all the closureVars[] if any of the
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2956 * closureVars[] are accessed by a
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2957 * function that escapes the scope of this function.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2958 * We take the conservative approach and decide that any function that:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2959 * 1) is a virtual function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2960 * 2) has its address taken
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2961 * 3) has a parent that escapes
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2962 *
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2963 * Note that since a non-virtual function can be called by
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2964 * a virtual one, if that non-virtual function accesses a closure
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2965 * var, the closure still has to be taken. Hence, we check for isThis()
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2966 * instead of isVirtual(). (thanks to David Friedman)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2967 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2968
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2969 //printf("FuncDeclaration.needsClosure() %s\n", toChars());
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2970 foreach (Dsymbol s3; closureVars)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
2971 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2972 auto v = cast(VarDeclaration)s3;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2973 assert(v.isVarDeclaration());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2974 //printf("\tv = %s\n", v.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2975
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2976 foreach(FuncDeclaration f; v.nestedrefs)
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
2977 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2978 assert(f != this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2979
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2980 //printf("\t\tf = %s, %d, %p, %d\n", f.toChars(), f.isVirtual(), f.isThis(), f.tookAddressOf);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2981 if (f.isThis() || f.tookAddressOf)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2982 goto Lyes; // assume f escapes this function's scope
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2983
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2984 // Look to see if any parents of f that are below this escape
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2985 for (Dsymbol s = f.parent; s && s !is this; s = s.parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2986 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2987 f = s.isFuncDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2988 if (f && (f.isThis() || f.tookAddressOf)) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2989 goto Lyes;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2990 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2991 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2992 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2993 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2994 return false;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2995
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2996 Lyes:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2997 //printf("\tneeds closure\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2998 return true;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
2999 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3000
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3001 /****************************************************
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3002 * Merge into this function the 'in' contracts of all it overrides.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3003 * 'in's are OR'd together, i.e. only one of them needs to pass.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3004 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3005
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3006 Statement mergeFrequire(Statement sf)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3007 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3008 /* Implementing this is done by having the overriding function call
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3009 * nested functions (the fdrequire functions) nested inside the overridden
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3010 * function. This requires that the stack layout of the calling function's
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3011 * parameters and 'this' pointer be in the same place (as the nested
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3012 * function refers to them).
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3013 * This is easy for the parameters, as they are all on the stack in the same
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3014 * place by definition, since it's an overriding function. The problem is
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3015 * getting the 'this' pointer in the same place, since it is a local variable.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3016 * We did some hacks in the code generator to make this happen:
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3017 * 1. always generate exception handler frame, or at least leave space for it
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3018 * in the frame (Windows 32 SEH only)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3019 * 2. always generate an EBP style frame
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3020 * 3. since 'this' is passed in a register that is subsequently copied into
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3021 * a stack local, allocate that local immediately following the exception
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3022 * handler block, so it is always at the same offset from EBP.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3023 */
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
3024 foreach(FuncDeclaration fdv; foverrides) //(int i = 0; i < foverrides.dim; i++)
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3025 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3026 sf = fdv.mergeFrequire(sf);
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3027 if (fdv.fdrequire)
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3028 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3029 //printf("fdv.frequire: %s\n", fdv.frequire.toChars());
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3030 /* Make the call:
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3031 * try { __require(); }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3032 * catch { frequire; }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3033 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3034 Expression eresult = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3035 Expression e = new CallExp(loc, new VarExp(loc, fdv.fdrequire, 0), eresult);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3036 Statement s2 = new ExpStatement(loc, e);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3037
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3038 if (sf)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3039 {
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3040 Catch c = new Catch(loc, null, null, sf);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3041 Array catches = new Array();
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3042 catches.push(cast(void*)c);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3043 sf = new TryCatchStatement(loc, s2, catches);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3044 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3045 else
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3046 sf = s2;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3047 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3048 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3049 return sf;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3050 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3051
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3052 /****************************************************
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3053 * Merge into this function the 'out' contracts of all it overrides.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3054 * 'out's are AND'd together, i.e. all of them need to pass.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3055 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3056
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3057 Statement mergeFensure(Statement sf)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3058 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3059 /* Same comments as for mergeFrequire(), except that we take care
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3060 * of generating a consistent reference to the 'result' local by
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3061 * explicitly passing 'result' to the nested function as a reference
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3062 * argument.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3063 * This won't work for the 'this' parameter as it would require changing
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3064 * the semantic code for the nested function so that it looks on the parameter
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3065 * list for the 'this' pointer, something that would need an unknown amount
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3066 * of tweaking of various parts of the compiler that I'd rather leave alone.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3067 */
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
3068 foreach (FuncDeclaration fdv; foverrides)
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3069 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3070 sf = fdv.mergeFensure(sf);
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3071 if (fdv.fdensure)
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3072 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3073 //printf("fdv.fensure: %s\n", fdv.fensure.toChars());
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3074 // Make the call: __ensure(result)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3075 Expression eresult = null;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3076 if (outId)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3077 eresult = new IdentifierExp(loc, outId);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3078 Expression e = new CallExp(loc, new VarExp(loc, fdv.fdensure, 0), eresult);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3079 Statement s2 = new ExpStatement(loc, e);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3080
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3081 if (sf)
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3082 {
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3083 sf = new CompoundStatement(fensure.loc, s2, sf);
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3084 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3085 else
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3086 sf = s2;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3087 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3088 }
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3089 return sf;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3090 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3091
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3092 static FuncDeclaration genCfunc(Type treturn, string name)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3093 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3094 return genCfunc(treturn, Lexer.idPool(name));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3095 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3096
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3097 /**********************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3098 * Generate a FuncDeclaration for a runtime library function.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3099 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3100 static FuncDeclaration genCfunc(Type treturn, Identifier id)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3101 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3102 FuncDeclaration fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3103 TypeFunction tf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3104 Dsymbol s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3105
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3106 //printf("genCfunc(name = '%s')\n", id.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3107 //printf("treturn\n\t"); treturn.print();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3108
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3109 // See if already in table
167
50a6d232176c rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents: 158
diff changeset
3110 s = global.st.lookup(id);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3111 if (s)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3112 {
167
50a6d232176c rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents: 158
diff changeset
3113 debug fd = s.isFuncDeclaration();
50a6d232176c rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents: 158
diff changeset
3114 debug assert(fd);
50a6d232176c rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents: 158
diff changeset
3115 debug assert(fd.type.nextOf().equals(treturn));
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3116 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3117 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3118 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3119 tf = new TypeFunction(null, treturn, 0, LINK.LINKc);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3120 fd = new FuncDeclaration(Loc(0), Loc(0), id, STCstatic, tf);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3121 fd.protection = PROT.PROTpublic;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3122 fd.linkage = LINK.LINKc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3123
167
50a6d232176c rewrite GlobalExpressions, moved DsymbolTable to Global, some cleanup
korDen
parents: 158
diff changeset
3124 global.st.insert(fd);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3125 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3126 return fd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3127 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3128
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3129 override Symbol* toSymbol()
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3130 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3131 if (!csym)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3132 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3133 Symbol* s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3134 TYPE* t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3135 string id;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3136
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3137 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3138 id = ident.toChars();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3139 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3140 id = mangle();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3141 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3142 //writef("FuncDeclaration.toSymbol(%s %s)\n", kind(), toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3143 //writef("\tid = '%s'\n", id);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3144 //writef("\ttype = %s\n", type.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3145 s = symbol_calloc(toStringz(id));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3146 slist_add(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3147
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3148 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3149 s.prettyIdent = toStringz(toPrettyChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3150 s.Sclass = SC.SCglobal;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3151 symbol_func(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3152 func_t* f = s.Sfunc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3153 if (isVirtual())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3154 f.Fflags |= F.Fvirtual;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3155 else if (isMember2())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3156 f.Fflags |= F.Fstatic;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3157 f.Fstartline.Slinnum = loc.linnum;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3158 f.Fstartline.Sfilename = cast(char*)toStringz(loc.filename);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3159 if (endloc.linnum)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3160 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3161 f.Fendline.Slinnum = endloc.linnum;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3162 f.Fendline.Sfilename = cast(char*)toStringz(endloc.filename);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3163 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3164 else
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3165 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3166 f.Fendline.Slinnum = loc.linnum;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3167 f.Fendline.Sfilename = cast(char*)toStringz(loc.filename);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3168 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3169 t = type.toCtype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3170 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3171
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3172 mangle_t msave = t.Tmangle;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3173 if (isMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3174 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3175 t.Tty = TYM.TYnfunc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3176 t.Tmangle = mTYman.mTYman_c;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3177 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3178 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3179 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3180 switch (linkage)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3181 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3182 case LINK.LINKwindows:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3183 t.Tmangle = mTYman.mTYman_std;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3184 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3185
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3186 case LINK.LINKpascal:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3187 t.Tty = TYM.TYnpfunc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3188 t.Tmangle = mTYman.mTYman_pas;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3189 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3190
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3191 case LINK.LINKc:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3192 t.Tmangle = mTYman.mTYman_c;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3193 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3194
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3195 case LINK.LINKd:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3196 t.Tmangle = mTYman.mTYman_d;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3197 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3198
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3199 case LINK.LINKcpp:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3200 { t.Tmangle = mTYman.mTYman_cpp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3201 version (TARGET_WINDOS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3202 if (isThis())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3203 t.Tty = TYM.TYmfunc;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3204 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3205 s.Sflags |= SFL.SFLpublic;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3206 Dsymbol parent = toParent();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3207 ClassDeclaration cd = parent.isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3208 if (cd)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3209 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3210 .type* tt = cd.type.toCtype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3211 s.Sscope = tt.Tnext.Ttag;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3212 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3213 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3214 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3215 default:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3216 writef("linkage = %d\n", linkage);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3217 assert(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3218 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3219 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3220 if (msave)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3221 assert(msave == t.Tmangle);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3222 //printf("Tty = %x, mangle = x%x\n", t.Tty, t.Tmangle);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3223 t.Tcount++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3224 s.Stype = t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3225 //s.Sfielddef = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3226
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3227 csym = s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3228 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3229 return csym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3230 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3231
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3232 Symbol* toThunkSymbol(int offset) // thunk version
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3233 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3234 Symbol *sthunk;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3235
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3236 toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3237
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3238 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3239 char *id;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3240 char *n;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3241 type *t;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3242
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3243 n = sym.Sident;
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3244 version (Bug4054) {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
3245 id = cast(char*) GC.malloc(8 + 5 + strlen(n) + 1);
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3246 } else {
63
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
3247 id = cast(char*) alloca(8 + 5 + strlen(n) + 1);
cab4c37afb89 A bunch of implementations
korDen
parents: 22
diff changeset
3248 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3249 sprintf(id, "_thunk%d__%s", offset, n);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3250 s = symbol_calloc(id);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3251 slist_add(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3252 s.Stype = csym.Stype;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3253 s.Stype.Tcount++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3254 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3255 sthunk = symbol_generate(SCstatic, csym.Stype);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3256 sthunk.Sflags |= SFLimplem;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3257 cod3_thunk(sthunk, csym, 0, TYnptr, -offset, -1, 0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3258 return sthunk;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3259 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3260
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3261 override void toObjFile(int multiobj) // compile to .obj file
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3262 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3263 Symbol* s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3264 func_t* f;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3265 Symbol* senter;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3266 Symbol* sexit;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3267
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3268 FuncDeclaration func = this;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3269 ClassDeclaration cd = func.parent.isClassDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3270 int reverse;
89
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3271
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3272 int has_arguments;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3273
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3274 //printf("FuncDeclaration.toObjFile(%p, %s.%s)\n", func, parent.toChars(), func.toChars());
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3275 static if (false)
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3276 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3277 //printf("line = %d\n",func.getWhere() / LINEINC);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3278 EEcontext ee = env.getEEcontext();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3279 if (ee.EEcompile == 2)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3280 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3281 if (ee.EElinnum < (func.getWhere() / LINEINC) ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3282 ee.EElinnum > (func.endwhere / LINEINC)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3283 )
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3284 return; // don't compile this function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3285 ee.EEfunc = func.toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3286 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3287 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3288
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3289 if (multiobj && !isStaticDtorDeclaration() && !isStaticCtorDeclaration())
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3290 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3291 obj_append(this);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3292 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3293 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3294
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3295 if (semanticRun >= 5) // if toObjFile() already run
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3296 return;
177
1475fd394c9e bug fixes
korDen
parents: 176
diff changeset
3297
1475fd394c9e bug fixes
korDen
parents: 176
diff changeset
3298 semanticRun = 5;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3299
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3300 if (!func.fbody)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3301 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3302 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3303 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3304
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3305 if (func.isUnitTestDeclaration() && !global.params.useUnitTests)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3306 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3307
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3308 if (global.params.verbose)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3309 writef("function %s\n",func.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3310
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3311 s = func.toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3312 f = s.Sfunc;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3313
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3314 version (TARGET_WINDOS)
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3315 {
73
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3316 /* This is done so that the 'this' pointer on the stack is the same
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3317 * distance away from the function parameters, so that an overriding
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3318 * function can call the nested fdensure or fdrequire of its overridden function
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3319 * and the stack offsets are the same.
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3320 */
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3321 if (isVirtual() && (fensure || frequire))
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3322 f.Fflags3 |= F3.Ffakeeh;
ef02e2e203c2 Updating to dmd2.033
korDen
parents: 72
diff changeset
3323 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3324
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3325 version (TARGET_OSX) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3326 s.Sclass = SC.SCcomdat;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3327 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3328 s.Sclass = SC.SCglobal;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3329 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3330
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3331 for (Dsymbol p = parent; p; p = p.parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3332 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3333 if (p.isTemplateInstance())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3334 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3335 s.Sclass = SC.SCcomdat;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3336 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3337 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3338 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3339
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3340 if (isNested())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3341 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3342 // if (!(config.flags3 & CFG3pic))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3343 // s.Sclass = SCstatic;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3344 f.Fflags3 |= F3.Fnested;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3345 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3346 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3347 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3348 const(char)* libname = (global.params.symdebug) ? global.params.debuglibname : global.params.defaultlibname;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3349
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3350 // Pull in RTL startup code
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3351 if (func.isMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3352 { objextdef("_main");
22
fd4acc376c45 Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents: 17
diff changeset
3353 version (POSIX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3354 obj_ehsections(); // initialize exception handling sections
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3355 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3356 objextdef("__acrtused_con");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3357 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3358 obj_includelib(libname);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3359 s.Sclass = SC.SCglobal;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3360 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3361 else if (strcmp(s.Sident.ptr, "main".ptr) == 0 && linkage == LINK.LINKc)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3362 s.Sclass = SC.SCglobal;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3363
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3364 else if (func.isWinMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3365 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3366 objextdef("__acrtused");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3367 obj_includelib(libname);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3368 s.Sclass = SC.SCglobal;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3369 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3370
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3371 // Pull in RTL startup code
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3372 else if (func.isDllMain())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3373 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3374 objextdef("__acrtused_dll");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3375 obj_includelib(libname);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3376 s.Sclass = SC.SCglobal;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3377 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3378 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3379
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3380 cstate.CSpsymtab = &f.Flocsym;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3381
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3382 // Find module m for this function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3383 Module m = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3384 for (Dsymbol p = parent; p; p = p.parent)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3385 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3386 m = p.isModule();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3387 if (m)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3388 break;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3389 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3390
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3391 IRState irs = IRState(m, func);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3392 Array deferToObj = new Array(); // write these to OBJ file later
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3393 irs.deferToObj = deferToObj;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3394
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3395 TypeFunction tf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3396 RET retmethod;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3397 Symbol* shidden = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3398 Symbol* sthis = null;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3399 tym_t tyf;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3400
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3401 tyf = tybasic(s.Stype.Tty);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3402 //printf("linkage = %d, tyf = x%x\n", linkage, tyf);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3403 reverse = tyrevfunc(s.Stype.Tty);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3404
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3405 assert(func.type.ty == TY.Tfunction);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3406 tf = cast(TypeFunction)(func.type);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3407 has_arguments = (tf.linkage == LINK.LINKd) && (tf.varargs == 1);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3408 retmethod = tf.retStyle();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3409 if (retmethod == RET.RETstack)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3410 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3411 // If function returns a struct, put a pointer to that
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3412 // as the first argument
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3413 .type* thidden = tf.next.pointerTo().toCtype();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3414 char hiddenparam[5+4+1];
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3415 sprintf(hiddenparam.ptr, "__HID%d".ptr, ++global.hiddenparami);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3416 shidden = symbol_name(hiddenparam.ptr, SC.SCparameter, thidden);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3417 shidden.Sflags |= SFL.SFLtrue | SFL.SFLfree;
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3418
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3419 version (DMDV1) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3420 bool nestedref = func.nrvo_can && func.nrvo_var && func.nrvo_var.nestedref;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3421 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3422 bool nestedref = func.nrvo_can && func.nrvo_var && (func.nrvo_var.nestedrefs.dim != 0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3423 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3424 if (nestedref) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3425 type_setcv(&shidden.Stype, shidden.Stype.Tty | mTY.mTYvolatile);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3426 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3427
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3428 irs.shidden = shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3429 this.shidden = shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3430 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3431
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3432 if (vthis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3433 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3434 assert(!vthis.csym);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3435 sthis = vthis.toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3436 irs.sthis = sthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3437 if (!(f.Fflags3 & F3.Fnested))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3438 f.Fflags3 |= F3.Fmember;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3439 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3440
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3441 Symbol** params;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3442 uint pi;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3443
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3444 // Estimate number of parameters, pi
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3445 pi = (v_arguments !is null);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3446 if (parameters)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3447 pi += parameters.dim;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3448
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3449 // Allow extra 2 for sthis and shidden
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3450 version (Bug4054)
14
2cc604139636 Implemented Linux support for ddmd. Some parts are a bit hacky to just "get it working", that said, druntime and phobos compile, and unittests pass.
Robert Clipsham <robert@octarineparrot.com>
parents: 0
diff changeset
3451 params = cast(Symbol**)GC.malloc((pi + 2) * (Symbol*).sizeof);
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3452 else
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3453 params = cast(Symbol**)alloca((pi + 2) * (Symbol*).sizeof);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3454
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3455 // Get the actual number of parameters, pi, and fill in the params[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3456 pi = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3457 if (v_arguments)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3458 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3459 params[pi] = v_arguments.toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3460 pi += 1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3461 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3462 if (parameters)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3463 {
89
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3464 size_t i = 0;
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3465 for ( ; i < parameters.dim; ++i)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3466 {
89
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3467 auto v = cast(VarDeclaration)parameters[i];
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3468
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3469 if (v.csym)
98
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3470 {
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3471 error("compiler error, parameter '%s', bugzilla 2962?", v.toChars());
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3472 assert(false);
5c859d5fbe27 and more
Trass3r
parents: 93
diff changeset
3473 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3474 params[pi + i] = v.toSymbol();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3475 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3476 pi += i;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3477 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3478
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3479 if (reverse)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3480 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3481 // Reverse params[] entries
89
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3482 for (size_t i = 0; i < pi/2; i++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3483 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3484 Symbol* sptmp = params[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3485 params[i] = params[pi - 1 - i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3486 params[pi - 1 - i] = sptmp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3487 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3488 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3489
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3490 if (shidden)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3491 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3492 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3493 // shidden becomes last parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3494 params[pi] = shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3495 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3496 // shidden becomes first parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3497 memmove(params + 1, params, pi * (*params).sizeof);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3498 params[0] = shidden;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3499 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3500 pi++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3501 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3502
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3503
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3504 if (sthis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3505 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3506 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3507 // sthis becomes last parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3508 params[pi] = sthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3509 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3510 // sthis becomes first parameter
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3511 memmove(params + 1, params, pi * (*params).sizeof);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3512 params[0] = sthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3513 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3514 pi++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3515 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3516
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3517 if ((global.params.isLinux || global.params.isOSX || global.params.isFreeBSD || global.params.isSolaris) &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3518 linkage != LINK.LINKd && shidden && sthis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3519 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3520 /* swap shidden and sthis
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3521 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3522 Symbol* sp = params[0];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3523 params[0] = params[1];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3524 params[1] = sp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3525 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3526
89
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3527 for (size_t i = 0; i < pi; i++)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3528 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3529 Symbol *sp = params[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3530 sp.Sclass = SC.SCparameter;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3531 sp.Sflags &= ~SFL.SFLspill;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3532 sp.Sfl = FL.FLpara;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3533 symbol_add(sp);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3534 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3535
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3536 // First parameter goes in register
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3537 if (pi)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3538 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3539 Symbol* sp = params[0];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3540 if ((tyf == TYM.TYjfunc || tyf == TYM.TYmfunc) && type_jparam(sp.Stype))
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3541 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3542 sp.Sclass = SC.SCfastpar;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3543 sp.Spreg = (tyf == TYM.TYjfunc) ? REG.AX : REG.CX;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3544 sp.Sfl = FL.FLauto;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3545 //printf("'%s' is SCfastpar\n",sp.Sident);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3546 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3547 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3548
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3549 if (func.fbody)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3550 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3551 block* b;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3552 Blockx bx;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3553 Statement sbody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3554
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3555 global.localgot = null;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3556
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3557 sbody = func.fbody;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3558 ///memset(&bx, 0, (bx).sizeof);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3559 bx.startblock = block_calloc();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3560 bx.curblock = bx.startblock;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3561 bx.funcsym = s;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3562 bx.scope_index = -1;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3563 bx.classdec = cd;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3564 bx.member = func;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3565 bx.module_ = getModule();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3566 irs.blx = &bx;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3567
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3568 buildClosure(&irs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3569
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3570 static if (false) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3571 if (func.isSynchronized())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3572 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3573 if (cd)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3574 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3575 elem *esync;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3576 if (func.isStatic())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3577 { // monitor is in ClassInfo
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3578 esync = el_ptr(cd.toSymbol());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3579 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3580 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3581 { // 'this' is the monitor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3582 esync = el_var(sthis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3583 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3584
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3585 if (func.isStatic() || sbody.usesEH() ||
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3586 !(config.flags2 & CFG2.CFG2seh))
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3587 { // BUG: what if frequire or fensure uses EH?
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3588
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3589 sbody = new SynchronizedStatement(func.loc, esync, sbody);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3590 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3591 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3592 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3593 version (TARGET_WINDOS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3594 if (config.flags2 & CFG2.CFG2seh)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3595 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3596 /* The "jmonitor" uses an optimized exception handling frame
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3597 * which is a little shorter than the more general EH frame.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3598 * It isn't strictly necessary.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3599 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3600 s.Sfunc.Fflags3 |= Fjmonitor;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3601 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3602 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3603 el_free(esync);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3604 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3605 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3606 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3607 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3608 error("synchronized function %s must be a member of a class", func.toChars());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3609 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3610 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3611 } else version (TARGET_WINDOS) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3612 if (func.isSynchronized() && cd && config.flags2 & CFG2.CFG2seh &&
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3613 !func.isStatic() && !sbody.usesEH())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3614 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3615 /* The "jmonitor" hack uses an optimized exception handling frame
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3616 * which is a little shorter than the more general EH frame.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3617 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3618 s.Sfunc.Fflags3 |= F3.Fjmonitor;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3619 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3620 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3621
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3622 sbody.toIR(&irs);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3623 bx.curblock.BC = BC.BCret;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3624
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3625 f.Fstartblock = bx.startblock;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3626 // einit = el_combine(einit,bx.init);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3627
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3628 if (isCtorDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3629 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3630 assert(sthis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3631 for (b = f.Fstartblock; b; b = b.Bnext)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3632 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3633 if (b.BC == BC.BCret)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3634 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3635 b.BC = BC.BCretexp;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3636 b.Belem = el_combine(b.Belem, el_var(sthis));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3637 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3638 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3639 }
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3640 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3641
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3642 // If static constructor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3643 if (isStaticConstructor())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3644 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3645 elem* e = el_una(OPER.OPucall, TYM.TYvoid, el_var(s));
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3646 global.ector = el_combine(global.ector, e);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3647 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3648
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3649 // If static destructor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3650 if (isStaticDestructor())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3651 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3652 elem* e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3653
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3654 version (STATICCTOR) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3655 e = el_bin(OPER.OPcall, TYM.TYvoid, el_var(rtlsym[RTLSYM.RTLSYM_FATEXIT]), el_ptr(s));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3656 ector = el_combine(ector, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3657 dtorcount++;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3658 } else {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3659 StaticDtorDeclaration f2 = isStaticDtorDeclaration();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3660 assert(f2);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3661 if (f2.vgate)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3662 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3663 /* Increment destructor's vgate at construction time
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3664 */
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3665 global.ectorgates.push(cast(void*)f2);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3666 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3667
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3668 e = el_una(OPER.OPucall, TYM.TYvoid, el_var(s));
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3669 global.edtor = el_combine(e, global.edtor);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3670 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3671 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3672
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3673 // If unit test
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3674 if (isUnitTestDeclaration())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3675 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3676 elem* e = el_una(OPER.OPucall, TYM.TYvoid, el_var(s));
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3677 global.etest = el_combine(global.etest, e);
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3678 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3679
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3680 if (global.errors)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3681 return;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3682
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3683 writefunc(s);
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3684
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3685 if (isExport()) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3686 obj_export(s, Poffset);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3687 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3688
89
37b95c347975 Fixed an obscure bug with i variable being reused
korDen
parents: 88
diff changeset
3689 for (size_t i = 0; i < irs.deferToObj.dim; i++)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3690 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3691 Dsymbol ss = cast(Dsymbol)irs.deferToObj.data[i];
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3692 ss.toObjFile(0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3693 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3694
22
fd4acc376c45 Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents: 17
diff changeset
3695 version (POSIX) { ///TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3696 // A hack to get a pointer to this function put in the .dtors segment
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3697 if (ident && ident.toChars() == "_STD") {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3698 obj_staticdtor(s);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3699 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3700 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3701 version (DMDV2) {
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3702 if (irs.startaddress)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3703 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3704 writef("Setting start address\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3705 obj_startaddress(irs.startaddress);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3706 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3707 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3708 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3709
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3710 override int cvMember(ubyte* p)
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3711 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3712 assert(false);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3713 }
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3714
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3715 /*************************************
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3716 * Closures are implemented by taking the local variables that
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3717 * need to survive the scope of the function, and copying them
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3718 * into a gc allocated chuck of memory. That chunk, called the
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3719 * closure here, is inserted into the linked list of stack
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3720 * frames instead of the usual stack frame.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3721 *
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3722 * buildClosure() inserts code just after the function prolog
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3723 * is complete. It allocates memory for the closure, allocates
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3724 * a local variable (sclosure) to point to it, inserts into it
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3725 * the link to the enclosing frame, and copies into it the parameters
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3726 * that are referred to in nested functions.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3727 * In VarExp.toElem and SymOffExp.toElem, when referring to a
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3728 * variable that is in a closure, takes the offset from sclosure rather
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3729 * than from the frame pointer.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3730 *
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3731 * getEthis() and NewExp.toElem need to use sclosure, if set, rather
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3732 * than the current frame pointer.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3733 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3734 void buildClosure(IRState* irs)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3735 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3736 if (needsClosure())
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3737 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3738 // Generate closure on the heap
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3739 // BUG: doesn't capture variadic arguments passed to this function
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3740
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3741 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3742 /* BUG: doesn't handle destructors for the local variables.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3743 * The way to do it is to make the closure variables the fields
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3744 * of a class object:
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3745 * class Closure
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3746 * { vtbl[]
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3747 * monitor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3748 * ptr to destructor
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3749 * sthis
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3750 * ... closure variables ...
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3751 * ~this() { call destructor }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3752 * }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3753 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3754 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3755 //printf("FuncDeclaration.buildClosure()\n");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3756 Symbol* sclosure;
176
fa9a71a9f5a8 Moved all the mutable globals to Global
korDen
parents: 175
diff changeset
3757 sclosure = symbol_name("__closptr".ptr, SC.SCauto, global.tvoidptr.toCtype());
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3758 sclosure.Sflags |= SFL.SFLtrue | SFL.SFLfree;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3759 symbol_add(sclosure);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3760 irs.sclosure = sclosure;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3761
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3762 uint offset = PTRSIZE; // leave room for previous sthis
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
3763 foreach (Dsymbol s3; closureVars)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3764 {
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
3765 auto v = cast(VarDeclaration)s3;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3766 assert(v.isVarDeclaration());
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3767
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3768 version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3769 if (v.needsAutoDtor())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3770 v.error("has scoped destruction, cannot build closure");
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3771 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3772 /* Align and allocate space for v in the closure
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3773 * just like AggregateDeclaration.addField() does.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3774 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3775 uint memsize;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3776 uint memalignsize;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3777 uint xalign;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3778 /// version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3779 if (v.storage_class & STC.STClazy)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3780 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3781 /* Lazy variables are really delegates,
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3782 * so give same answers that TypeDelegate would
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3783 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3784 memsize = PTRSIZE * 2;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3785 memalignsize = memsize;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3786 xalign = global.structalign;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3787 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3788 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3789 /// }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3790 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3791 memsize = cast(uint)v.type.size();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3792 memalignsize = v.type.alignsize();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3793 xalign = v.type.memalign(global.structalign);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3794 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3795 AggregateDeclaration.alignmember(xalign, memalignsize, &offset);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3796 v.offset = offset;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3797 offset += memsize;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3798
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3799 /* Can't do nrvo if the variable is put in a closure, since
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3800 * what the shidden points to may no longer exist.
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3801 */
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3802 if (nrvo_can && nrvo_var == v)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3803 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3804 nrvo_can = 0;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3805 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3806 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3807 // offset is now the size of the closure
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3808
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3809 // Allocate memory for the closure
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3810 elem* e;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3811 e = el_long(TYM.TYint, offset);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3812 e = el_bin(OPER.OPcall, TYM.TYnptr, el_var(rtlsym[RTLSYM.RTLSYM_ALLOCMEMORY]), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3813
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3814 // Assign block of memory to sclosure
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3815 // sclosure = allocmemory(sz);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3816 e = el_bin(OPER.OPeq, TYM.TYvoid, el_var(sclosure), e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3817
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3818 // Set the first element to sthis
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3819 // *(sclosure + 0) = sthis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3820 elem* ethis;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3821 if (irs.sthis)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3822 ethis = el_var(irs.sthis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3823 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3824 ethis = el_long(TYM.TYnptr, 0);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3825 elem *ex = el_una(OPER.OPind, TYM.TYnptr, el_var(sclosure));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3826 ex = el_bin(OPER.OPeq, TYM.TYnptr, ex, ethis);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3827 e = el_combine(e, ex);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3828
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3829 // Copy function parameters into closure
77
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
3830 foreach (Dsymbol s3; closureVars)
ad4792a1cfd6 more D-ification container accessing
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 74
diff changeset
3831 { auto v = cast(VarDeclaration)s3;
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3832
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3833 if (!v.isParameter())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3834 continue;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3835 TYM tym = v.type.totym();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3836 if (v.type.toBasetype().ty == TY.Tsarray || v.isOut() || v.isRef())
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3837 tym = TYM.TYnptr; // reference parameters are just pointers
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3838 /// version (DMDV2) {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3839 else if (v.storage_class & STC.STClazy)
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3840 tym = TYM.TYdelegate;
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3841 /// }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3842 ex = el_bin(OPER.OPadd, TYM.TYnptr, el_var(sclosure), el_long(TYM.TYint, v.offset));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3843 ex = el_una(OPER.OPind, tym, ex);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3844 if (ex.Ety == TYM.TYstruct)
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3845 {
0
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3846 ex.Enumbytes = cast(uint)v.type.size();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3847 ex = el_bin(OPER.OPstreq, tym, ex, el_var(v.toSymbol()));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3848 ex.Enumbytes = cast(uint)v.type.size();
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3849 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3850 else
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3851 {
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3852 ex = el_bin(OPER.OPeq, tym, ex, el_var(v.toSymbol()));
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3853 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3854
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3855 e = el_combine(e, ex);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3856 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3857
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3858 block_appendexp(irs.blx.curblock, e);
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3859 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3860 }
10317f0c89a5 Initial commit
korDen
parents:
diff changeset
3861
135
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3862 /*********************************************
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3863 * Return the function's parameter list, and whether
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3864 * it is variadic or not.
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3865 */
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3866
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3867 Parameters getParameters(int *pvarargs)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3868 {
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3869 Parameters fparameters;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3870 int fvarargs;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3871
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3872 if (type)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3873 {
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3874 assert(type.ty == Tfunction);
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3875 auto fdtype = cast(TypeFunction)type;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3876 fparameters = fdtype.parameters;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3877 fvarargs = fdtype.varargs;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3878 }
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3879 else // Constructors don't have type's
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3880 {
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3881 CtorDeclaration fctor = isCtorDeclaration();
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3882 assert(fctor);
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3883 fparameters = fctor.arguments;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3884 fvarargs = fctor.varargs;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3885 }
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3886 if (pvarargs)
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3887 *pvarargs = fvarargs;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3888 return fparameters;
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3889 }
af1bebfd96a4 dmd 2.038
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 131
diff changeset
3890
72
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3891 override FuncDeclaration isFuncDeclaration() { return this; }
2e2a5c3f943a reduced warnings by adding override to the methods
Trass3r
parents: 68
diff changeset
3892 }
74
7e0d548de9e6 Switch Arrays of Dsymbols to the new templated Vector type
Eldar Insafutdinov <e.insafutdinov@gmail.com>
parents: 73
diff changeset
3893
174
af724d3510d7 lot os toCBuffer methods implemented
korDen
parents: 167
diff changeset
3894 alias Vector!FuncDeclaration FuncDeclarations;