From 0fef2986daa2945c9e3d050c0f750d56792b30bd Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sun, 26 Jul 2026 17:13:15 +0000 Subject: refactor: groundwork for TYPE — sizeof constants, string guard, array scoping MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Element sizes now flow as target-folded null-GEP sizeof constants (TypeSystem::getSizeOfConstant); the module has no DataLayout string, so host-side size math would diverge from the backend on padded structs. - Extract the triplicated STRING null->"" select into CodeGen::emitStringNullGuard. - Scope ArrayTable per function via ArrayHandler::exchangeTable, mirroring the Symbols save/clear/restore discipline. - Promote checked element addressing to public ArrayHandler::emitElementAddress for the upcoming lvalue layer. Co-Authored-By: Claude Fable 5 --- lib/CodeGen/ArrayHandler.cc | 51 +++++++++++++++++++++++++++++++-------------- lib/CodeGen/CodeGen.cc | 25 ++++++++++++---------- lib/CodeGen/TypeSystem.cc | 4 ++++ 3 files changed, 53 insertions(+), 27 deletions(-) (limited to 'lib/CodeGen') diff --git a/lib/CodeGen/ArrayHandler.cc b/lib/CodeGen/ArrayHandler.cc index 83204a7..7977563 100644 --- a/lib/CodeGen/ArrayHandler.cc +++ b/lib/CodeGen/ArrayHandler.cc @@ -117,14 +117,13 @@ void ArrayHandler::emitArrayDeclare(ArrayDeclareStmtAST *Stmt, CodeGen &CG) { Meta.Rank = Rank; Meta.ElementTypeName = ElemInfo->Name; Meta.ElementType = ElemInfo->LLVMType; - Meta.ElementSize = ElemInfo->ElementSize; + Meta.ElementSizeC = Types.getSizeOfConstant(ElemInfo->LLVMType); Meta.LowerBounds = std::move(Lows); Meta.UpperBounds = std::move(Highs); Meta.Multipliers = std::move(Multipliers); ArrayTable[Name] = Meta; - Value *ElemSize = ConstantInt::get(*TheContext, APInt(64, ElemInfo->ElementSize)); - Value *TotalBytes = Builder->CreateMul(TotalElements, ElemSize, Name + "_total_bytes"); + Value *TotalBytes = Builder->CreateMul(TotalElements, Meta.ElementSizeC, Name + "_total_bytes"); CallInst *Ptr = Builder->CreateCall(MallocFunc, TotalBytes, Name + "_malloc"); FunctionType *MemsetType = FunctionType::get(PointerType::getUnqual(*TheContext), @@ -179,10 +178,7 @@ Value *ArrayHandler::loadElement(const std::string &Name, Value *Offset, CodeGen Value *Val = Builder->CreateLoad(Meta->ElementType, ElemPtr, Name + "_elem"); if (Meta->ElementTypeName == "STRING") { - Value *IsNull = Builder->CreateICmpEQ(Val, - ConstantPointerNull::get(cast(Meta->ElementType)), - Name + "_str_is_null"); - Val = Builder->CreateSelect(IsNull, CG.EmptyStringStr, Val, Name + "_safe_str"); + Val = CG.emitStringNullGuard(Val); } return Val; } @@ -198,22 +194,45 @@ Value *ArrayHandler::emitArrayAccess(ArrayAccessExprAST *Expr, CodeGen &CG) { } void ArrayHandler::emitArrayAssign(ArrayAssignStmtAST *Stmt, CodeGen &CG) { - std::string Name = Stmt->getName(); - std::vector Indices; - if (!emitCheckedIndices(Name, Stmt->getIndices(), Stmt->getLine(), true, CG, Indices)) - return; + std::string ElemTypeName; + Value *ElemPtr = emitElementAddress(Stmt->getName(), Stmt->getIndices(), + Stmt->getLine(), CG, ElemTypeName); + if (!ElemPtr) return; - const ArrayMetadata *Meta = getMetadata(Name); - const TypeInfo *ElemInfo = Types.resolve(Meta->ElementTypeName); Value *Val = CG.emitExpr(Stmt->getExpr()); - Val = CG.coerceValueToType(Val, ElemInfo); + Val = CG.coerceValueToType(Val, Types.resolve(ElemTypeName)); if (!Val) return; + Builder->CreateStore(Val, ElemPtr); +} + +Value *ArrayHandler::emitElementAddress(const std::string &Name, + const std::vector> &IndexExprs, + int Line, + CodeGen &CG, + std::string &ElemTypeNameOut) { + std::vector Indices; + if (!emitCheckedIndices(Name, IndexExprs, Line, true, CG, Indices)) + return nullptr; + Value *Offset = computeFlatIndex(Name, Indices); Value *ElemPtr = getElementPointer(Name, Offset); - if (!ElemPtr) return; + if (!ElemPtr) return nullptr; - Builder->CreateStore(Val, ElemPtr); + ElemTypeNameOut = getMetadata(Name)->ElementTypeName; + return ElemPtr; +} + +Value *ArrayHandler::emitElementAddress(ArrayAccessExprAST *Expr, + CodeGen &CG, + std::string &ElemTypeNameOut) { + return emitElementAddress(Expr->getName(), Expr->getIndices(), Expr->getLine(), + CG, ElemTypeNameOut); +} + +std::map ArrayHandler::exchangeTable(std::map NewTable) { + std::swap(ArrayTable, NewTable); + return NewTable; } bool ArrayHandler::tryEmitArrayOutput(ExprAST *Expr, CodeGen &CG) { diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc index ae82914..4b9ebfb 100644 --- a/lib/CodeGen/CodeGen.cc +++ b/lib/CodeGen/CodeGen.cc @@ -363,6 +363,14 @@ void CodeGen::emitDeclareStmt(DeclareStmtAST *Stmt) { registerSymbol(Stmt->getName(), Alloca, Info->Name, false); } +Value *CodeGen::emitStringNullGuard(Value *StrVal) { + if (!StrVal || !StrVal->getType()->isPointerTy()) return StrVal; + Value *IsNull = Builder->CreateICmpEQ(StrVal, + ConstantPointerNull::get(cast(StrVal->getType())), + "str_is_null"); + return Builder->CreateSelect(IsNull, EmptyStringStr, StrVal, "safe_str"); +} + void CodeGen::emitOutputValue(Value *Val, const TypeInfo *Info, bool AppendNewline) { if (!Val || !Info) return; if (!Info->Printable && Info->Kind == TypeKind::Custom) { @@ -387,13 +395,7 @@ void CodeGen::emitOutputValue(Value *Val, const TypeInfo *Info, bool AppendNewli Args.push_back(Fmt); Args.push_back(Builder->CreateSelect(BoolVal, TrueStr, FalseStr)); } else if (Info->isString()) { - Value *StrVal = Val; - if (StrVal->getType()->isPointerTy()) { - Value *IsNull = Builder->CreateICmpEQ(StrVal, - ConstantPointerNull::get(cast(StrVal->getType())), - "str_is_null"); - StrVal = Builder->CreateSelect(IsNull, EmptyStringStr, StrVal, "safe_str"); - } + Value *StrVal = emitStringNullGuard(Val); Fmt = AppendNewline ? PrintfStringFormatStr : Builder->CreateGlobalStringPtr("%s", "fmt_str_inline", 0, TheModule.get()); @@ -491,10 +493,7 @@ Value *CodeGen::emitExpr(ExprAST *Expr) { Value *Loaded = Builder->CreateLoad(TypeInfo->LLVMType, Info->Storage, Var->getName().c_str()); if (TypeInfo->isString()) { - Value *IsNull = Builder->CreateICmpEQ(Loaded, - ConstantPointerNull::get(cast(Loaded->getType())), - "str_is_null"); - Loaded = Builder->CreateSelect(IsNull, EmptyStringStr, Loaded, "safe_var_str"); + Loaded = emitStringNullGuard(Loaded); } return Loaded; } @@ -836,11 +835,15 @@ void CodeGen::emitStmt(StmtAST *Stmt) { if (auto *FuncDef = dynamic_cast(Stmt)) { BasicBlock *SavedBlock = Builder->GetInsertBlock(); + // Function bodies get a fresh array scope (metadata SSA values belong + // to the emitting function), mirroring FunctionGen's Symbols handling. + auto SavedArrays = Arrays->exchangeTable({}); FuncGen->emitFunctionDef(FuncDef, [this](StmtAST *S) { this->emitStmt(S); }); + Arrays->exchangeTable(std::move(SavedArrays)); if (SavedBlock) Builder->SetInsertPoint(SavedBlock); return; } diff --git a/lib/CodeGen/TypeSystem.cc b/lib/CodeGen/TypeSystem.cc index 59dcc18..830ce25 100644 --- a/lib/CodeGen/TypeSystem.cc +++ b/lib/CodeGen/TypeSystem.cc @@ -129,6 +129,10 @@ uint64_t TypeSystem::getElementSize(const std::string &TypeName) const { return Info ? Info->ElementSize : 0; } +Constant *TypeSystem::getSizeOfConstant(Type *Ty) const { + return ConstantExpr::getSizeOf(Ty); +} + Constant *TypeSystem::getZeroValue(const std::string &TypeName) const { const TypeInfo *Info = resolve(TypeName); if (!Info || !Info->LLVMType || Info->LLVMType->isVoidTy()) { -- cgit v1.3.1-4-g156e