Mercurial > projects > ldc
comparison gen/toir.c @ 67:f918f3e2e99e trunk
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
Some cleanups in VarExp::toElem.
author | lindquist |
---|---|
date | Sun, 28 Oct 2007 02:46:06 +0200 |
parents | 0c5f410d973c |
children | c4b3f5d2cd9b |
comparison
equal
deleted
inserted
replaced
66:0c5f410d973c | 67:f918f3e2e99e |
---|---|
111 assert(var); | 111 assert(var); |
112 if (VarDeclaration* vd = var->isVarDeclaration()) | 112 if (VarDeclaration* vd = var->isVarDeclaration()) |
113 { | 113 { |
114 Logger::println("VarDeclaration %s", vd->toChars()); | 114 Logger::println("VarDeclaration %s", vd->toChars()); |
115 | 115 |
116 if (vd->nestedref) { | |
117 Logger::println("has nested ref"); | |
118 } | |
119 | |
120 // _arguments | 116 // _arguments |
121 if (vd->ident == Id::_arguments) | 117 if (vd->ident == Id::_arguments) |
122 { | 118 { |
123 vd->llvmValue = p->func().decl->llvmArguments; | 119 vd->llvmValue = p->func().decl->llvmArguments; |
124 assert(vd->llvmValue); | 120 assert(vd->llvmValue); |
125 e->mem = vd->llvmValue; | 121 e->mem = vd->llvmValue; |
126 e->type = elem::VAR; | 122 e->type = elem::VAR; |
127 return e; | |
128 } | 123 } |
129 // _argptr | 124 // _argptr |
130 else if (vd->ident == Id::_argptr) | 125 else if (vd->ident == Id::_argptr) |
131 { | 126 { |
132 vd->llvmValue = p->func().decl->llvmArgPtr; | 127 vd->llvmValue = p->func().decl->llvmArgPtr; |
133 assert(vd->llvmValue); | 128 assert(vd->llvmValue); |
134 e->mem = vd->llvmValue; | 129 e->mem = vd->llvmValue; |
135 e->type = elem::VAR; | 130 e->type = elem::VAR; |
136 return e; | 131 } |
137 } | 132 // _dollar |
138 | 133 else if (vd->ident == Id::dollar) |
139 // needed to take care of forward references of global variables | 134 { |
140 if (!vd->llvmTouched && vd->isDataseg()) | 135 assert(!p->arrays.empty()); |
141 vd->toObjFile(); | 136 llvm::Value* tmp = LLVM_DtoGEPi(p->arrays.back(),0,0,"tmp",p->scopebb()); |
142 | 137 e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
143 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 138 e->type = elem::VAL; |
139 } | |
140 // typeinfo | |
141 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | |
144 { | 142 { |
145 Logger::println("TypeInfoDeclaration"); | 143 Logger::println("TypeInfoDeclaration"); |
146 } | 144 tid->toObjFile(); |
147 | 145 assert(tid->llvmValue); |
148 // this must be a dollar expression or some other magic value | 146 const llvm::Type* vartype = LLVM_DtoType(type); |
149 // or it could be a forward declaration of a global variable | 147 if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) |
150 if (!vd->llvmValue) | 148 e->mem = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); |
151 { | 149 else |
152 assert(!vd->nestedref); | 150 e->mem = tid->llvmValue; |
153 Logger::println("special - no llvmValue"); | 151 e->type = elem::VAR; |
154 // dollar | 152 } |
155 if (!p->arrays.empty()) | 153 // nested variable |
156 { | 154 else if (vd->nestedref) { |
157 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 155 e->mem = LLVM_DtoNestedVariable(vd); |
158 //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); | 156 e->type = elem::VAR; |
159 llvm::Value* tmp = LLVM_DtoGEP(p->arrays.back(),zero,zero,"tmp",p->scopebb()); | 157 e->vardecl = vd; |
160 e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 158 } |
161 e->type = elem::VAL; | |
162 } | |
163 // typeinfo | |
164 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | |
165 { | |
166 tid->toObjFile(); | |
167 assert(tid->llvmValue); | |
168 e->val = tid->llvmValue; | |
169 e->type = elem::VAR; | |
170 } | |
171 // global forward ref | |
172 else { | |
173 Logger::println("unsupported magic: %s\n", vd->toChars()); | |
174 assert(0 && "only magic supported is $, _arguments, _argptr"); | |
175 } | |
176 return e; | |
177 } | |
178 | |
179 // function parameter | 159 // function parameter |
180 if (vd->storage_class & STCparameter) { | 160 else if (vd->isParameter()) { |
181 assert(!vd->nestedref); | |
182 Logger::println("function param"); | 161 Logger::println("function param"); |
183 if (vd->storage_class & (STCref | STCout)) { | 162 assert(vd->llvmValue); |
163 if (vd->isRef() || vd->isOut()) { | |
184 e->mem = vd->llvmValue; | 164 e->mem = vd->llvmValue; |
185 e->type = elem::VAR; | 165 e->type = elem::VAR; |
186 } | 166 } |
187 else { | 167 else { |
188 if (LLVM_DtoIsPassedByRef(vd->type)) { | 168 if (LLVM_DtoIsPassedByRef(vd->type)) { |
203 assert(0); | 183 assert(0); |
204 } | 184 } |
205 } | 185 } |
206 } | 186 } |
207 else { | 187 else { |
208 // nested variable | 188 // take care of forward references of global variables |
209 if (vd->nestedref) { | 189 if (!vd->llvmTouched && vd->isDataseg()) |
210 e->mem = LLVM_DtoNestedVariable(vd); | 190 vd->toObjFile(); |
211 } | 191 assert(vd->llvmValue); |
212 // normal local variable | 192 e->mem = vd->llvmValue; |
213 else { | |
214 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) { | |
215 Logger::println("typeinfo varexp"); | |
216 const llvm::Type* vartype = LLVM_DtoType(type); | |
217 if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) { | |
218 e->mem = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp"); | |
219 } | |
220 else { | |
221 e->mem = tid->llvmValue; | |
222 } | |
223 Logger::cout() << "got:" << '\n' << *tid->llvmValue << "returned:" << '\n' << *e->mem << '\n'; | |
224 } | |
225 else { | |
226 e->mem = vd->llvmValue; | |
227 } | |
228 } | |
229 e->vardecl = vd; | 193 e->vardecl = vd; |
230 e->type = elem::VAR; | 194 e->type = elem::VAR; |
231 } | 195 } |
196 | |
197 assert(e->mem || e->val); | |
232 } | 198 } |
233 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | 199 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) |
234 { | 200 { |
235 Logger::println("FuncDeclaration"); | 201 Logger::println("FuncDeclaration"); |
236 if (fdecl->llvmInternal != LLVMva_arg && fdecl->llvmValue == 0) | 202 if (fdecl->llvmInternal != LLVMva_arg && fdecl->llvmValue == 0) |
237 fdecl->toObjFile(); | 203 fdecl->toObjFile(); |
238 e->val = fdecl->llvmValue; | 204 e->val = fdecl->llvmValue; |
239 e->type = elem::FUNC; | 205 e->type = elem::FUNC; |
240 e->funcdecl = fdecl; | 206 e->funcdecl = fdecl; |
241 return e; | |
242 } | 207 } |
243 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | 208 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) |
244 { | 209 { |
245 // this seems to be the static initialiser for structs | 210 // this seems to be the static initialiser for structs |
246 Type* sdecltype = LLVM_DtoDType(sdecl->type); | 211 Type* sdecltype = LLVM_DtoDType(sdecl->type); |
254 else | 219 else |
255 { | 220 { |
256 assert(0 && "Unimplemented VarExp type"); | 221 assert(0 && "Unimplemented VarExp type"); |
257 } | 222 } |
258 | 223 |
259 assert(e->mem || e->val); | |
260 return e; | 224 return e; |
261 } | 225 } |
262 | 226 |
263 ////////////////////////////////////////////////////////////////////////////////////////// | 227 ////////////////////////////////////////////////////////////////////////////////////////// |
264 | 228 |
1258 int li = fn->funcdecl->llvmInternal; | 1222 int li = fn->funcdecl->llvmInternal; |
1259 if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) { | 1223 if (li != LLVMintrinsic && li != LLVMva_start && li != LLVMva_intrinsic) { |
1260 call->setCallingConv(LLVM_DtoCallingConv(dlink)); | 1224 call->setCallingConv(LLVM_DtoCallingConv(dlink)); |
1261 } | 1225 } |
1262 } | 1226 } |
1263 else if (delegateCall) | 1227 else if (delegateCall) { |
1264 call->setCallingConv(LLVM_DtoCallingConv(dlink)); | 1228 call->setCallingConv(LLVM_DtoCallingConv(dlink)); |
1265 else if (fn->callconv != (unsigned)-1) | 1229 } |
1230 else if (fn->callconv != (unsigned)-1) { | |
1266 call->setCallingConv(fn->callconv); | 1231 call->setCallingConv(fn->callconv); |
1232 } | |
1267 | 1233 |
1268 delete fn; | 1234 delete fn; |
1269 return e; | 1235 return e; |
1270 } | 1236 } |
1271 | 1237 |