diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-17 06:54:32 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-17 06:54:32 +0000 |
| commit | 74b6d06711afd3efbbc47436f1491900994313f3 (patch) | |
| tree | b9050214b147cd2b1b54fd27e75d669bf6146e48 /lib/CodeGen/ConstructorGen.cc | |
| parent | 39661855c0816ac248be437704c76f58359cb5f0 (diff) | |
feat(classes): allocate objects with NEW and rebind named class variables
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ConstructorGen.cc')
| -rw-r--r-- | lib/CodeGen/ConstructorGen.cc | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc index 0d4d732..f726590 100644 --- a/lib/CodeGen/ConstructorGen.cc +++ b/lib/CodeGen/ConstructorGen.cc @@ -1,4 +1,8 @@ #include "cps/CodeGen.h" +#include "cps/MemoryHandler.h" +#include "cps/TypeAST.h" +#include <climits> +#include <cstddef> using namespace llvm; using namespace cps; @@ -37,3 +41,38 @@ bool CodeGen::emitConstruct(const std::string &TypeName, Value *Addr, bool CodeGen::emitDefaultConstruct(const std::string &TypeName, Value *Addr, int Line) { return emitConstruct(TypeName, Addr, {}, Line); } + +Value *CodeGen::symbolAddress(const SymbolInfo &Info) { + if (!Info.IsReference) return Info.Storage; + return Builder->CreateLoad(PointerType::getUnqual(*TheContext), Info.Storage, "object_address"); +} + +void CodeGen::emitAssignment(const LValueInfo &Target, ExprAST *Expr, const SymbolInfo *Symbol) { + const TypeInfo *Info = resolveType(Target.TypeName); + if (auto *New = dynamic_cast<NewExprAST*>(Expr)) { + SaveAndRestore<int> Location(DiagnosticLine, New->getLine()); + const TypeInfo *Class = resolveType(New->getClassName()); + if (!Class || !Class->IsClass) { + reportError("NEW requires a class type: %s", New->getClassName().c_str()); + return; + } + if (!Info || !Info->sameType(Class)) { + reportError("NEW target must have type %s", Class->Name.c_str()); + return; + } + Value *Size = Builder->CreateIntCast(Types->getSizeOfConstant(Class->LLVMType), + Type::getIntNTy(*TheContext, sizeof(std::size_t) * CHAR_BIT), false); + Value *Object = Memory->emitAllocate(Size, New->getLine()); + Builder->CreateStore(Types->getZeroValue(Class->Name), Object); + if (!emitConstruct(Class->Name, Object, New->getArgs(), New->getLine())) return; + if (Symbol && Symbol->IsReference) { + Builder->CreateStore(Object, Symbol->Storage); + } else { + Value *Val = Builder->CreateLoad(Class->LLVMType, Object); + Builder->CreateStore(Val, Target.Addr); + } + return; + } + Value *Val = emitCoercedExpr(Expr, Info); + if (Val) Builder->CreateStore(Val, Target.Addr); +} |
