annotate dmd/FuncDeclaration.d @ 179:cd48cb899aee

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