From 10174ffc7ea08b7845dbe409a11811e820536468 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sat, 15 Dec 2012 07:06:22 +0000 Subject: Compile constructors as LLVM struct types. Use LLVM type names instead of hyper verbose literal types in more places in general. More work on quoting. git-svn-id: http://svn.drobilla.net/resp/trunk@439 ad02d1e2-f140-0410-9f75-f8b11f17cedd --- src/llvm.cpp | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'src/llvm.cpp') diff --git a/src/llvm.cpp b/src/llvm.cpp index 7f521b7..795cd8c 100644 --- a/src/llvm.cpp +++ b/src/llvm.cpp @@ -100,7 +100,7 @@ struct LLVMEngine : public Engine { CVal compileLiteral(CEnv& cenv, const AST* lit); CVal compilePrimitive(CEnv& cenv, const ATuple* prim); CVal compileString(CEnv& cenv, const char* str); - CType compileType(CEnv& cenv, const char* name, const AST* exp); + CType compileType(CEnv& cenv, const std::string& name, const AST* exp); void writeModule(CEnv& cenv, std::ostream& os); @@ -193,7 +193,6 @@ LLVMEngine::llType(const AST* t, const char* name) if (sym == "Float") return Type::getFloatTy(context); if (sym == "String") return PointerType::get(Type::getInt8Ty(context), 0); if (sym == "Symbol") return PointerType::get(Type::getInt8Ty(context), 0); - if (sym == "Expr") return PointerType::get(Type::getInt8Ty(context), 0); if (sym == opaqueName) { THROW_IF(!opaqueT, t->loc, "Broken recursive type"); return PointerType::getUnqual(opaqueT); @@ -233,6 +232,21 @@ LLVMEngine::llType(const AST* t, const char* name) Type* ret = NULL; vector ctypes; + + if (!name) { + const ASymbol* tag = t->as_tuple()->fst()->as_symbol(); + if (tag->str() != "Tup" && tag->str() != "Closure") { + name = tag->str().c_str(); + } + } + + if (name) { + CTypes::const_iterator i = compiledTypes.find(name); + if (i != compiledTypes.end()) { + return i->second; + } + } + // Define opaque type to stand for name in recursive type body if (name) { THROW_IF(opaqueT, t->loc, "Nested recursive types"); @@ -279,7 +293,17 @@ LLVMEngine::compileCall(CEnv& cenv, CFunc f, const ATuple* funcT, const vectorto_tuple(); + string name; + if (tup) { + const ASymbol* head = tup->fst()->to_symbol(); + if (head && head->str() != "Fn" && isupper(head->str()[0])) { + name = head->str(); + } + } else if (t->to_symbol()) { + name = t->to_symbol()->str(); + } + return builder.CreateBitCast(llVal(v), (Type*)compileType(cenv, name, cenv.resolveType(t)), "cast"); } CVal @@ -291,7 +315,7 @@ LLVMEngine::compileCons(CEnv& cenv, const char* tname, const ATuple* type, CVal assert(type->begin() != type->end()); for (ATuple::const_iterator i = type->iter_at(1); i != type->end(); ++i) s += engine->getTargetData()->getTypeSizeInBits( - (Type*)compileType(cenv, NULL, *i)); + (Type*)compileType(cenv, (*i)->str(), *i)); // Allocate struct const std::string name = type->fst()->str(); @@ -354,17 +378,18 @@ LLVMEngine::compileString(CEnv& cenv, const char* str) } CType -LLVMEngine::compileType(CEnv& cenv, const char* name, const AST* expr) +LLVMEngine::compileType(CEnv& cenv, const std::string& name, const AST* expr) { - if (name) { + if (!name.empty()) { CTypes::const_iterator i = compiledTypes.find(name); - if (i != compiledTypes.end()) + if (i != compiledTypes.end()) { return i->second; + } } - Type* const type = llType(expr, name); + Type* const type = llType(expr, name.c_str()); - if (name) + if (!name.empty()) compiledTypes.insert(make_pair(name, type)); return type; @@ -381,8 +406,9 @@ LLVMEngine::startFn( vector cprot; FOREACHP(ATuple::const_iterator, i, argsT) { - const char* name = (*i)->to_symbol() ? (*i)->as_symbol()->sym() : NULL; - CType iT = compileType(cenv, name, cenv.resolveType(*i)); + const CType iT = ((*i)->to_symbol()) + ? compileType(cenv, (*i)->str(), cenv.resolveType(*i)) + : compileType(cenv, (*i)->as_tuple()->fst()->str(), *i); THROW_IF(!iT, Cursor(), string("non-concrete parameter :: ") + (*i)->str()); cprot.push_back((Type*)iT); } @@ -432,7 +458,7 @@ LLVMEngine::pushFnArgs(CEnv& cenv, const ATuple* prot, const ATuple* type, CFunc assert(prot->size() == argsT->size()); assert(prot->size() == f->num_args()); for (Function::arg_iterator a = f->arg_begin(); a != f->arg_end(); ++a, ++p, ++pT) { - const AST* t = cenv.resolveType(*pT); + const AST* t = *pT;//cenv.resolveType(*pT); // THROW_IF(!llType(t), (*p)->loc, "untyped parameter\n"); cenv.def((*p)->as_symbol(), *p, t, &*a); } -- cgit v1.2.1