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/ConstantGen.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/ConstantGen.cc')
| -rw-r--r-- | lib/CodeGen/ConstantGen.cc | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/CodeGen/ConstantGen.cc b/lib/CodeGen/ConstantGen.cc index fc5d178..374b423 100644 --- a/lib/CodeGen/ConstantGen.cc +++ b/lib/CodeGen/ConstantGen.cc @@ -39,7 +39,7 @@ bool CodeGen::prepareSymbolDeclaration(const std::string &Name, bool IsConstant) reportError("Declaration of %s conflicts with an existing declaration in this scope", Name.c_str()); return false; } - if (IsConstant || It->second.ConstantValue || It->second.IsGlobal) Scope.Saved.emplace(Name, It->second); + if (IsConstant || It->second.isConstant() || It->second.IsGlobal) Scope.Saved.emplace(Name, It->second); } else if (IsConstant) { Scope.Saved.emplace(Name, std::nullopt); } @@ -48,7 +48,7 @@ bool CodeGen::prepareSymbolDeclaration(const std::string &Name, bool IsConstant) } bool CodeGen::requireWritable(const SymbolInfo &Info, const std::string &Name) { - if (!Info.ConstantValue) return true; + if (!Info.isConstant()) return true; reportError("Constant %s is not a writable location", Name.c_str()); return false; } @@ -65,8 +65,31 @@ void CodeGen::emitConstantStmt(ConstantStmtAST *Stmt) { return; } if (!prepareSymbolDeclaration(Name, true)) return; + auto Existing = StringConstants.find(Stmt); + if (Existing != StringConstants.end()) { + Symbols[Name] = Existing->second; + return; + } const TypeInfo *Type = getExprTypeInfo(Stmt->getValue()); Value *Val = emitExpr(Stmt->getValue()); + if (Type && Type->isString() && Val) { + Value *Storage; + bool TopLevel = ConstantScopes.back().ID == 0; + if (TopLevel) { + Storage = new GlobalVariable(*TheModule, Type->LLVMType, false, + GlobalValue::InternalLinkage, Types->getZeroValue(Type->Name), "__cps_constant." + Name); + } else { + Storage = CreateEntryBlockAlloca(Builder->GetInsertBlock()->getParent(), Type->LLVMType, Name); + } + size_t Lifetime = registerStackObject(Storage, Type->Name, DiagnosticLine); + Builder->CreateStore(Val, Storage); + activateStackObject(Lifetime); + SymbolInfo Info{Storage, Type->Name, false, nullptr, ConstantScopes.back().ID}; + Info.ReadOnly = true; + Symbols[Name] = Info; + if (TopLevel) StringConstants.emplace(Stmt, Info); + return; + } auto *Literal = dyn_cast_or_null<Constant>(Val); if (!Type || !Literal) { reportError("CONSTANT initializer must be a literal"); |
