From 62b605c6c0ea13e9763c0a0115464007b13a8831 Mon Sep 17 00:00:00 2001 From: _ov4 Date: Tue, 20 Oct 2026 11:57:16 +0000 Subject: refactor(strings): replace compiler builtins with the STRING library Construct literals as STRING values and route string operations through ordinary library functions and operators. Preserve value ownership in records, arrays, constants and file I/O. Co-Authored-By: Claude Opus 5.5 --- lib/CodeGen/ConstructorGen.cc | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'lib/CodeGen/ConstructorGen.cc') diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc index 9fc762c..ec97fca 100644 --- a/lib/CodeGen/ConstructorGen.cc +++ b/lib/CodeGen/ConstructorGen.cc @@ -20,13 +20,17 @@ void CodeGen::transferObjects(const std::vector &Objects) { Value *CodeGen::emitOwnedValue(ExprAST *Expr, const TypeInfo *Type, std::vector &Transfers) { - if (!Type || !Type->IsClass) return emitCoercedExpr(Expr, Type); + if (!Type || (!Type->IsClass && !containsString(Type))) return emitCoercedExpr(Expr, Type); const TypeInfo *Source = getExprTypeInfo(Expr); if (!Source || !Source->sameType(Type)) return emitCoercedExpr(Expr, Type); Value *Value = nullptr; if (isObjectLValue(Expr)) { LValueInfo LV; - if (!emitLValue(Expr, LV)) return nullptr; + const auto *Var = dynamic_cast(Expr); + const auto *Symbol = Var ? getSymbolInfo(Var->getName()) : nullptr; + if (Symbol && Symbol->isConstant() && Symbol->Storage) { + LV = {symbolAddress(*Symbol), Symbol->TypeName}; + } else if (!emitLValue(Expr, LV)) return nullptr; return copyClassValue(Type, LV.Addr, Transfers); } Value = emitCoercedExpr(Expr, Type); @@ -44,7 +48,25 @@ Value *CodeGen::copyClassValue(const TypeInfo *Type, Value *Address, if (Sig->IsOverload && Sig->Params.size() == 1 && Sig->Params[0].IsByRef && !Sig->Params[0].IsArray && Type->sameType(resolveType(Sig->Params[0].TypeName))) Copy = Sig; - if (!Copy) return Builder->CreateLoad(Type->LLVMType, Address); + if (!Copy) { + if (!containsString(Type) || Type->isString()) + return Builder->CreateLoad(Type->LLVMType, Address); + Value *Result = UndefValue::get(Type->LLVMType); + std::vector Fields; + for (const auto &[Name, Field] : Type->Record.Fields) { + const auto *FieldType = resolveType(Field.TypeName); + Value *Source = Builder->CreateStructGEP(Type->LLVMType, Address, Field.Index); + Value *Value = containsString(FieldType) + ? copyClassValue(FieldType, Source, Fields) + : Builder->CreateLoad(FieldType->LLVMType, Source); + if (!Value) return nullptr; + Result = Builder->CreateInsertValue(Result, Value, {Field.Index}); + } + auto *Storage = materializeOperatorReceiver(Result, Type); + transferObjects(Fields); + if (typeNeedsDestruction(Type->Name)) Transfers.push_back(StackObjects.size() - 1); + return Builder->CreateLoad(Type->LLVMType, Storage); + } if (!checkOperatorAccess(*Copy)) return nullptr; auto *Storage = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), Type->LLVMType, "copy_object"); @@ -156,6 +178,15 @@ void CodeGen::emitAssignment(const LValueInfo &Target, ExprAST *Expr, const Symb return; } } + if (Info && containsString(Info)) { + std::vector Transfers; + Value *Val = emitOwnedValue(Expr, Info, Transfers); + if (!Val) return; + if (!emitDestroy(Info->Name, Target.Addr, DiagnosticLine)) return; + Builder->CreateStore(Val, Target.Addr); + transferObjects(Transfers); + return; + } Value *Val = emitCoercedExpr(Expr, Info); if (Val) Builder->CreateStore(Val, Target.Addr); } -- cgit v1.3.1-4-g156e