aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CTypeGen.cc3
-rw-r--r--lib/CodeGen/ExpressionGen.cc213
-rw-r--r--lib/CodeGen/FunctionGen.cc11
-rw-r--r--lib/CodeGen/NativeTypeSystem.cc1
-rw-r--r--lib/CodeGen/StatementGen.cc4
5 files changed, 117 insertions, 115 deletions
diff --git a/lib/CodeGen/CTypeGen.cc b/lib/CodeGen/CTypeGen.cc
index 7623103..b30814e 100644
--- a/lib/CodeGen/CTypeGen.cc
+++ b/lib/CodeGen/CTypeGen.cc
@@ -62,6 +62,9 @@ Value *CodeGen::emitCast(CastExprAST *Cast) {
return nullptr;
}
const TypeInfo *Source = getExprTypeInfo(Operand);
+ if (Source && ((Source->Kind == TypeKind::Pointer && Target->CIdentity == "void*") ||
+ (Source->CIdentity == "void*" && Target->Kind == TypeKind::Pointer)))
+ return emitExpr(Operand);
if (!Source || Source->isVoid() || Source->isUserKind() || Target->isUserKind()) {
reportError("Unsupported operand or target for cast to %s", Target->Name.c_str());
return nullptr;
diff --git a/lib/CodeGen/ExpressionGen.cc b/lib/CodeGen/ExpressionGen.cc
index b3655fd..fa2581f 100644
--- a/lib/CodeGen/ExpressionGen.cc
+++ b/lib/CodeGen/ExpressionGen.cc
@@ -124,110 +124,8 @@ Value *CodeGen::emitExpr(ExprAST *Expr) {
return emitBinaryOp(Bin->getOp(), L, LT, R, RT, Bin->getLine());
}
- if (auto *Call = dynamic_cast<CallExprAST*>(Expr)) {
- std::string Name = Call->getCallee();
- if (const BuiltinInfo *B = findBuiltin(Name)) {
- Name = B->Name;
- if (Call->getArgs().size() != B->Arity) {
- reportError("%s expects %u arg%s", B->Name, B->Arity, B->Arity == 1 ? "" : "s");
- return nullptr;
- }
- }
- if (Name == "LENGTH") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrHandler->emitLength(Str);
- }
- if (Name == "MID") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- Value *Start = emitCoercedExpr(Call->getArgs()[1].get(), resolveType("INTEGER"));
- Value *Len = emitCoercedExpr(Call->getArgs()[2].get(), resolveType("INTEGER"));
- if (!Str || !Start || !Len) return nullptr;
- return StrHandler->emitMid(Str, Start, Len);
- }
- if (Name == "RIGHT") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- Value *Len = emitCoercedExpr(Call->getArgs()[1].get(), resolveType("INTEGER"));
- if (!Str || !Len) return nullptr;
- return StrHandler->emitRight(Str, Len);
- }
- if (Name == "LEFT") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- Value *Len = emitCoercedExpr(Call->getArgs()[1].get(), resolveType("INTEGER"));
- if (!Str || !Len) return nullptr;
- return StrHandler->emitLeft(Str, Len);
- }
- if (Name == "LCASE") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrHandler->emitLCase(Str);
- }
- if (Name == "UCASE") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrHandler->emitUCase(Str);
- }
- if (Name == "ASC") {
- const TypeInfo *ArgType = getExprTypeInfo(Call->getArgs()[0].get());
- if (ArgType && (ArgType->isUserKind() || ArgType->isC())) {
- reportError("ASC expects a CHAR or STRING (got %s)", ArgType->Name.c_str());
- return nullptr;
- }
- Value *ArgVal = emitExpr(Call->getArgs()[0].get());
- if (!ArgVal) return nullptr;
- Value *CharVal = nullptr;
- if (ArgType && ArgType->isChar()) {
- CharVal = coerceValueToType(ArgVal, resolveType("CHAR"));
- } else {
- CharVal = Builder->CreateLoad(Type::getInt8Ty(*TheContext), ArgVal, "char_load");
- }
- Value *AscVal = Builder->CreateZExt(CharVal, Type::getInt32Ty(*TheContext), "asc_val");
- return coerceValueToType(AscVal, resolveType("INTEGER"));
- }
- if (Name == "CHR") {
- Value *IntVal = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("INTEGER"));
- if (!IntVal) return nullptr;
- Value *CharVal = Builder->CreateTrunc(IntVal, Type::getInt8Ty(*TheContext), "chr_val");
- return coerceValueToType(CharVal, resolveType("STRING"));
- }
- if (Name == "IS_NUM") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrConvHandler->emitIsNum(Str);
- }
- if (Name == "NUM_TO_STR") {
- const TypeInfo *ArgType = getExprTypeInfo(Call->getArgs()[0].get());
- if (ArgType && (ArgType->isUserKind() || ArgType->isC())) {
- reportError("NUM_TO_STR expects a number (got %s)", ArgType->Name.c_str());
- return nullptr;
- }
- Value *NumV = emitExpr(Call->getArgs()[0].get());
- if (!NumV) return nullptr;
- bool IsReal = NumV->getType()->isDoubleTy();
- if (NumV->getType()->isIntegerTy(8)) {
- NumV = coerceValueToType(NumV, resolveType("INTEGER"));
- }
- return StrConvHandler->emitNumToStr(NumV, IsReal);
- }
- if (Name == "STR_TO_NUM") {
- Value *Str = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- if (!Str) return nullptr;
- return StrConvHandler->emitStrToNum(Str, true);
- }
- if (Name == "EOF") {
- if (isWholeArrayVar(Call->getArgs()[0].get())) {
- reportError("Cannot use a whole array as the EOF filename");
- return nullptr;
- }
- Value *FileName = emitCoercedExpr(Call->getArgs()[0].get(), resolveType("STRING"));
- if (!FileName) return nullptr;
- return Files->emitEof(FileName, Call->getLine());
- }
-
- std::vector<Value*> Args;
- if (!marshalCallArgs(Name, Call->getArgs(), Call->getLine(), Args)) return nullptr;
- return FuncGen->emitCallExpr(Call, Args);
- }
+ if (auto *Call = dynamic_cast<CallExprAST*>(Expr))
+ return emitCall(Call->getCallee(), Call->getArgs(), Call->getLine());
if (auto *D = dynamic_cast<DesignatorExprAST*>(Expr)) {
LValueInfo LV;
@@ -274,3 +172,110 @@ Value *CodeGen::emitBinaryOp(int Op, Value *L, const TypeInfo *LT,
}
return ArithHandler->emitBinaryOp(Op, L, R, Line);
}
+
+Value *CodeGen::emitCall(const std::string &Callee,
+ const std::vector<std::unique_ptr<ExprAST>> &ArgExprs, int Line) {
+ SaveAndRestore<int> Location(DiagnosticLine, Line ? Line : DiagnosticLine);
+ std::string Name = Callee;
+ if (const BuiltinInfo *B = findBuiltin(Name)) {
+ Name = B->Name;
+ if (ArgExprs.size() != B->Arity) {
+ reportError("%s expects %u arg%s", B->Name, B->Arity, B->Arity == 1 ? "" : "s");
+ return nullptr;
+ }
+ }
+ if (Name == "LENGTH") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ if (!Str) return nullptr;
+ return StrHandler->emitLength(Str);
+ }
+ if (Name == "MID") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ Value *Start = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER"));
+ Value *Len = emitCoercedExpr(ArgExprs[2].get(), resolveType("INTEGER"));
+ if (!Str || !Start || !Len) return nullptr;
+ return StrHandler->emitMid(Str, Start, Len);
+ }
+ if (Name == "RIGHT") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ Value *Len = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER"));
+ if (!Str || !Len) return nullptr;
+ return StrHandler->emitRight(Str, Len);
+ }
+ if (Name == "LEFT") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ Value *Len = emitCoercedExpr(ArgExprs[1].get(), resolveType("INTEGER"));
+ if (!Str || !Len) return nullptr;
+ return StrHandler->emitLeft(Str, Len);
+ }
+ if (Name == "LCASE") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ if (!Str) return nullptr;
+ return StrHandler->emitLCase(Str);
+ }
+ if (Name == "UCASE") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ if (!Str) return nullptr;
+ return StrHandler->emitUCase(Str);
+ }
+ if (Name == "ASC") {
+ const TypeInfo *ArgType = getExprTypeInfo(ArgExprs[0].get());
+ if (ArgType && (ArgType->isUserKind() || ArgType->isC())) {
+ reportError("ASC expects a CHAR or STRING (got %s)", ArgType->Name.c_str());
+ return nullptr;
+ }
+ Value *ArgVal = emitExpr(ArgExprs[0].get());
+ if (!ArgVal) return nullptr;
+ Value *CharVal = nullptr;
+ if (ArgType && ArgType->isChar()) {
+ CharVal = coerceValueToType(ArgVal, resolveType("CHAR"));
+ } else {
+ CharVal = Builder->CreateLoad(Type::getInt8Ty(*TheContext), ArgVal, "char_load");
+ }
+ Value *AscVal = Builder->CreateZExt(CharVal, Type::getInt32Ty(*TheContext), "asc_val");
+ return coerceValueToType(AscVal, resolveType("INTEGER"));
+ }
+ if (Name == "CHR") {
+ Value *IntVal = emitCoercedExpr(ArgExprs[0].get(), resolveType("INTEGER"));
+ if (!IntVal) return nullptr;
+ Value *CharVal = Builder->CreateTrunc(IntVal, Type::getInt8Ty(*TheContext), "chr_val");
+ return coerceValueToType(CharVal, resolveType("STRING"));
+ }
+ if (Name == "IS_NUM") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ if (!Str) return nullptr;
+ return StrConvHandler->emitIsNum(Str);
+ }
+ if (Name == "NUM_TO_STR") {
+ const TypeInfo *ArgType = getExprTypeInfo(ArgExprs[0].get());
+ if (ArgType && (ArgType->isUserKind() || ArgType->isC())) {
+ reportError("NUM_TO_STR expects a number (got %s)", ArgType->Name.c_str());
+ return nullptr;
+ }
+ Value *NumV = emitExpr(ArgExprs[0].get());
+ if (!NumV) return nullptr;
+ bool IsReal = NumV->getType()->isDoubleTy();
+ if (NumV->getType()->isIntegerTy(8)) {
+ NumV = coerceValueToType(NumV, resolveType("INTEGER"));
+ }
+ return StrConvHandler->emitNumToStr(NumV, IsReal);
+ }
+ if (Name == "STR_TO_NUM") {
+ Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ if (!Str) return nullptr;
+ return StrConvHandler->emitStrToNum(Str, true);
+ }
+ if (Name == "EOF") {
+ if (isWholeArrayVar(ArgExprs[0].get())) {
+ reportError("Cannot use a whole array as the EOF filename");
+ return nullptr;
+ }
+ Value *FileName = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
+ if (!FileName) return nullptr;
+ return Files->emitEof(FileName, Line);
+ }
+
+ std::vector<Value*> Args;
+ if (!marshalCallArgs(Name, ArgExprs, Line, Args)) return nullptr;
+ return FuncGen->emitCall(Name, Args);
+}
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc
index a155f60..10bd3fa 100644
--- a/lib/CodeGen/FunctionGen.cc
+++ b/lib/CodeGen/FunctionGen.cc
@@ -243,14 +243,9 @@ static Value *GenerateCall(llvm::Module &Module,
return Exceptions.emitCall(CalleeF, Args, "calltmp");
}
-llvm::Value *FunctionGen::emitCallExpr(CallExprAST *Call, const std::vector<llvm::Value*> &Args) {
- 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) {
- const FuncSig *Sig = getSignature(Call->getCallee());
- GenerateCall(Module, Exceptions, Sig ? Sig->Name : Call->getCallee(), Args, HadError);
+llvm::Value *FunctionGen::emitCall(const std::string &Callee, const std::vector<llvm::Value*> &Args) {
+ const FuncSig *Sig = getSignature(Callee);
+ return GenerateCall(Module, Exceptions, Sig ? Sig->Name : Callee, Args, HadError);
}
void FunctionGen::emitReturn(ReturnStmtAST *Ret, llvm::Value *RetVal) {
diff --git a/lib/CodeGen/NativeTypeSystem.cc b/lib/CodeGen/NativeTypeSystem.cc
index a4fcee0..2dbbc49 100644
--- a/lib/CodeGen/NativeTypeSystem.cc
+++ b/lib/CodeGen/NativeTypeSystem.cc
@@ -106,6 +106,7 @@ void TypeSystem::registerBuiltins() {
defineCAlias("C_CHAR", "char", Err);
defineCAlias("C_STRING", "char*", Err);
defineCAlias("C_DOUBLE", "double", Err);
+ importCType("void*", Err);
}
diff --git a/lib/CodeGen/StatementGen.cc b/lib/CodeGen/StatementGen.cc
index 2c80437..b648ec6 100644
--- a/lib/CodeGen/StatementGen.cc
+++ b/lib/CodeGen/StatementGen.cc
@@ -55,9 +55,7 @@ void CodeGen::emitStmt(StmtAST *Stmt) {
}
if (auto *Call = dynamic_cast<CallStmtAST*>(Stmt)) {
- std::vector<Value*> Args;
- if (!marshalCallArgs(Call->getCallee(), Call->getArgs(), Call->getLine(), Args)) return;
- FuncGen->emitCallStmt(Call, Args);
+ emitCall(Call->getCallee(), Call->getArgs(), Call->getLine());
return;
}