aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/FunctionGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-16 13:21:05 +0000
committer_ov4 <ov4@ov4.org>2026-10-16 13:21:05 +0000
commite44bdc6a2a0cf624b08046ecc7e5c5d5d9d2d66c (patch)
treef5276cc0dd2f34e4d30a58f80223912265a1c5a0 /lib/CodeGen/FunctionGen.cc
parente1e789ac0249149a4aa1671f5f9260d488cb617a (diff)
fix(compiler): correct CIE semantics and diagnostic locations
Use standard WHILE headers and default-public class fields, resolve pseudocode identifiers without case sensitivity, and check signed i64 literal boundaries before conversion. Preserve source locations across recursive emission and function diagnostics. Add 22 regression cases and update compiler examples and documentation. Validated all 69 CTest entries with the original Linux Actions seed and verified the release package's embedded, native and IR output paths.
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) {