Mercurial > projects > ldc
comparison gen/toobj.c @ 82:d8dd47ef3973 trunk
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
Initial support for debug information. Very limited, but MUCH better than nothing :)
author | lindquist |
---|---|
date | Fri, 02 Nov 2007 01:17:26 +0100 |
parents | 3587401b6eeb |
children | 169711a7126e |
comparison
equal
deleted
inserted
replaced
81:3587401b6eeb | 82:d8dd47ef3973 |
---|---|
34 #include "gen/irstate.h" | 34 #include "gen/irstate.h" |
35 #include "gen/elem.h" | 35 #include "gen/elem.h" |
36 #include "gen/logger.h" | 36 #include "gen/logger.h" |
37 #include "gen/tollvm.h" | 37 #include "gen/tollvm.h" |
38 #include "gen/arrays.h" | 38 #include "gen/arrays.h" |
39 #include "gen/todebug.h" | |
39 | 40 |
40 ////////////////////////////////////////////////////////////////////////////////////////// | 41 ////////////////////////////////////////////////////////////////////////////////////////// |
41 | 42 |
42 void | 43 void |
43 Module::genobjfile() | 44 Module::genobjfile() |
72 assert(targetEntry && "Failed to find a static target for module"); | 73 assert(targetEntry && "Failed to find a static target for module"); |
73 std::auto_ptr<llvm::TargetMachine> targetPtr(targetEntry->CtorFn(*ir.module, "")); // TODO: replace "" with features | 74 std::auto_ptr<llvm::TargetMachine> targetPtr(targetEntry->CtorFn(*ir.module, "")); // TODO: replace "" with features |
74 assert(targetPtr.get() && "Could not allocate target machine!"); | 75 assert(targetPtr.get() && "Could not allocate target machine!"); |
75 llvm::TargetMachine &targetMachine = *targetPtr.get(); | 76 llvm::TargetMachine &targetMachine = *targetPtr.get(); |
76 gTargetData = targetMachine.getTargetData(); | 77 gTargetData = targetMachine.getTargetData(); |
78 | |
79 // debug info | |
80 if (global.params.symdebug) { | |
81 RegisterDwarfSymbols(ir.module); | |
82 ir.dwarfCompileUnit = DtoDwarfCompileUnit(this); | |
83 } | |
77 | 84 |
78 // process module members | 85 // process module members |
79 for (int k=0; k < members->dim; k++) { | 86 for (int k=0; k < members->dim; k++) { |
80 Dsymbol* dsym = (Dsymbol*)(members->data[k]); | 87 Dsymbol* dsym = (Dsymbol*)(members->data[k]); |
81 assert(dsym); | 88 assert(dsym); |
748 llvmQueued = true; | 755 llvmQueued = true; |
749 } | 756 } |
750 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete | 757 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete |
751 } | 758 } |
752 | 759 |
760 // debug info | |
761 if (global.params.symdebug) { | |
762 llvmDwarfSubProgram = DtoDwarfSubProgram(this); | |
763 } | |
764 | |
753 assert(f->llvmType); | 765 assert(f->llvmType); |
754 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0)); | 766 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0)); |
755 | 767 |
756 // only members of the current module maybe be defined | 768 // only members of the current module maybe be defined |
757 if (getModule() == gIR->dmodule || parent->isTemplateInstance()) | 769 if (getModule() == gIR->dmodule || parent->isTemplateInstance()) |
806 gIR->scopes.push_back(IRScope(beginbb, endbb)); | 818 gIR->scopes.push_back(IRScope(beginbb, endbb)); |
807 | 819 |
808 // create alloca point | 820 // create alloca point |
809 f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); | 821 f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); |
810 gIR->func().allocapoint = f->llvmAllocaPoint; | 822 gIR->func().allocapoint = f->llvmAllocaPoint; |
823 | |
824 // give arguments storage | |
825 size_t n = Argument::dim(f->parameters); | |
826 for (int i=0; i < n; ++i) { | |
827 Argument* arg = Argument::getNth(f->parameters, i); | |
828 if (arg && arg->vardecl) { | |
829 VarDeclaration* vd = arg->vardecl; | |
830 if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) | |
831 continue; | |
832 llvm::Value* a = vd->llvmValue; | |
833 assert(a); | |
834 std::string s(a->getName()); | |
835 Logger::println("giving argument '%s' storage", s.c_str()); | |
836 s.append("_storage"); | |
837 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,f->llvmAllocaPoint); | |
838 gIR->ir->CreateStore(a,v); | |
839 vd->llvmValue = v; | |
840 } | |
841 else assert(0); | |
842 } | |
843 | |
844 // debug info | |
845 if (global.params.symdebug) DtoDwarfFuncStart(this); | |
811 | 846 |
812 llvm::Value* parentNested = NULL; | 847 llvm::Value* parentNested = NULL; |
813 if (FuncDeclaration* fd = toParent()->isFuncDeclaration()) { | 848 if (FuncDeclaration* fd = toParent()->isFuncDeclaration()) { |
814 parentNested = fd->llvmNested; | 849 parentNested = fd->llvmNested; |
815 } | 850 } |
864 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement | 899 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement |
865 // in automatically, so we do it here. | 900 // in automatically, so we do it here. |
866 if (!isMain()) { | 901 if (!isMain()) { |
867 if (!gIR->scopereturned()) { | 902 if (!gIR->scopereturned()) { |
868 // pass the previous block into this block | 903 // pass the previous block into this block |
869 //new llvm::BranchInst(irs.end, irs.begin); | 904 if (global.params.symdebug) DtoDwarfFuncEnd(this); |
870 if (func->getReturnType() == llvm::Type::VoidTy) { | 905 if (func->getReturnType() == llvm::Type::VoidTy) { |
871 new llvm::ReturnInst(gIR->scopebb()); | 906 new llvm::ReturnInst(gIR->scopebb()); |
872 } | 907 } |
873 else { | 908 else { |
874 new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb()); | 909 new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb()); |