comparison gen/CodeGen.d @ 173:50b98a06a200

Start of support for virtual functions
author Anders Halager <halager@gmail.com>
date Thu, 24 Jul 2008 20:40:04 +0200
parents f0385c044065
children 20ff3c31f600
comparison
equal deleted inserted replaced
172:01c2c49775ef 173:50b98a06a200
220 GlobalVariable g = m.addGlobal(t, id.get); 220 GlobalVariable g = m.addGlobal(t, id.get);
221 g.initializer = ConstantInt.GetS(t, 0); 221 g.initializer = ConstantInt.GetS(t, 0);
222 table[varDecl.identifier.get] = g; 222 table[varDecl.identifier.get] = g;
223 break; 223 break;
224 224
225 case DeclType.ClassDecl:
226 auto cdecl = cast(ClassDecl)decl;
227 SmallArray!(Constant) functions;
228 foreach (d; cdecl.decls)
229 {
230 auto func = cast(FuncDecl)d;
231 if (func is null)
232 continue;
233 genRootDecl(func);
234 auto llvm_f = m.getNamedFunction(symbolName(func));
235 functions ~= Constant.GetBitCast(llvm_f, BytePtr);
236 }
237 auto class_vtbl = ConstantArray.Get(BytePtr, functions.unsafe());
238 auto gv = m.addGlobal(class_vtbl, cdecl.identifier.get ~ "_vtable");
239 gv.linkage = Linkage.Weak;
240 gv.globalConstant = true;
241 break;
242
225 default: 243 default:
226 break; 244 break;
227 } 245 }
228 } 246 }
229 247
246 RValue src = genExpression(varDecl.init); 264 RValue src = genExpression(varDecl.init);
247 storeThroughLValue(dst, src, id.type); 265 storeThroughLValue(dst, src, id.type);
248 } 266 }
249 break; 267 break;
250 268
251 case DeclType.FuncDecl: 269 case DeclType.FuncDecl,
270 DeclType.StructDecl,
271 DeclType.ClassDecl:
252 genRootDecl(decl); 272 genRootDecl(decl);
253 break; 273 break;
254 274
255 default: 275 default:
256 break; 276 break;
343 DType type = callExp.exp.type; 363 DType type = callExp.exp.type;
344 assert (type.isFunction(), "Can only call functions"); 364 assert (type.isFunction(), "Can only call functions");
345 scope args = new Value[callExp.args.length]; 365 scope args = new Value[callExp.args.length];
346 foreach (i, arg; callExp.args) 366 foreach (i, arg; callExp.args)
347 args[i] = genExpression(arg).value; 367 args[i] = genExpression(arg).value;
348 llvm(type); 368 DFunction ftype = type.asFunction();
349 Function f = null; 369 Type llvm_ftype = llvm(ftype);
370 Value f = null;
350 if (callExp.callSym is null) 371 if (callExp.callSym is null)
351 { 372 {
352 // Do a virtual function call 373 // Do a virtual function call
353 f = m.getNamedFunction(symbolName(callExp.exp)); 374 f = genLValue(callExp.exp).getAddress();
375 f = b.buildLoad(f, "func_pointer");
376 f = b.buildBitCast(
377 f,
378 PointerType.Get(llvm_ftype),
379 ftype.name);
354 } 380 }
355 else 381 else
356 { 382 {
357 auto sym = callExp.callSym; 383 auto sym = callExp.callSym;
358 f = m.getNamedFunction(sym.getMangledFQN()); 384 f = m.getNamedFunction(sym.getMangledFQN());
359 } 385 }
360 DFunction f_type = type.asFunction(); 386 bool isVoid = ftype.returnType is DType.Void;
361 bool isVoid = f_type.returnType is DType.Void;
362 auto r = b.buildCall(f, args, isVoid? "" : "call"); 387 auto r = b.buildCall(f, args, isVoid? "" : "call");
363 return RValue(r); 388 return RValue(r);
364 case ExpType.CastExp: 389 case ExpType.CastExp:
365 auto castExp = cast(CastExp)exp; 390 auto castExp = cast(CastExp)exp;
366 exp = castExp.exp; 391 exp = castExp.exp;
685 case ExpType.Identifier: 710 case ExpType.Identifier:
686 auto id = cast(Identifier)mem.target; 711 auto id = cast(Identifier)mem.target;
687 auto child = mem.child; 712 auto child = mem.child;
688 Value v = table.find(id.get); 713 Value v = table.find(id.get);
689 DType t = id.type; 714 DType t = id.type;
690 auto st = t.asStruct; 715 if (auto st = t.asStruct)
691 716 {
692 int i = st.indexOf(child.get); 717 int i = st.indexOf(child.get);
693 718 if (i == -1)
694 Value[2] vals; 719 {
695 vals[0] = ZeroIndex; 720 auto fname = mem.getSymbol.getMangledFQN();
696 vals[1] = ConstantInt.GetU(IntegerType.Int32, i); 721 auto f = m.getNamedFunction(fname);
697 722 return LValue(f);
698 Value val = b.buildGEP(v, vals, id.get~"."~child.get); 723 }
699 return LValue(val); 724
725 Value[2] vals;
726 vals[0] = ZeroIndex;
727 vals[1] = ConstantInt.GetU(IntegerType.Int32, i);
728
729 Value val = b.buildGEP(v, vals, id.get~"."~child.get);
730 return LValue(val);
731 }
732 else if (auto ct = t.asClass)
733 {
734 int i = ct.indexOf(child.get);
735 Value[2] vals;
736 vals[0] = ZeroIndex;
737 // A normal member
738 if (i != -1)
739 {
740 vals[1] = ConstantInt.GetU(IntegerType.Int32, i);
741 Value val = b.buildGEP(v, vals, id.get~"."~child.get);
742 return LValue(val);
743 }
744 // A method
745 else
746 {
747 vals[1] = ZeroIndex;
748 //vals[1] = ConstantInt.GetU(IntegerType.Int32, 1);
749 auto vtbl_name = ct.name ~ "_vtable";
750 auto vtbl = m.getNamedGlobal(vtbl_name);
751 v = vtbl;
752 }
753
754 Value val = b.buildGEP(v, vals, id.get~"."~child.get);
755 return LValue(val);
756 }
757 else
758 assert(0, "Can only access members in classes "
759 "and structs");
700 760
701 case ExpType.MemberReference: 761 case ExpType.MemberReference:
702 auto addr = genLValue(mem.target).getAddress(); 762 auto addr = genLValue(mem.target).getAddress();
703 auto child = mem.child; 763 auto child = mem.child;
704 DStruct t = mem.target.type.asStruct(); 764 DStruct t = mem.target.type.asStruct();