diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-17 06:52:23 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-17 06:52:23 +0000 |
| commit | 39661855c0816ac248be437704c76f58359cb5f0 (patch) | |
| tree | 202b014805e40208e3adb861f4a97d31770f13e6 /lib/CodeGen/ConstructorGen.cc | |
| parent | c89477d615fb0ce4d89786ef848ffe6aca1da088 (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.cc | 39 |
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); +} |
