aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/ConstructorGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-17 06:52:23 +0000
committer_ov4 <ov4@ov4.org>2026-10-17 06:52:23 +0000
commit39661855c0816ac248be437704c76f58359cb5f0 (patch)
tree202b014805e40208e3adb861f4a97d31770f13e6 /lib/CodeGen/ConstructorGen.cc
parentc89477d615fb0ce4d89786ef848ffe6aca1da088 (diff)
feat(classes): construct declared objects and nested fields and arrays
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ConstructorGen.cc')
-rw-r--r--lib/CodeGen/ConstructorGen.cc39
1 files changed, 39 insertions, 0 deletions
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<std::unique_ptr<ExprAST>> &Args, int Line) {
+ SaveAndRestore<int> 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);
+}