diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-27 14:00:16 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-27 14:00:16 +0000 |
| commit | 3d7d1d7cf8685f0d9230cd89d06017869da1c6d8 (patch) | |
| tree | 3b5ea9523e94f4193eb1a28b237f41d81a2cde03 /lib/CodeGen | |
| parent | a91bd145008432fb8c5d91d94ab6f50473a277f5 (diff) | |
feat(library)!: replace #LIB with __LIB source regions
Track library mode by original source line, including deferred template bodies
and automatic object cleanup. Update call lines from ordinary code and migrate
the embedded standard library to PP_DEFINE __LIB.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen')
| -rw-r--r-- | lib/CodeGen/CodeGen.cc | 12 | ||||
| -rw-r--r-- | lib/CodeGen/ConstructorGen.cc | 5 | ||||
| -rw-r--r-- | lib/CodeGen/RuntimeCheck.cc | 5 |
3 files changed, 15 insertions, 7 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc index 49b470c..ce5fa00 100644 --- a/lib/CodeGen/CodeGen.cc +++ b/lib/CodeGen/CodeGen.cc @@ -149,9 +149,12 @@ void CodeGen::selectUnit(size_t Unit) { CurrentUnit = Unit; DiagnosticSource = (*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->setLibraryLookup([this](int Line) { + return (*Units)[CurrentUnit].isLibrary(Line); + }); + FuncGen->setCallHook([this](const FuncSig &) { + // The callee may enable __LIB inside its body even if its header is ordinary code. + if (!(*Units)[CurrentUnit].isLibrary(DiagnosticLine)) RuntimeChecker->setUserLine(DiagnosticLine); }); } @@ -195,7 +198,8 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) { if (!Added && !Compatible && (It->second.Unit != CurrentUnit || ((IsTemplate || It->second.IsTemplate) && !(IsFunction && It->second.IsFunction)))) { // Default library units follow user inputs; point at the user's conflicting definition. - bool UserConflict = Sources[CurrentUnit].IsLibrary && !Sources[It->second.Unit].IsLibrary; + bool UserConflict = Sources[CurrentUnit].isLibrary(DiagnosticLine) && + !Sources[It->second.Unit].isLibrary(It->second.Line); SaveAndRestore<int> Location(DiagnosticLine, UserConflict ? It->second.Line : DiagnosticLine); SaveAndRestore<std::string> Source(DiagnosticSource, UserConflict ? Sources[It->second.Unit].Path : DiagnosticSource); diff --git a/lib/CodeGen/ConstructorGen.cc b/lib/CodeGen/ConstructorGen.cc index b029385..da89f59 100644 --- a/lib/CodeGen/ConstructorGen.cc +++ b/lib/CodeGen/ConstructorGen.cc @@ -284,7 +284,7 @@ size_t CodeGen::registerStackObject(Value *Addr, const std::string &TypeName, in Count = Entry.CreateAlloca(Entry.getInt64Ty(), nullptr, "object_count"); Entry.CreateStore(Entry.getInt64(0), Count); } - StackObjects.push_back({Addr, TypeName, Alive, Count, Line}); + StackObjects.push_back({Addr, TypeName, Alive, Count, Line, CurrentUnit}); // This DECLARE can execute repeatedly, including after a backward loop edge. emitStackObjectCleanup(StackObjects.back()); return StackObjects.size() - 1; @@ -298,6 +298,8 @@ void CodeGen::activateStackObject(size_t Index, Value *Count) { } void CodeGen::emitStackObjectCleanup(const StackObject &Object) { + size_t SavedUnit = CurrentUnit; + selectUnit(Object.OwnerUnit); auto *F = Builder->GetInsertBlock()->getParent(); auto *Destroy = BasicBlock::Create(*TheContext, "destroy_object", F); auto *Done = BasicBlock::Create(*TheContext, "destroyed_object", F); @@ -339,6 +341,7 @@ void CodeGen::emitStackObjectCleanup(const StackObject &Object) { } Builder->CreateBr(Done); Builder->SetInsertPoint(Done); + selectUnit(SavedUnit); } void CodeGen::finishStackObjects(Function *F) { diff --git a/lib/CodeGen/RuntimeCheck.cc b/lib/CodeGen/RuntimeCheck.cc index e15c10b..3991bf2 100644 --- a/lib/CodeGen/RuntimeCheck.cc +++ b/lib/CodeGen/RuntimeCheck.cc @@ -17,8 +17,9 @@ RuntimeCheck::RuntimeCheck(Module &M, LLVMContext &C, IRBuilder<> &B, ExceptionH } Value *RuntimeCheck::lineValue(int Line) { - return LibraryMode ? Builder.CreateLoad(Builder.getInt32Ty(), UserLine, "user_line") - : static_cast<Value *>(Builder.getInt32(Line)); + return LibraryLookup && LibraryLookup(Line) + ? Builder.CreateLoad(Builder.getInt32Ty(), UserLine, "user_line") + : static_cast<Value *>(Builder.getInt32(Line)); } void RuntimeCheck::setUserLine(int Line) { |
