aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGen.cc
diff options
context:
space:
mode:
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)",