diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-20 11:57:16 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-20 11:57:16 +0000 |
| commit | 62b605c6c0ea13e9763c0a0115464007b13a8831 (patch) | |
| tree | 53c27965f5a365682e0d79fd96e25b228ecb9dca /lib/CodeGen/ConstructorGen.cc | |
| parent | bfe2e75d7e3b372e55369677028429990c49bc54 (diff) | |
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 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/ConstructorGen.cc')
| -rw-r--r-- | lib/CodeGen/ConstructorGen.cc | 37 |
1 files changed, 34 insertions, 3 deletions
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<size_t> &Objects) { Value *CodeGen::emitOwnedValue(ExprAST *Expr, const TypeInfo *Type, std::vector<size_t> &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<VariableExprAST *>(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<size_t> 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<size_t> 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); } |
