aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-20 11:57:16 +0000
committer_ov4 <ov4@ov4.org>2026-10-20 11:57:16 +0000
commit62b605c6c0ea13e9763c0a0115464007b13a8831 (patch)
tree53c27965f5a365682e0d79fd96e25b228ecb9dca /lib/CodeGen/CodeGen.cc
parentbfe2e75d7e3b372e55369677028429990c49bc54 (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/CodeGen.cc')
-rw-r--r--lib/CodeGen/CodeGen.cc24
1 files changed, 12 insertions, 12 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index 49fc7b1..30b6131 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -59,8 +59,6 @@ CodeGen::CodeGen() {
ArithHandler = std::make_unique<ArithmeticHandler>(*TheContext, *Builder, HadError,
*RuntimeChecker);
- StrHandler = std::make_unique<StringHandler>(*TheContext, *Builder, *TheModule);
- StrConvHandler = std::make_unique<StringConversionHandler>(*TheContext, *Builder, *TheModule);
Files = std::make_unique<FileHandler>(*TheContext, *Builder, *TheModule, *RuntimeChecker,
*Exceptions);
@@ -92,11 +90,6 @@ void CodeGen::SetupExternalFunctions() {
FunctionType *ScanfType = FunctionType::get(Type::getInt32Ty(*TheContext), PrintfArgs, true);
ScanfFunc = TheModule->getOrInsertFunction("scanf", ScanfType);
- FunctionType *MallocType = FunctionType::get(PointerType::getUnqual(*TheContext),
- {Type::getInt64Ty(*TheContext)},
- false);
- MallocFunc = TheModule->getOrInsertFunction("malloc", MallocType);
-
PrintfFormatStr = Builder->CreateGlobalString("%lld\n", "fmt_nl", 0, TheModule.get());
PrintfFloatFormatStr = Builder->CreateGlobalString("%f\n", "fmt_flt", 0, TheModule.get());
PrintfStringFormatStr = Builder->CreateGlobalString("%s\n", "fmt_str", 0, TheModule.get());
@@ -104,7 +97,6 @@ void CodeGen::SetupExternalFunctions() {
ScanfFormatStr = Builder->CreateGlobalString("%lld", "fmt_in", 0, TheModule.get());
ScanfFloatFormatStr = Builder->CreateGlobalString("%lf", "fmt_in_flt", 0, TheModule.get());
- ScanfStringFormatStr = Builder->CreateGlobalString("%s", "fmt_in_str", 0, TheModule.get());
TrueStr = Builder->CreateGlobalString("TRUE", "str_true", 0, TheModule.get());
FalseStr = Builder->CreateGlobalString("FALSE", "str_false", 0, TheModule.get());
@@ -192,19 +184,25 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
});
FuncGen->setVisibility([this](size_t Owner) { return isVisible(Owner); });
- struct Definition { size_t Unit; bool IsFunction; bool IsOverload; bool IsExtern; };
+ struct Definition { size_t Unit; bool IsFunction; bool IsOverload; bool IsExtern; int Line; };
IdentifierMap<Definition> Definitions;
std::optional<size_t> CodeUnit;
FunctionDefAST *Entry = nullptr;
size_t EntryUnit = 0;
auto Reserve = [&](const std::string &Name, bool IsFunction = false, bool IsOverload = false,
bool IsExtern = false) {
- auto [It, Added] = Definitions.emplace(Name, Definition{CurrentUnit, IsFunction, IsOverload, IsExtern});
+ auto [It, Added] = Definitions.emplace(Name, Definition{CurrentUnit, IsFunction, IsOverload, IsExtern, DiagnosticLine});
bool Compatible = (IsFunction && IsOverload && It->second.IsFunction && It->second.IsOverload) ||
(IsExtern && It->second.IsExtern);
- if (!Added && It->second.Unit != CurrentUnit && !Compatible)
+ if (!Added && It->second.Unit != CurrentUnit && !Compatible) {
+ // Default library units follow user inputs; point at the user's conflicting definition.
+ bool UserConflict = Sources[CurrentUnit].IsLibrary && !Sources[It->second.Unit].IsLibrary;
+ SaveAndRestore<int> Location(DiagnosticLine, UserConflict ? It->second.Line : DiagnosticLine);
+ SaveAndRestore<std::string> Source(DiagnosticSource,
+ UserConflict ? Sources[It->second.Unit].Path : DiagnosticSource);
reportError("Duplicate definition %s in %s and %s", Name.c_str(),
Sources[It->second.Unit].Path.c_str(), Sources[CurrentUnit].Path.c_str());
+ }
};
for (size_t I = 0; I < Sources.size(); ++I) {
selectUnit(I);
@@ -453,7 +451,9 @@ bool CodeGen::marshalCallArgs(const FuncSig &Signature,
reportError("Unknown variable %s in BYREF call", Var->getName().c_str());
return false;
}
- if (!requireWritable(*Info, Var->getName())) return false;
+ const TypeInfo *ParameterType = resolveType(TypeName);
+ if (!(InternalBinding && ParameterType && ParameterType->isString()) &&
+ !requireWritable(*Info, Var->getName())) return false;
// BYREF aliases the storage, so the types must match exactly.
if (!Types->sameType(Info->TypeName, TypeName)) {
reportError("BYREF argument %s to %s must be of type %s (got %s)",