summaryrefslogtreecommitdiff
path: root/source/slang/slang-linkable.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-08-06 01:07:41 -0700
committerGitHub <noreply@github.com>2025-08-06 08:07:41 +0000
commit68b0125226464cb3c9e9b7f50bfb53cda97723b4 (patch)
tree5f0833c6d9aa759b2769f7f6ac9b3ca6ed9a10f0 /source/slang/slang-linkable.cpp
parent83675103a1a4fefde11b314aed26f4d37860efe7 (diff)
Add reflection api for overload candidate filtering. (#8066)
* Add reflection api for overload candidate filtering. * Fix API. * Fix. * Update build. * Update test. * Update formatting.
Diffstat (limited to 'source/slang/slang-linkable.cpp')
-rw-r--r--source/slang/slang-linkable.cpp59
1 files changed, 34 insertions, 25 deletions
diff --git a/source/slang/slang-linkable.cpp b/source/slang/slang-linkable.cpp
index da4cec823..f7dc28171 100644
--- a/source/slang/slang-linkable.cpp
+++ b/source/slang/slang-linkable.cpp
@@ -8,6 +8,7 @@
#include "core/slang-memory-file-system.h"
#include "slang-check-impl.h"
#include "slang-compiler.h"
+#include "slang-lookup.h"
#include "slang-mangle.h"
namespace Slang
@@ -772,6 +773,14 @@ Type* ComponentType::getTypeFromString(String const& typeStr, DiagnosticSink* si
return type;
}
+Expr* ComponentType::tryResolveOverloadedExpr(Expr* exprIn)
+{
+ auto linkage = getLinkage();
+ SemanticsContext context(linkage->getSemanticsForReflection());
+ SemanticsVisitor visitor(context);
+ return visitor.maybeResolveOverloadedExpr(exprIn, LookupMask::Function, nullptr);
+}
+
Expr* ComponentType::findDeclFromString(String const& name, DiagnosticSink* sink)
{
// If we've looked up this type name before,
@@ -905,39 +914,39 @@ Expr* ComponentType::findDeclFromStringInType(
auto checkedTerm = visitor.CheckTerm(expr);
- // Check if checkedTerm is overloaded functions and avoid resolving if so
- // to preserve all function overloads with different signatures
- Expr* resolvedTerm = checkedTerm;
if (auto overloadedExpr = as<OverloadedExpr>(checkedTerm))
{
- // Check if all candidates are function references
- bool allAreFunctions = true;
- for (auto item : overloadedExpr->lookupResult2.items)
+ // For functions, since we don't know the argument list yet, we will have to defer
+ // non-parameter-related candidate comparison logic into its separate step.
+ if (mask != LookupMask::Function)
+ return visitor.maybeResolveOverloadedExpr(checkedTerm, mask, nullptr);
+ overloadedExpr->lookupResult2 = refineLookup(overloadedExpr->lookupResult2, mask);
+
+ // Filter out abstract base interface method implementations for reflection.
+ if (!isInterfaceType(type))
{
- if (!as<FunctionDeclBase>(item.declRef.getDecl()))
+ LookupResult filteredResult;
+ for (auto candidate : overloadedExpr->lookupResult2)
{
- allAreFunctions = false;
- break;
+ if (as<InterfaceDecl>(getParentDecl(candidate.declRef.getDecl())))
+ {
+ if (!candidate.declRef.getDecl()
+ ->hasModifier<HasInterfaceDefaultImplModifier>())
+ continue;
+ }
+ AddToLookupResult(filteredResult, candidate);
}
+ if (filteredResult.isValid() && !filteredResult.isOverloaded())
+ {
+ // If there are exactly one candidate after filtering, we can
+ // safely return resolved expr.
+ return visitor.maybeResolveOverloadedExpr(checkedTerm, mask, nullptr);
+ }
+ overloadedExpr->lookupResult2 = filteredResult;
}
-
- // If not all are functions, resolve the overload as usual
- if (!allAreFunctions)
- {
- resolvedTerm = visitor.maybeResolveOverloadedExpr(checkedTerm, mask, sink);
- }
- }
- else
- {
- // Not overloaded, resolve as usual
- resolvedTerm = visitor.maybeResolveOverloadedExpr(checkedTerm, mask, sink);
- }
-
- if (auto overloadedExpr = as<OverloadedExpr>(resolvedTerm))
- {
return overloadedExpr;
}
- if (auto declRefExpr = as<DeclRefExpr>(resolvedTerm))
+ if (auto declRefExpr = as<DeclRefExpr>(checkedTerm))
{
return declRefExpr;
}