示例#1
0
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;
}
示例#2
0
// 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);
	}
}