aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CodeGen.cc5
-rw-r--r--lib/CodeGen/FileHandler.cc10
-rw-r--r--lib/CodeGen/FunctionGen.cc1
-rw-r--r--lib/CodeGen/MemoryHandler.cc8
-rw-r--r--lib/CodeGen/RuntimeCheck.cc17
5 files changed, 29 insertions, 12 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index f7c4de6..c9d8c1a 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -161,6 +161,11 @@ void CodeGen::selectUnit(size_t Unit) {
CurrentUnit = Unit;
DiagnosticSource = Units->size() > 1 ? (*Units)[Unit].Path : "";
FuncGen->setCurrentUnit(Unit, (*Units)[Unit].Path);
+ RuntimeChecker->setLibraryMode((*Units)[Unit].IsLibrary);
+ FuncGen->setCallHook([this](const FuncSig &Sig) {
+ if (!(*Units)[CurrentUnit].IsLibrary && (*Units)[Sig.OwnerUnit].IsLibrary)
+ RuntimeChecker->setUserLine(DiagnosticLine);
+ });
}
void CodeGen::importSymbols() {
diff --git a/lib/CodeGen/FileHandler.cc b/lib/CodeGen/FileHandler.cc
index a4d7561..a7879e0 100644
--- a/lib/CodeGen/FileHandler.cc
+++ b/lib/CodeGen/FileHandler.cc
@@ -246,31 +246,31 @@ void FileHandler::emitOpen(Value *NameStr, FileMode Mode, int Line) {
ensureRuntime();
Exceptions.emitCall(OpenFn, {NameStr,
ConstantInt::get(Type::getInt8Ty(Context), uint8_t(Mode)),
- ConstantInt::get(Context, APInt(32, Line))});
+ Checker.lineValue(Line)});
}
Value *FileHandler::emitRead(Value *NameStr, int Line) {
if (!NameStr) return nullptr;
ensureRuntime();
- return Exceptions.emitCall(ReadFn, {NameStr, ConstantInt::get(Context, APInt(32, Line))},
+ return Exceptions.emitCall(ReadFn, {NameStr, Checker.lineValue(Line)},
"file_line");
}
void FileHandler::emitWrite(Value *NameStr, Value *DataStr, int Line) {
if (!NameStr || !DataStr) return;
ensureRuntime();
- Exceptions.emitCall(WriteFn, {NameStr, DataStr, ConstantInt::get(Context, APInt(32, Line))});
+ Exceptions.emitCall(WriteFn, {NameStr, DataStr, Checker.lineValue(Line)});
}
void FileHandler::emitClose(Value *NameStr, int Line) {
if (!NameStr) return;
ensureRuntime();
- Exceptions.emitCall(CloseFn, {NameStr, ConstantInt::get(Context, APInt(32, Line))});
+ Exceptions.emitCall(CloseFn, {NameStr, Checker.lineValue(Line)});
}
Value *FileHandler::emitEof(Value *NameStr, int Line) {
if (!NameStr) return nullptr;
ensureRuntime();
- return Exceptions.emitCall(EofFn, {NameStr, ConstantInt::get(Context, APInt(32, Line))},
+ return Exceptions.emitCall(EofFn, {NameStr, Checker.lineValue(Line)},
"file_eof");
}
diff --git a/lib/CodeGen/FunctionGen.cc b/lib/CodeGen/FunctionGen.cc
index bccf397..a0d0e32 100644
--- a/lib/CodeGen/FunctionGen.cc
+++ b/lib/CodeGen/FunctionGen.cc
@@ -451,6 +451,7 @@ llvm::Value *FunctionGen::emitCall(const std::string &Callee, const std::vector<
}
llvm::Value *FunctionGen::emitCall(const FuncSig &Sig, const std::vector<llvm::Value*> &Args) {
+ if (BeforeCall) BeforeCall(Sig);
if (!Sig.IsExternal) return emitCall(Sig.LinkName, Args);
FunctionCallee Callee(Sig.ExternType, Module.getNamedValue(Sig.LinkName));
Value *Call = Sig.ExternType->getReturnType()->isVoidTy()
diff --git a/lib/CodeGen/MemoryHandler.cc b/lib/CodeGen/MemoryHandler.cc
index fa25eb9..7cb62b3 100644
--- a/lib/CodeGen/MemoryHandler.cc
+++ b/lib/CodeGen/MemoryHandler.cc
@@ -114,12 +114,12 @@ void MemoryHandler::buildRelease() {
Value *MemoryHandler::emitAllocate(Value *Size, int Line) {
ensureRuntime();
- return Exceptions.emitCall(AllocateFn, {Size, Builder.getInt32(Line)}, "allocated");
+ return Exceptions.emitCall(AllocateFn, {Size, Checker.lineValue(Line)}, "allocated");
}
Value *MemoryHandler::emitRelease(Value *Address, int Line) {
ensureRuntime();
- return Exceptions.emitCall(ReleaseFn, {Address, Builder.getInt32(Line)}, "released");
+ return Exceptions.emitCall(ReleaseFn, {Address, Checker.lineValue(Line)}, "released");
}
void MemoryHandler::buildResize() {
@@ -150,10 +150,10 @@ void MemoryHandler::buildResize() {
Value *MemoryHandler::emitResize(Value *Address, Value *Size, int Line) {
ensureRuntime();
- return Exceptions.emitCall(ResizeFn, {Address, Size, Builder.getInt32(Line)}, "resized");
+ return Exceptions.emitCall(ResizeFn, {Address, Size, Checker.lineValue(Line)}, "resized");
}
void MemoryHandler::emitValidate(Value *Address, int Line) {
ensureRuntime();
- Exceptions.emitCall(FindFn, {Address, Builder.getInt32(Line)});
+ Exceptions.emitCall(FindFn, {Address, Checker.lineValue(Line)});
}
diff --git a/lib/CodeGen/RuntimeCheck.cc b/lib/CodeGen/RuntimeCheck.cc
index 0515f1e..4cee16f 100644
--- a/lib/CodeGen/RuntimeCheck.cc
+++ b/lib/CodeGen/RuntimeCheck.cc
@@ -11,9 +11,20 @@ using namespace cps;
RuntimeCheck::RuntimeCheck(Module &M, LLVMContext &C, IRBuilder<> &B, ExceptionHandler &EH)
: TheModule(M), TheContext(C), Builder(B), Exceptions(EH) {
+ UserLine = new GlobalVariable(TheModule, Builder.getInt32Ty(), false,
+ GlobalValue::ExternalLinkage, Builder.getInt32(0), "__cps_user_line");
setupExternalFunctions();
}
+Value *RuntimeCheck::lineValue(int Line) {
+ return LibraryMode ? Builder.CreateLoad(Builder.getInt32Ty(), UserLine, "user_line")
+ : static_cast<Value *>(Builder.getInt32(Line));
+}
+
+void RuntimeCheck::setUserLine(int Line) {
+ Builder.CreateStore(Builder.getInt32(Line), UserLine);
+}
+
void RuntimeCheck::setupExternalFunctions() {
Type *PtrTy = PointerType::getUnqual(TheContext);
Type *I32 = Type::getInt32Ty(TheContext);
@@ -54,7 +65,7 @@ void RuntimeCheck::emitStderr(Value *Msg, ArrayRef<Value *> FmtArgs) {
}
void RuntimeCheck::emitCheck(Value *Condition, Value *Msg, int Line) {
- emitCheck(Condition, Msg, {ConstantInt::get(TheContext, APInt(32, Line))});
+ emitCheck(Condition, Msg, {lineValue(Line)});
}
void RuntimeCheck::emitCheck(Value *Condition, Value *Msg, ArrayRef<Value *> FmtArgs) {
@@ -105,7 +116,7 @@ void RuntimeCheck::emitEnumRangeCheck(Value *Ordinal, uint64_t ValueCount,
Value *NameStr = Builder.CreateGlobalString(TypeName, "enum_name", 0, &TheModule);
emitCheck(OutOfRange, EnumRangeMsg,
- {ConstantInt::get(TheContext, APInt(32, Line)), NameStr});
+ {lineValue(Line), NameStr});
}
void RuntimeCheck::emitNullDerefCheck(Value *Ptr, int Line) {
@@ -125,6 +136,6 @@ void RuntimeCheck::emitArrayArgBoundsCheck(Value *ActualLower, Value *ActualUppe
Value *Mismatch = Builder.CreateOr(LoDiff, HiDiff, "arg_bounds_ne");
emitCheck(Mismatch, ArrayArgBoundsMsg,
- {ConstantInt::get(TheContext, APInt(32, Line)),
+ {lineValue(Line),
ActualLower, ActualUpper, DeclLo, DeclHi});
}