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