Mercurial > projects > ldc
comparison gen/toir.cpp @ 144:a27941d00351 trunk
[svn r149] fixed: a bunch of D-style variadics problems.
fixed: GotoDefaultStatement implemented.
fixed: some other minor bugs.
author | lindquist |
---|---|
date | Sat, 26 Jan 2008 17:13:22 +0100 |
parents | 336ec4f4bbb3 |
children | 2c336566ffed |
comparison
equal
deleted
inserted
replaced
143:336ec4f4bbb3 | 144:a27941d00351 |
---|---|
151 | 151 |
152 // _arguments | 152 // _arguments |
153 if (vd->ident == Id::_arguments) | 153 if (vd->ident == Id::_arguments) |
154 { | 154 { |
155 Logger::println("Id::_arguments"); | 155 Logger::println("Id::_arguments"); |
156 if (!vd->getIrValue()) | 156 /*if (!vd->getIrValue()) |
157 vd->getIrValue() = p->func()->decl->irFunc->_arguments; | 157 vd->getIrValue() = p->func()->decl->irFunc->_arguments; |
158 assert(vd->getIrValue()); | 158 assert(vd->getIrValue()); |
159 return new DVarValue(vd, vd->getIrValue(), true); | 159 return new DVarValue(vd, vd->getIrValue(), true);*/ |
160 llvm::Value* v = p->func()->decl->irFunc->_arguments; | |
161 assert(v); | |
162 return new DVarValue(vd, v, true); | |
160 } | 163 } |
161 // _argptr | 164 // _argptr |
162 else if (vd->ident == Id::_argptr) | 165 else if (vd->ident == Id::_argptr) |
163 { | 166 { |
164 Logger::println("Id::_argptr"); | 167 Logger::println("Id::_argptr"); |
165 if (!vd->getIrValue()) | 168 /*if (!vd->getIrValue()) |
166 vd->getIrValue() = p->func()->decl->irFunc->_argptr; | 169 vd->getIrValue() = p->func()->decl->irFunc->_argptr; |
167 assert(vd->getIrValue()); | 170 assert(vd->getIrValue()); |
168 return new DVarValue(vd, vd->getIrValue(), true); | 171 return new DVarValue(vd, vd->getIrValue(), true);*/ |
172 llvm::Value* v = p->func()->decl->irFunc->_argptr; | |
173 assert(v); | |
174 return new DVarValue(vd, v, true); | |
169 } | 175 } |
170 // _dollar | 176 // _dollar |
171 else if (vd->ident == Id::dollar) | 177 else if (vd->ident == Id::dollar) |
172 { | 178 { |
173 Logger::println("Id::dollar"); | 179 Logger::println("Id::dollar"); |
1046 size_t nimplicit = j; | 1052 size_t nimplicit = j; |
1047 | 1053 |
1048 std::vector<const llvm::Type*> vtypes; | 1054 std::vector<const llvm::Type*> vtypes; |
1049 std::vector<llvm::Value*> vtypeinfos; | 1055 std::vector<llvm::Value*> vtypeinfos; |
1050 | 1056 |
1057 // number of non variadic args | |
1058 int begin = tf->parameters->dim; | |
1059 Logger::println("num non vararg params = %d", begin); | |
1060 | |
1051 // build struct with argument types | 1061 // build struct with argument types |
1052 for (int i=0; i<arguments->dim; i++) | 1062 for (int i=begin; i<arguments->dim; i++) |
1053 { | 1063 { |
1064 Argument* argu = Argument::getNth(tf->parameters, i); | |
1054 Expression* argexp = (Expression*)arguments->data[i]; | 1065 Expression* argexp = (Expression*)arguments->data[i]; |
1055 vtypes.push_back(DtoType(argexp->type)); | 1066 vtypes.push_back(DtoType(argexp->type)); |
1056 } | 1067 } |
1057 const llvm::StructType* vtype = llvm::StructType::get(vtypes); | 1068 const llvm::StructType* vtype = llvm::StructType::get(vtypes); |
1058 Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; | 1069 Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; |
1059 llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); | 1070 llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); |
1060 | 1071 |
1061 // store arguments in the struct | 1072 // store arguments in the struct |
1062 for (int i=0; i<arguments->dim; i++) | 1073 for (int i=begin,k=0; i<arguments->dim; i++,k++) |
1063 { | 1074 { |
1064 Expression* argexp = (Expression*)arguments->data[i]; | 1075 Expression* argexp = (Expression*)arguments->data[i]; |
1065 if (global.params.llvmAnnotate) | 1076 if (global.params.llvmAnnotate) |
1066 DtoAnnotation(argexp->toChars()); | 1077 DtoAnnotation(argexp->toChars()); |
1067 DtoVariadicArgument(argexp, DtoGEPi(mem,0,i,"tmp")); | 1078 DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp")); |
1068 } | 1079 } |
1069 | 1080 |
1070 // build type info array | 1081 // build type info array |
1071 assert(Type::typeinfo->irStruct->constInit); | 1082 assert(Type::typeinfo->irStruct->constInit); |
1072 const llvm::Type* typeinfotype = getPtrToType(Type::typeinfo->irStruct->constInit->getType()); | 1083 const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type); |
1073 Logger::cout() << "typeinfo ptr type: " << *typeinfotype << '\n'; | |
1074 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); | 1084 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); |
1075 | 1085 |
1076 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); | 1086 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); |
1077 for (int i=0; i<arguments->dim; i++) | 1087 Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; |
1088 for (int i=begin,k=0; i<arguments->dim; i++,k++) | |
1078 { | 1089 { |
1079 Expression* argexp = (Expression*)arguments->data[i]; | 1090 Expression* argexp = (Expression*)arguments->data[i]; |
1080 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); | 1091 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); |
1081 DtoForceDeclareDsymbol(tidecl); | 1092 DtoForceDeclareDsymbol(tidecl); |
1082 assert(tidecl->getIrValue()); | 1093 assert(tidecl->getIrValue()); |
1083 vtypeinfos.push_back(tidecl->getIrValue()); | 1094 vtypeinfos.push_back(tidecl->getIrValue()); |
1084 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp"); | 1095 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[k], typeinfotype, "tmp"); |
1085 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp")); | 1096 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,k,"tmp")); |
1086 } | 1097 } |
1087 | 1098 |
1088 // put data in d-array | 1099 // put data in d-array |
1089 llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint()); | 1100 llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint()); |
1090 p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp")); | 1101 p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp")); |
1094 // specify arguments | 1105 // specify arguments |
1095 llargs[j] = typeinfoarrayparam;; | 1106 llargs[j] = typeinfoarrayparam;; |
1096 j++; | 1107 j++; |
1097 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); | 1108 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); |
1098 j++; | 1109 j++; |
1099 llargs.resize(nimplicit+2); | 1110 |
1111 // pass non variadic args | |
1112 for (int i=0; i<begin; i++) | |
1113 { | |
1114 Argument* fnarg = Argument::getNth(tf->parameters, i); | |
1115 DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); | |
1116 llargs[j] = argval->getRVal(); | |
1117 j++; | |
1118 } | |
1119 | |
1120 // make sure arg vector has the right size | |
1121 llargs.resize(nimplicit+begin+2); | |
1100 } | 1122 } |
1101 // normal function | 1123 // normal function |
1102 else { | 1124 else { |
1103 Logger::println("doing normal arguments"); | 1125 Logger::println("doing normal arguments"); |
1104 for (int i=0; i<arguments->dim; i++,j++) { | 1126 for (int i=0; i<arguments->dim; i++,j++) { |
1120 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); | 1142 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); |
1121 } | 1143 } |
1122 } | 1144 } |
1123 } | 1145 } |
1124 } | 1146 } |
1125 Logger::println("%d params passed", n); | 1147 } |
1126 for (int i=0; i<n; ++i) { | 1148 } |
1127 assert(llargs[i]); | 1149 |
1128 Logger::cout() << *llargs[i] << '\n'; | 1150 #if 1 |
1129 } | 1151 Logger::println("%d params passed", n); |
1130 } | 1152 for (int i=0; i<llargs.size(); ++i) { |
1131 } | 1153 assert(llargs[i]); |
1154 Logger::cout() << "arg["<<i<<"] = " << *llargs[i] << '\n'; | |
1155 } | |
1156 #endif | |
1132 | 1157 |
1133 // void returns cannot not be named | 1158 // void returns cannot not be named |
1134 const char* varname = ""; | 1159 const char* varname = ""; |
1135 if (llfnty->getReturnType() != llvm::Type::VoidTy) | 1160 if (llfnty->getReturnType() != llvm::Type::VoidTy) |
1136 varname = "tmp"; | 1161 varname = "tmp"; |
1137 | 1162 |
1138 //Logger::cout() << "Calling: " << *funcval << '\n'; | 1163 Logger::cout() << "Calling: " << *funcval << '\n'; |
1139 | 1164 |
1140 // call the function | 1165 // call the function |
1141 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); | 1166 llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); |
1142 llvm::Value* retllval = (retinptr) ? llargs[0] : call; | 1167 llvm::Value* retllval = (retinptr) ? llargs[0] : call; |
1143 | 1168 |
2261 else { | 2286 else { |
2262 assert(l->getType() == r->getType()); | 2287 assert(l->getType() == r->getType()); |
2263 } | 2288 } |
2264 eval = DtoDynArrayIs(op,l,r); | 2289 eval = DtoDynArrayIs(op,l,r); |
2265 } | 2290 } |
2291 else if (t1->isfloating()) | |
2292 { | |
2293 llvm::FCmpInst::Predicate pred = (op == TOKidentity) ? llvm::FCmpInst::FCMP_OEQ : llvm::FCmpInst::FCMP_ONE; | |
2294 eval = new llvm::FCmpInst(pred, l, r, "tmp", p->scopebb()); | |
2295 } | |
2266 else { | 2296 else { |
2267 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; | 2297 llvm::ICmpInst::Predicate pred = (op == TOKidentity) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
2268 if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) { | 2298 if (t1->ty == Tpointer && v->isNull() && l->getType() != r->getType()) { |
2269 r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); | 2299 r = llvm::ConstantPointerNull::get(isaPointer(l->getType())); |
2270 } | 2300 } |
2281 Logger::print("CommaExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2311 Logger::print("CommaExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2282 LOG_SCOPE; | 2312 LOG_SCOPE; |
2283 | 2313 |
2284 DValue* u = e1->toElem(p); | 2314 DValue* u = e1->toElem(p); |
2285 DValue* v = e2->toElem(p); | 2315 DValue* v = e2->toElem(p); |
2316 assert(e2->type == type); | |
2286 return v; | 2317 return v; |
2287 } | 2318 } |
2288 | 2319 |
2289 ////////////////////////////////////////////////////////////////////////////////////////// | 2320 ////////////////////////////////////////////////////////////////////////////////////////// |
2290 | 2321 |
2989 { | 3020 { |
2990 this->tokens = tokens; | 3021 this->tokens = tokens; |
2991 } | 3022 } |
2992 Statement *AsmStatement::syntaxCopy() | 3023 Statement *AsmStatement::syntaxCopy() |
2993 { | 3024 { |
2994 assert(0); | 3025 /*error("%s: inline asm is not yet implemented", loc.toChars()); |
3026 fatal(); | |
3027 assert(0);*/ | |
2995 return 0; | 3028 return 0; |
2996 } | 3029 } |
2997 | 3030 |
2998 Statement *AsmStatement::semantic(Scope *sc) | 3031 Statement *AsmStatement::semantic(Scope *sc) |
2999 { | 3032 { |
3006 Statement::toCBuffer(buf, hgs); | 3039 Statement::toCBuffer(buf, hgs); |
3007 } | 3040 } |
3008 | 3041 |
3009 int AsmStatement::comeFrom() | 3042 int AsmStatement::comeFrom() |
3010 { | 3043 { |
3011 assert(0); | 3044 /*error("%s: inline asm is not yet implemented", loc.toChars()); |
3045 fatal(); | |
3046 assert(0);*/ | |
3012 return 0; | 3047 return 0; |
3013 } | 3048 } |
3014 | 3049 |
3015 void | 3050 void |
3016 backend_init() | 3051 backend_init() |