aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGen.cc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-21 06:14:00 +0000
committer_ov4 <ov4@ov4.org>2026-10-21 06:14:00 +0000
commitdb8c7f14d2f74c3db205782acf8222cb7d91a047 (patch)
tree31b6e17c0cb818ba0cc700cd1e0ca896a6b9156f /lib/CodeGen/CodeGen.cc
parent25ae363250e479701ed532c55c255e043c8240da (diff)
feat(codegen): instantiate class templates
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'lib/CodeGen/CodeGen.cc')
-rw-r--r--lib/CodeGen/CodeGen.cc18
1 files changed, 10 insertions, 8 deletions
diff --git a/lib/CodeGen/CodeGen.cc b/lib/CodeGen/CodeGen.cc
index 9a678ca..fb86120 100644
--- a/lib/CodeGen/CodeGen.cc
+++ b/lib/CodeGen/CodeGen.cc
@@ -182,9 +182,11 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
if (Sources.empty()) { reportError("no main program"); return; }
Exports.resize(Sources.size());
Types->setVisibility([this](const std::string &Name) {
+ if (FailedTemplateTypes.count(Name)) return false;
auto It = TypeOwners.find(Name);
return It == TypeOwners.end() || isVisible(It->second);
});
+ Types->setResolveMiss([this](const std::string &Name) { return instantiateClass(Name); });
FuncGen->setVisibility([this](size_t Owner) { return isVisible(Owner); });
struct Definition { size_t Unit; bool IsFunction; bool IsOverload; bool IsExtern; bool IsTemplate; int Line; };
@@ -277,6 +279,7 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
BasicBlock *UnhandledBB = BasicBlock::Create(*TheContext, "unhandled_exception", F);
Exceptions->pushHandler(UnhandledBB);
+ TypePrePass = true;
// Reserve names across every unit before resolving any type payload.
for (size_t I = 0; I < Sources.size(); ++I) {
selectUnit(I);
@@ -294,6 +297,8 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
runTypePrePass(Sources[I].Statements, 2);
};
for (size_t I = 0; I < Sources.size(); ++I) DefineTypes(I);
+ TypePrePass = false;
+ emitDeferredClassPrototypes();
for (size_t I = 0; I < Sources.size(); ++I) {
selectUnit(I);
@@ -304,11 +309,7 @@ void CodeGen::compile(const std::vector<SourceUnit> &Sources) {
if (auto *Extern = dynamic_cast<ExternDeclAST*>(Stmt.get()))
FuncGen->emitExternPrototype(Extern->getProto());
if (auto *Class = dynamic_cast<ClassTypeDeclAST*>(Stmt.get())) {
- for (const auto &Method : Class->getMethods()) {
- SaveAndRestore<int> MethodLocation(DiagnosticLine, Method->getLine());
- if (isRegisteredMethod(Class->getName(), Method->getProto()))
- FuncGen->emitPrototype(Method->getProto());
- }
+ emitClassPrototypes(Class);
}
}
}
@@ -573,14 +574,15 @@ const FuncSig *CodeGen::resolveCall(const std::string &Name,
if (HasPackParam ? Actual.size() < FixedCount : Actual.size() != FixedCount) continue;
detail::TemplateBindings Bindings;
for (const auto &Param : TemplateParams) Bindings.emplace(Param.Name, std::vector<std::string>{});
+ SaveAndRestore<bool> Speculation(SpeculativeTemplateResolution, true);
bool Match = true;
if (HasExplicit) {
size_t FixedTypes = TemplateParams.size() - Variadic;
if (!Variadic && Explicit->size() > FixedTypes) continue;
for (size_t I = 0; I < Explicit->size(); ++I) {
- const TypeInfo *Type = resolveType((*Explicit)[I]);
- if (!Type || Type->isVoid()) { Match = false; break; }
- Bindings.at(TemplateParams[std::min(I, FixedTypes)].Name).push_back(Type->Name);
+ auto Type = canonicalTemplateArgument((*Explicit)[I]);
+ if (!Type) { Match = false; break; }
+ Bindings.at(TemplateParams[std::min(I, FixedTypes)].Name).push_back(*Type);
}
}
if (!Match) continue;