aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ExpressionGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 05:30:57 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 05:30:57 +0000
commit4dd85fd6ecd9a67e5c2b68380873e6e114714355 (patch)
treeb9dad1d0845f4c2ae7e6efed171fbee40ccd1f31 /lib/CodeGen/ExpressionGen.cc
parente782898e420c7f2abd83b97c160194d0e70598dd (diff)
feat(memory): add tracked MALLOC and FREE builtins
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ExpressionGen.cc')
-rw-r--r--lib/CodeGen/ExpressionGen.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/CodeGen/ExpressionGen.cc b/lib/CodeGen/ExpressionGen.cc
index fa2581f..0a24c8d 100644
--- a/lib/CodeGen/ExpressionGen.cc
+++ b/lib/CodeGen/ExpressionGen.cc
@@ -1,9 +1,12 @@
#include "cps/CodeGen.h"
#include "cps/ArrayHandler.h"
#include "cps/FileHandler.h"
+#include "cps/MemoryHandler.h"
#include "cps/Lexer.h"
#include "cps/TypeAST.h"
#include "Builtins.h"
+#include <climits>
+#include <cstddef>
using namespace llvm;
using namespace cps;
@@ -184,6 +187,16 @@ Value *CodeGen::emitCall(const std::string &Callee,
return nullptr;
}
}
+ if (Name == "MALLOC") {
+ Value *Size = emitAllocationSize(ArgExprs[0].get());
+ if (!Size) return nullptr;
+ return Memory->emitAllocate(Size, Line);
+ }
+ if (Name == "FREE") {
+ Value *Address = emitCoercedExpr(ArgExprs[0].get(), resolveType("C_TYPE(\"void*\")"));
+ if (!Address) return nullptr;
+ return Memory->emitRelease(Address, Line);
+ }
if (Name == "LENGTH") {
Value *Str = emitCoercedExpr(ArgExprs[0].get(), resolveType("STRING"));
if (!Str) return nullptr;
@@ -279,3 +292,19 @@ Value *CodeGen::emitCall(const std::string &Callee,
if (!marshalCallArgs(Name, ArgExprs, Line, Args)) return nullptr;
return FuncGen->emitCall(Name, Args);
}
+
+Value *CodeGen::emitAllocationSize(ExprAST *Expr) {
+ SaveAndRestore<int> Location(DiagnosticLine, Expr->getLine() ? Expr->getLine() : DiagnosticLine);
+ const TypeInfo *Info = getExprTypeInfo(Expr);
+ if (isWholeArrayVar(Expr) || !Info ||
+ !(Info->Kind == TypeKind::Integer ||
+ (Info->Kind == TypeKind::CScalar && Info->isIntegral()))) {
+ reportError("Allocation size must be INTEGER or a C integer");
+ return nullptr;
+ }
+ Value *Size = emitExpr(Expr);
+ if (!Size) return nullptr;
+ auto *SizeTy = Type::getIntNTy(*TheContext, sizeof(std::size_t) * CHAR_BIT);
+ return Builder->CreateIntCast(Size, SizeTy,
+ Info->Kind == TypeKind::Integer || Info->CSigned, "allocation_size");
+}