aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CodeGen.cc2
-rw-r--r--lib/CodeGen/Designator.cc39
-rw-r--r--lib/CodeGen/StatementGen.cc2
-rw-r--r--lib/CodeGen/ValueTypeGen.cc6
4 files changed, 33 insertions, 16 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index 9f59a4d..92a52e8 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -288,7 +288,7 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
if (auto *Class = dynamic_cast<ClassTypeDeclAST*>(Stmt.get())) {
for (const auto &Method : Class->getMethods()) {
SaveAndRestore<int> MethodLocation(DiagnosticLine, Method->getLine());
- if (findMethod(Class->getName(), Method->getProto()->getName()) == Method->getProto())
+ if (isRegisteredMethod(Class->getName(), Method->getProto()))
FuncGen->emitPrototype(Method->getProto());
}
}
diff --git a/lib/CodeGen/Designator.cc b/lib/CodeGen/Designator.cc
index 540059d..467f788 100644
--- a/lib/CodeGen/Designator.cc
+++ b/lib/CodeGen/Designator.cc
@@ -59,20 +59,40 @@ void CodeGen::runTypePrePass(const std::vector<std::unique_ptr<StmtAST>> &Statem
const std::string &Name = Method->getProto()->getName();
if (sameIdentifier(Name, "this")) {
reportError("A method cannot be named this");
- } else if (!Names.insert(Name).second) {
+ } else if (Names.count(Name) ||
+ (!Methods[Name].empty() && (!Method->getProto()->isOverload() ||
+ !Methods[Name].front()->getProto()->isOverload()))) {
reportError("Duplicate member %s in class %s", Name.c_str(), Class->getName().c_str());
} else {
- Methods.emplace(Name, Method.get());
+ Methods[Name].push_back(Method.get());
}
}
}
}
-const PrototypeAST *CodeGen::findMethod(const std::string &Class, const std::string &Name) const {
+const std::vector<FunctionDefAST *> *CodeGen::findMethod(const std::string &Class, const std::string &Name) const {
auto C = ClassMethods.find(Class);
if (C == ClassMethods.end()) return nullptr;
auto M = C->second.find(Name);
- return M == C->second.end() ? nullptr : M->second->getProto();
+ return M == C->second.end() || M->second.empty() ? nullptr : &M->second;
+}
+
+bool CodeGen::isRegisteredMethod(const std::string &Class, const PrototypeAST *Method) const {
+ const auto *Methods = findMethod(Class, Method->getName());
+ if (Methods)
+ for (const auto *Candidate : *Methods)
+ if (Candidate->getProto() == Method) return true;
+ return false;
+}
+
+const FuncSig *CodeGen::resolveMethod(const std::string &Class, const std::string &Name,
+ const std::vector<std::unique_ptr<ExprAST>> &Args) {
+ const auto *Methods = findMethod(Class, Name);
+ if (!Methods) {
+ reportError("Type %s has no method %s", Class.c_str(), Name.c_str());
+ return nullptr;
+ }
+ return resolveCall(Methods->front()->getProto()->getLinkName(), Args);
}
Value *CodeGen::emitMemberCall(MemberCallExprAST *Call) {
@@ -87,18 +107,15 @@ Value *CodeGen::emitMethodCall(const std::string &Class, Value *Receiver,
const std::string &Name,
const std::vector<std::unique_ptr<ExprAST>> &ArgExprs, int Line) {
SaveAndRestore<int> Location(DiagnosticLine, Line);
- const PrototypeAST *Method = findMethod(Class, Name);
- if (!Method) {
- reportError("Type %s has no method %s", Class.c_str(), Name.c_str());
- return nullptr;
- }
+ const FuncSig *Sig = resolveMethod(Class, Name, ArgExprs);
+ if (!Sig) return nullptr;
+ const PrototypeAST *Method = Sig->Prototype;
if (!Method->isPublic() && !sameIdentifier(CurrentClass, Class)) {
reportError("Cannot access private method %s of type %s", Name.c_str(), Class.c_str());
return nullptr;
}
std::vector<Value*> Args = {Receiver};
- const FuncSig *Sig = resolveCall(Method->getLinkName(), ArgExprs);
- if (!Sig || !marshalCallArgs(*Sig, ArgExprs, Line, Args)) return nullptr;
+ if (!marshalCallArgs(*Sig, ArgExprs, Line, Args)) return nullptr;
return FuncGen->emitCall(Sig->LinkName, Args);
}
diff --git a/lib/CodeGen/StatementGen.cc b/lib/CodeGen/StatementGen.cc
index 8783cde..022c550 100644
--- a/lib/CodeGen/StatementGen.cc
+++ b/lib/CodeGen/StatementGen.cc
@@ -19,7 +19,7 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
if (auto *Class = dynamic_cast<ClassTypeDeclAST*>(Stmt)) {
for (const auto &Method : Class->getMethods()) {
// Invalid or duplicate members have already been diagnosed.
- if (findMethod(Class->getName(), Method->getProto()->getName()) == Method->getProto())
+ if (isRegisteredMethod(Class->getName(), Method->getProto()))
emitStmt(Method.get());
}
return;
diff --git a/lib/CodeGen/ValueTypeGen.cc b/lib/CodeGen/ValueTypeGen.cc
index d2bba03..3c1fc06 100644
--- a/lib/CodeGen/ValueTypeGen.cc
+++ b/lib/CodeGen/ValueTypeGen.cc
@@ -119,9 +119,9 @@ const TypeInfo *CodeGen::getExprTypeInfo(ExprAST *Expr) {
if (auto *Call = dynamic_cast<MemberCallExprAST*>(Expr)) {
const TypeInfo *Receiver = getExprTypeInfo(Call->getReceiver());
- const PrototypeAST *Method = Receiver ? findMethod(Receiver->Name, Call->getMethod()) : nullptr;
- if (!Method || (!Method->isPublic() && !sameIdentifier(CurrentClass, Receiver->Name))) return nullptr;
- return resolveType(Method->getReturnType());
+ const FuncSig *Sig = Receiver ? resolveMethod(Receiver->Name, Call->getMethod(), Call->getArgs()) : nullptr;
+ if (!Sig || (!Sig->Prototype->isPublic() && !sameIdentifier(CurrentClass, Receiver->Name))) return nullptr;
+ return resolveType(Sig->ReturnTypeName);
}
if (auto *Call = dynamic_cast<CallExprAST*>(Expr)) {