fir::Type* Class::createType(CodegenInstance* cgi) { if(this->didCreateType) return 0; // see if we have nested types for(auto nested : this->nestedTypes) { cgi->pushNestedTypeScope(this); nested.second = nested.first->createType(cgi); cgi->popNestedTypeScope(); } // check our inheritances?? bool alreadyHaveSuperclass = false; for(auto super : this->protocolstrs) { TypePair_t* type = cgi->getType(super); if(type == 0) error(this, "Type %s does not exist", super.c_str()); if(type->second.second == TypeKind::Class) { if(alreadyHaveSuperclass) { error(this, "Multiple inheritance is not supported, only one superclass" " can be inherited from. Consider using protocols instead"); } alreadyHaveSuperclass = true; } else if(type->second.second != TypeKind::Protocol) { error(this, "%s is neither a protocol nor a class, and cannot be inherited from", super.c_str()); } Class* supcls = dynamic_cast<Class*>(type->second.first); iceAssert(supcls); // this will (should) do a recursive thing where they copy all their superclassed methods into themselves // by the time we see it. supcls->createType(cgi); // if it's a struct, copy its members into ourselves. if(type->second.second == TypeKind::Class) { this->superclass = { supcls, type->first->toStructType() }; // normal members for(auto mem : supcls->members) { auto pred = [mem](VarDecl* v) -> bool { return v->name == mem->name; }; auto it = std::find_if(this->members.begin(), this->members.end(), pred); if(it != this->members.end()) { error(*it, "Fields cannot be overriden, only computed properties can"); } this->members.push_back(mem); } size_t nms = this->nameMap.size(); for(auto nm : supcls->nameMap) { this->nameMap[nm.first] = nms; nms++; } // functions for(auto fn : supcls->funcs) { auto pred = [fn, cgi](Func* f) -> bool { if(fn->decl->params.size() != f->decl->params.size()) return false; for(size_t i = 0; i < fn->decl->params.size(); i++) { if(cgi->getExprType(fn->decl->params[i]) != cgi->getExprType(f->decl->params[i])) return false; } return fn->decl->name == f->decl->name; }; auto it = std::find_if(this->funcs.begin(), this->funcs.end(), pred); if(it != this->funcs.end()) { // check for 'override' Func* f = *it; if(!(f->decl->attribs & Attr_Override)) { error(f->decl, "Overriding function '%s' in superclass %s requires 'override' keyword", cgi->printAst(f->decl).c_str(), supcls->name.c_str()); } else { // don't add the superclass one. continue; } } this->funcs.push_back((Func*) cgi->cloneAST(fn)); } // computed properties for(auto cp : supcls->cprops) { auto pred = [cp](ComputedProperty* cpr) -> bool { return cp->name == cpr->name; }; auto it = std::find_if(this->cprops.begin(), this->cprops.end(), pred); if(it != this->cprops.end()) { // this thing exists. // check if ours has an override ComputedProperty* ours = *it; iceAssert(ours->name == cp->name); if(!(ours->attribs & Attr_Override)) { error(ours, "Overriding computed property '%s' in superclass %s needs 'override' keyword", ours->name.c_str(), supcls->name.c_str()); } else { // we have 'override'. // disable this property, don't add it. continue; } } this->cprops.push_back((ComputedProperty*) cgi->cloneAST(cp)); } } else { // protcols not supported yet. error(this, "enotsup"); } } fir::Type** types = new fir::Type*[this->members.size()]; // create a bodyless struct so we can use it std::deque<std::string> fullScope = cgi->getFullScope(); this->mangledName = cgi->mangleWithNamespace(this->name, fullScope, false); if(cgi->isDuplicateType(this->mangledName)) GenError::duplicateSymbol(cgi, this, this->name, SymbolType::Type); fir::StructType* str = fir::StructType::createNamedWithoutBody(this->mangledName, cgi->getContext()); this->scope = fullScope; cgi->addNewType(str, this, TypeKind::Class); // because we can't (and don't want to) mangle names in the parser, // we could only build an incomplete name -> index map // finish it here. for(auto p : this->opOverloads) { // before calling codegen (that checks for valid overloads), insert the "self" parameter VarDecl* fakeSelf = new VarDecl(this->pin, "self", true); std::string fulltype; for(auto s : cgi->getFullScope()) fulltype += s + "::"; fakeSelf->type = fulltype + this->name + "*"; p->func->decl->params.push_front(fakeSelf); p->codegen(cgi); // remove it after iceAssert(p->func->decl->params.front() == fakeSelf); p->func->decl->params.pop_front(); } for(Func* func : this->funcs) { // only override if we don't have one. if(this->attribs & Attr_VisPublic && !(func->decl->attribs & (Attr_VisInternal | Attr_VisPrivate | Attr_VisPublic))) func->decl->attribs |= Attr_VisPublic; func->decl->parentClass = this; std::string mangled = cgi->mangleFunctionName(func->decl->name, func->decl->params); if(this->nameMap.find(mangled) != this->nameMap.end()) { error(this, "Duplicate member '%s'", func->decl->name.c_str()); } } for(VarDecl* var : this->members) { var->inferType(cgi); // fir::Type* type = cgi->getExprType(var); iceAssert(var->inferredLType != 0); fir::Type* type = var->inferredLType; if(type == str) { error(this, "Cannot have non-pointer member of type self"); } cgi->applyExtensionToStruct(cgi->mangleWithNamespace(var->type.strType)); if(!var->isStatic) { int i = this->nameMap[var->name]; iceAssert(i >= 0); types[i] = cgi->getExprType(var); } } std::vector<fir::Type*> vec(types, types + this->nameMap.size()); str->setBody(vec); this->didCreateType = true; delete types; return str; }
// N-pass system. // there's no point counting at this stage. static void codegenTopLevel(CodegenInstance* cgi, int pass, std::deque<Expr*> expressions, bool isInsideNamespace) { if(pass == 0) { // add all the types for order-independence -- if we encounter a need, we can // force codegen. for(Expr* e : expressions) { NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); TypeAlias* ta = dynamic_cast<TypeAlias*>(e); Struct* str = dynamic_cast<Struct*>(e); Class* cls = dynamic_cast<Class*>(e); // enum : class, extension : class Func* fn = dynamic_cast<Func*>(e); ForeignFuncDecl* ffi = dynamic_cast<ForeignFuncDecl*>(e); OpOverload* oo = dynamic_cast<OpOverload*>(e); if(ns) ns->codegenPass(cgi, pass); else if(ta) addTypeToFuncTree(cgi, ta, ta->name, TypeKind::TypeAlias); else if(str) addTypeToFuncTree(cgi, str, str->name, TypeKind::Struct); else if(cls) addTypeToFuncTree(cgi, cls, cls->name, TypeKind::Class); else if(fn) addFuncDeclToFuncTree(cgi, fn->decl); else if(ffi) addFuncDeclToFuncTree(cgi, ffi->decl); else if(oo) addOpOverloadToFuncTree(cgi, oo); } } else if(pass == 1) { // pass 1: setup extensions for(Expr* e : expressions) { Extension* ext = dynamic_cast<Extension*>(e); NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); if(ext) ext->mangledName = cgi->mangleWithNamespace(ext->name); else if(ns) ns->codegenPass(cgi, pass); } // we need the 'Type' enum to be available, as well as the 'Any' type, // before any variables are encountered. if(!isInsideNamespace) TypeInfo::initialiseTypeInfo(cgi); } else if(pass == 2) { // pass 2: create types for(Expr* e : expressions) { Struct* str = dynamic_cast<Struct*>(e); Class* cls = dynamic_cast<Class*>(e); // enums are handled, since enum : class NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); if(str) str->createType(cgi); if(cls) cls->createType(cgi); else if(ns) ns->codegenPass(cgi, pass); } } else if(pass == 3) { // pass 3: override types with any extensions for(Expr* e : expressions) { Extension* ext = dynamic_cast<Extension*>(e); NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); TypeAlias* ta = dynamic_cast<TypeAlias*>(e); if(ext) ext->createType(cgi); else if(ta) ta->createType(cgi); else if(ns) ns->codegenPass(cgi, pass); } // step 3: generate the type info. // now that we have all the types that we need, and they're all fully // processed, we create the Type enum. TypeInfo::generateTypeInfo(cgi); } else if(pass == 4) { // pass 4: create declarations for(Expr* e : expressions) { ForeignFuncDecl* ffi = dynamic_cast<ForeignFuncDecl*>(e); Func* func = dynamic_cast<Func*>(e); NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); if(ffi) ffi->codegen(cgi); else if(ns) ns->codegenPass(cgi, pass); else if(func) { // func->decl->codegen(cgi); } } } else if(pass == 5) { // start semantic analysis before any typechecking needs to happen. SemAnalysis::rewriteDotOperators(cgi); // pass 4: everything else for(Expr* e : expressions) { Struct* str = dynamic_cast<Struct*>(e); Class* cls = dynamic_cast<Class*>(e); // again, enums are handled since enum : class Extension* ext = dynamic_cast<Extension*>(e); NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); VarDecl* vd = dynamic_cast<VarDecl*>(e); if(str) str->codegen(cgi); else if(cls) cls->codegen(cgi); else if(ext) ext->codegen(cgi); else if(ns) ns->codegenPass(cgi, pass); else if(vd) vd->isGlobal = true, vd->codegen(cgi); } } else if(pass == 6) { // pass 7: functions. for generic shit. for(Expr* e : expressions) { Func* func = dynamic_cast<Func*>(e); NamespaceDecl* ns = dynamic_cast<NamespaceDecl*>(e); if(func && !func->didCodegen) func->codegen(cgi); if(ns) ns->codegenPass(cgi, pass); } } else { error("Invalid pass number '%d'\n", pass); } }