aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/FunctionGen.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/FunctionGen.cc')
-rw-r--r--lib/CodeGen/FunctionGen.cc58
1 files changed, 32 insertions, 26 deletions
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc
index 957a1f5..a155f60 100644
--- a/lib/CodeGen/FunctionGen.cc
+++ b/lib/CodeGen/FunctionGen.cc
@@ -2,6 +2,7 @@
#include "cps/CodeGen.h"
#include "cps/ExceptionHandler.h"
#include <cstdio>
+#include <cstdarg>
using namespace llvm;
using namespace cps;
@@ -19,16 +20,26 @@ static bool isReservedRuntimeName(const std::string &Name) {
"__gxx_personality_seh0", "__gxx_personality_sj0", "_Unwind_Resume", "_ZTIi",
};
for (const char *R : Reserved) {
- if (Name == R) return true;
+ if (sameIdentifier(Name, R)) return true;
}
return false;
}
+void FunctionGen::reportError(const char *Fmt, ...) {
+ va_list Args;
+ va_start(Args, Fmt);
+ fprintf(stderr, "error: ");
+ vfprintf(stderr, Fmt, Args);
+ if (DiagnosticLine) fprintf(stderr, " at line %d", DiagnosticLine);
+ fprintf(stderr, "\n");
+ va_end(Args);
+ HadError = true;
+}
+
Type *FunctionGen::getLLVMType(const std::string &TypeName) {
Type *Resolved = Types.getLLVMType(TypeName);
if (!Resolved) {
- fprintf(stderr, "error: Unknown type %s\n", TypeName.c_str());
- HadError = true;
+ reportError("Unknown type %s", TypeName.c_str());
return Type::getInt64Ty(Context);
}
return Resolved;
@@ -38,12 +49,10 @@ void FunctionGen::createArgumentAllocas(Function *F, const std::vector<ParamDecl
Function::arg_iterator AI = F->arg_begin();
for (const ParamDecl &P : Params) {
if (Types.lookupEnumConstant(P.Name)) {
- fprintf(stderr, "error: parameter '%s' collides with an enum value\n", P.Name.c_str());
- HadError = true;
+ reportError("parameter '%s' collides with an enum value", P.Name.c_str());
}
if (Types.resolve(P.Name)) {
- fprintf(stderr, "error: parameter '%s' collides with a type name\n", P.Name.c_str());
- HadError = true;
+ reportError("parameter '%s' collides with a type name", P.Name.c_str());
}
Value *ArgVal = &(*AI);
++AI;
@@ -88,39 +97,35 @@ const FuncSig *FunctionGen::getSignature(const std::string &Name) const {
Function *FunctionGen::emitPrototype(PrototypeAST *Proto) {
if (isReservedRuntimeName(Proto->getName())) {
- fprintf(stderr, "error: '%s' is a reserved runtime symbol and cannot be a FUNCTION/PROCEDURE name\n",
+ reportError("'%s' is a reserved runtime symbol and cannot be a FUNCTION/PROCEDURE name",
Proto->getName().c_str());
- HadError = true;
return nullptr;
}
if (CodeGen::isBuiltinName(Proto->getName())) {
- fprintf(stderr, "error: '%s' is a built-in function and cannot be redefined\n",
+ reportError("'%s' is a built-in function and cannot be redefined",
Proto->getName().c_str());
- HadError = true;
return nullptr;
}
if (Types.lookupEnumConstant(Proto->getName())) {
- fprintf(stderr, "error: '%s' is an enum value and cannot be a FUNCTION/PROCEDURE name\n",
+ reportError("'%s' is an enum value and cannot be a FUNCTION/PROCEDURE name",
Proto->getName().c_str());
- HadError = true;
return nullptr;
}
if (Types.resolve(Proto->getName())) {
- fprintf(stderr, "error: '%s' is a type name and cannot be a FUNCTION/PROCEDURE name\n",
+ reportError("'%s' is a type name and cannot be a FUNCTION/PROCEDURE name",
Proto->getName().c_str());
- HadError = true;
return nullptr;
}
FuncSig Sig;
+ Sig.Name = Proto->getName();
Sig.ReturnTypeName = Proto->getReturnType();
std::vector<Type*> ArgTypes;
for (const ParamDecl &P : Proto->getParams()) {
const TypeInfo *Info = Types.resolve(P.TypeName);
if (Info && Info->isVoid()) {
- fprintf(stderr, "error: parameter %s cannot have void type\n", P.Name.c_str());
- HadError = true;
+ reportError("parameter %s cannot have void type", P.Name.c_str());
return nullptr;
}
ParamSig PS;
@@ -148,11 +153,11 @@ Function *FunctionGen::emitPrototype(PrototypeAST *Proto) {
Type *RetType = getLLVMType(Proto->getReturnType());
FunctionType *FT = FunctionType::get(RetType, ArgTypes, false);
- Function *F = Module.getFunction(Proto->getName());
+ const FuncSig *Existing = getSignature(Proto->getName());
+ Function *F = Module.getFunction(Existing ? Existing->Name : Proto->getName());
if (F && F->getFunctionType() != FT) {
- fprintf(stderr, "error: Function %s conflicts with an existing declaration of a different type\n",
+ reportError("Function %s conflicts with an existing declaration of a different type",
Proto->getName().c_str());
- HadError = true;
return nullptr;
}
if (!F) {
@@ -184,15 +189,14 @@ Function *FunctionGen::emitFunctionDef(FunctionDefAST *FuncAST,
if (!TheFunction) return nullptr;
if (!TheFunction->empty()) {
- fprintf(stderr, "error: Function %s cannot be redefined.\n", Proto->getName().c_str());
- HadError = true;
+ reportError("Function %s cannot be redefined.", Proto->getName().c_str());
return nullptr;
}
BasicBlock *BB = BasicBlock::Create(Context, "entry", TheFunction);
Builder.SetInsertPoint(BB);
- std::map<std::string, SymbolInfo> OldSymbols = Symbols;
+ IdentifierMap<SymbolInfo> OldSymbols = Symbols;
Symbols.clear();
for (const auto &[Name, Info] : OldSymbols) {
if (Info.ConstantValue && Info.ScopeID == 0) Symbols.emplace(Name, Info);
@@ -209,7 +213,7 @@ Function *FunctionGen::emitFunctionDef(FunctionDefAST *FuncAST,
}
if (!Builder.GetInsertBlock()->hasTerminator()) {
- if (Proto->getReturnType() == "VOID") {
+ if (sameIdentifier(Proto->getReturnType(), "VOID")) {
Builder.CreateRetVoid();
} else {
Builder.CreateRet(Constant::getNullValue(TheFunction->getReturnType()));
@@ -240,11 +244,13 @@ static Value *GenerateCall(llvm::Module &Module,
}
llvm::Value *FunctionGen::emitCallExpr(CallExprAST *Call, const std::vector<llvm::Value*> &Args) {
- return GenerateCall(Module, Exceptions, Call->getCallee(), Args, HadError);
+ const FuncSig *Sig = getSignature(Call->getCallee());
+ return GenerateCall(Module, Exceptions, Sig ? Sig->Name : Call->getCallee(), Args, HadError);
}
void FunctionGen::emitCallStmt(CallStmtAST *Call, const std::vector<llvm::Value*> &Args) {
- GenerateCall(Module, Exceptions, Call->getCallee(), Args, HadError);
+ const FuncSig *Sig = getSignature(Call->getCallee());
+ GenerateCall(Module, Exceptions, Sig ? Sig->Name : Call->getCallee(), Args, HadError);
}
void FunctionGen::emitReturn(ReturnStmtAST *Ret, llvm::Value *RetVal) {