From 39661855c0816ac248be437704c76f58359cb5f0 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sat, 17 Oct 2026 06:52:23 +0000 Subject: feat(classes): construct declared objects and nested fields and arrays Co-Authored-By: Claude Opus 5.5 --- lib/CodeGen/ConstructorGen.cc | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 lib/CodeGen/ConstructorGen.cc (limited to 'lib/CodeGen/ConstructorGen.cc') diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc new file mode 100644 index 0000000..0d4d732 --- /dev/null +++ b/lib/CodeGen/ConstructorGen.cc @@ -0,0 +1,39 @@ +#include "cps/CodeGen.h" + +using namespace llvm; +using namespace cps; + +bool CodeGen::typeNeedsConstruction(const std::string &TypeName) const { + if (findMethod(TypeName, "NEW")) return true; + const TypeInfo *Info = resolveType(TypeName); + if (Info && Info->asRecord()) { + for (const auto &[Name, Field] : Info->Record.Fields) + if (typeNeedsConstruction(Field.TypeName)) return true; + } + return false; +} + +bool CodeGen::emitConstruct(const std::string &TypeName, Value *Addr, + const std::vector> &Args, int Line) { + SaveAndRestore Location(DiagnosticLine, Line); + const TypeInfo *Info = resolveType(TypeName); + if (!Info) return false; + if (Info->asRecord()) { + for (const auto &[Name, Field] : Info->Record.Fields) { + if (!typeNeedsConstruction(Field.TypeName)) continue; + Value *FieldAddr = Builder->CreateStructGEP(Info->LLVMType, Addr, Field.Index); + if (!emitDefaultConstruct(Field.TypeName, FieldAddr, Line)) return false; + } + } + if (findMethod(TypeName, "NEW")) + return emitMethodCall(TypeName, Addr, "NEW", Args, Line) != nullptr; + if (!Args.empty()) { + reportError("Type %s has no constructor NEW but arguments were supplied", TypeName.c_str()); + return false; + } + return true; +} + +bool CodeGen::emitDefaultConstruct(const std::string &TypeName, Value *Addr, int Line) { + return emitConstruct(TypeName, Addr, {}, Line); +} -- cgit v1.3.1-4-g156e