void Class::addMethod(std::string name, Type* t, std::vector<Argument*>* args, Stm* body, int method_state) { // Add this argument at the beginning of arg list if (!args) args = new std::vector<Argument*>(); // TODO Do not do this for static methods if (!(method_state == 1)) { args->insert(args->begin(), new Argument(new TypeClass(this), "this")); } TypeFunction* tf = new TypeFunction(t); tf->setVirtual(method_state == 2); tf->setClass(this); cy::Function* f = new cy::Function(tf, args, body); f->setOriginalName(name); this->methods->push_back(f); // Do specific operation tf->setStatic(false); f->setStatic(false); switch (method_state) { case 1: // Method is static tf->setStatic(true); f->setStatic(true); break; case 2: // Virtual method f->setVirtual(true); tf->setVirtual(true); this->setVTable(); // Set pointer to vtable attribute this->virtual_methods->push_back(f); break; case 3: // Overriden method tf->setOverridden(true); if (!this->getParent()) { throw __FILE__ "(" QUOTE(__LINE__) "): Method " + name + " is overridden, but no super class."; } std::vector<Type*>* types = new std::vector<Type*>(); std::vector<Argument*>::iterator itarg; for (itarg = args->begin(); itarg != args->end(); itarg++) { types->push_back((*itarg)->getType()); } // Verify method with same name and same types exists in if (!this->getParent()->getMethod(name, types)) { throw __FILE__ "(" QUOTE(__LINE__) "): Method " + name + " is overridden, but not in super class."; } delete types; break; } }
void VisitorNodeTyper::visit(ExprSymbol *n){ // TODO Set flag if global or local if (this->cur_class) { Type* t = this->cur_class->getAttrType(n->getName()); // Get type from class if (!t) // If no type returned, it might be an unmangled method name { if (this->look_for_mangled) { TypeFunction* tf = new TypeFunction(); tf->setClass(this->cur_class); tf->setName(n->getName()); t = tf; } else { throw __FILE__ "(" QUOTE(__LINE__) "): Attribute " + n->getName() + " not found in class" + this->cur_class->getName() + "."; } } n->setType(t); } else { Variable* v = this->symt->get(n->getName()); if (!v) // Symbol not found { if (this->look_for_mangled) // Look for an unmangled name { TypeFunction* tf = new TypeFunction(); tf->setName(n->getName()); tf->setStatic(true); tf->setVirtual(false); n->setType(tf); } else { throw __FILE__ "(" QUOTE(__LINE__) "): Variable " + n->getName() + " not found."; } } else { n->setType(v->getType()); } } }