From d866c0b9dfc0fdc8ad8cede4d7a8593f7ddf4716 Mon Sep 17 00:00:00 2001 From: Sai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com> Date: Mon, 16 Sep 2024 16:04:45 -0400 Subject: Add API method to specialize function reference with argument types (#4966) * Add `FunctionReflection::specializeWithArgTypes()` * Update slang.cpp * Use a shared semantics context on linkage Improve performance on reflection queries * Try to fix linux/mac compile errors --- source/slang/slang.cpp | 100 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 67 insertions(+), 33 deletions(-) (limited to 'source/slang/slang.cpp') diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index c78348a86..6c152cddd 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -28,7 +28,6 @@ #include "slang-type-layout.h" #include "slang-lookup.h" -# #include "slang-options.h" #include "slang-repro.h" @@ -1069,8 +1068,12 @@ Linkage::Linkage(Session* session, ASTBuilder* astBuilder, Linkage* builtinLinka for (const auto& nameToMod : builtinLinkage->mapNameToLoadedModules) mapNameToLoadedModules.add(nameToMod); } + + m_semanticsForReflection = new SharedSemanticsContext(this, nullptr, nullptr); } +SharedSemanticsContext* Linkage::getSemanticsForReflection() { return m_semanticsForReflection.get(); } + ISlangUnknown* Linkage::getInterface(const Guid& guid) { if(guid == ISlangUnknown::getTypeGuid() || guid == ISession::getTypeGuid()) @@ -1348,18 +1351,11 @@ SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL Linkage::specializeType( return asExternal(specializedType); } - -DeclRef Linkage::specializeGeneric( - DeclRef declRef, - List argExprs, - DiagnosticSink* sink) +DeclRef getGenericParentDeclRef( + ASTBuilder* astBuilder, + SemanticsVisitor* visitor, + DeclRef declRef) { - SLANG_AST_BUILDER_RAII(getASTBuilder()); - SLANG_ASSERT(declRef); - - SharedSemanticsContext sharedSemanticsContext(this, nullptr, sink); - SemanticsVisitor visitor(&sharedSemanticsContext); - // Create substituted parent decl ref. auto decl = declRef.getDecl(); @@ -1369,9 +1365,58 @@ DeclRef Linkage::specializeGeneric( } auto genericDecl = as(decl); - auto genericDeclRef = createDefaultSubstitutionsIfNeeded(getASTBuilder(), &visitor, DeclRef(genericDecl)).as(); - genericDeclRef = substituteDeclRef(SubstitutionSet(declRef), getASTBuilder(), genericDeclRef).as(); + auto genericDeclRef = createDefaultSubstitutionsIfNeeded(astBuilder, visitor, DeclRef(genericDecl)).as(); + return substituteDeclRef(SubstitutionSet(declRef), astBuilder, genericDeclRef).as(); +} + +DeclRef Linkage::specializeWithArgTypes( + DeclRef funcDeclRef, + List argTypes, + DiagnosticSink* sink) +{ + SemanticsVisitor visitor(getSemanticsForReflection()); + visitor = visitor.withSink(sink); + + ASTBuilder* astBuilder = getASTBuilder(); + List argExprs; + for (SlangInt aa = 0; aa < argTypes.getCount(); ++aa) + { + auto argType = argTypes[aa]; + + // Create an 'empty' expr with the given type. Ideally, the expression itself should not matter + // only its checked type. + // + auto argExpr = astBuilder->create(); + argExpr->type = argType; + argExprs.add(argExpr); + } + + // Construct invoke expr. + auto invokeExpr = astBuilder->create(); + auto declRefExpr = astBuilder->create(); + + declRefExpr->declRef = getGenericParentDeclRef(getASTBuilder(), &visitor, funcDeclRef); + invokeExpr->functionExpr = declRefExpr; + invokeExpr->arguments = argExprs; + + auto checkedInvokeExpr = visitor.CheckInvokeExprWithCheckedOperands(invokeExpr); + return as(as(checkedInvokeExpr)->functionExpr)->declRef; +} + + +DeclRef Linkage::specializeGeneric( + DeclRef declRef, + List argExprs, + DiagnosticSink* sink) +{ + SLANG_AST_BUILDER_RAII(getASTBuilder()); + SLANG_ASSERT(declRef); + + SemanticsVisitor visitor(getSemanticsForReflection()); + visitor = visitor.withSink(sink); + + auto genericDeclRef = getGenericParentDeclRef(getASTBuilder(), &visitor, declRef); DeclRefExpr* declRefExpr = getASTBuilder()->create(); declRefExpr->declRef = genericDeclRef; @@ -1561,8 +1606,9 @@ SLANG_NO_THROW SlangResult SLANG_MCALL Linkage::createTypeConformanceComponentTy try { - SharedSemanticsContext sharedSemanticsContext(this, nullptr, &sink); - SemanticsVisitor visitor(&sharedSemanticsContext); + SemanticsVisitor visitor(getSemanticsForReflection()); + visitor = visitor.withSink(&sink); + auto witness = visitor.isSubtype((Slang::Type*)type, (Slang::Type*)interfaceType, IsSubTypeOptions::None); if (auto subtypeWitness = as(witness)) @@ -2318,12 +2364,8 @@ DeclRef ComponentType::findDeclFromString( Expr* expr = linkage->parseTermString(name, scope); - SharedSemanticsContext sharedSemanticsContext( - linkage, - nullptr, - sink); - SemanticsContext context(&sharedSemanticsContext); - context = context.allowStaticReferenceToNonStaticMember(); + SemanticsContext context(linkage->getSemanticsForReflection()); + context = context.allowStaticReferenceToNonStaticMember().withSink(sink); SemanticsVisitor visitor(context); @@ -2377,12 +2419,8 @@ DeclRef ComponentType::findDeclFromStringInType( Expr* expr = linkage->parseTermString(name, scope); - SharedSemanticsContext sharedSemanticsContext( - linkage, - nullptr, - sink); - SemanticsContext context(&sharedSemanticsContext); - context = context.allowStaticReferenceToNonStaticMember(); + SemanticsContext context(linkage->getSemanticsForReflection()); + context = context.allowStaticReferenceToNonStaticMember().withSink(sink); SemanticsVisitor visitor(context); @@ -2433,11 +2471,7 @@ DeclRef ComponentType::findDeclFromStringInType( bool ComponentType::isSubType(Type* subType, Type* superType) { - SharedSemanticsContext sharedSemanticsContext( - getLinkage(), - nullptr, - nullptr); - SemanticsContext context(&sharedSemanticsContext); + SemanticsContext context(getLinkage()->getSemanticsForReflection()); SemanticsVisitor visitor(context); return (visitor.isSubtype(subType, superType, IsSubTypeOptions::None) != nullptr); -- cgit v1.2.3