summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-reflection-api.cpp
diff options
context:
space:
mode:
authorSai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com>2024-07-18 13:11:19 -0400
committerGitHub <noreply@github.com>2024-07-18 13:11:19 -0400
commit0d06ebcefb36a19710d87832fc1ea027e21281af (patch)
tree05ac5af6fa26a658348335eac3d63199b6949507 /source/slang/slang-reflection-api.cpp
parent89e836d42822e69dcaa4eb0a366d8c66e5aaa7e4 (diff)
Initial implementation for decl-tree reflection API (#4666)
* Initial implementation for decl-tree reflection API This patch adds Slang API methods for walking all the declarations in the AST. We expose this functionality through an abstract `DeclReflection` class that can be a type, function or a variable declaration. We also provide ways to cast the decl to a `FunctionReflection`, `TypeReflection` or `VariableReflection` and traverse through the child nodes (for instance, a struct type will have component variable declarations) This patch also adds `ISlangInternal` as an internal COM interface to allow us to cast IGlobalSession to the internal Session pointer while bypassing any wrappers (such as the capture interface) * Update slang.h * Remove `ISlangInternal` (its causing a diamond pattern w.r.t `ISlangUnknown`) and use `ComPtr` for proper ref management. * Update unit-test-decl-tree-reflection.cpp * Change `FunctionDeclBase` to use `DeclRef` instead of directly using the decl. * Update slang-reflection-api.cpp
Diffstat (limited to 'source/slang/slang-reflection-api.cpp')
-rw-r--r--source/slang/slang-reflection-api.cpp152
1 files changed, 139 insertions, 13 deletions
diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp
index d0d09f814..9e08330e4 100644
--- a/source/slang/slang-reflection-api.cpp
+++ b/source/slang/slang-reflection-api.cpp
@@ -65,14 +65,15 @@ static inline SlangReflectionVariable* convert(Decl* var)
return (SlangReflectionVariable*) var;
}
-static inline FunctionDeclBase* convert(SlangReflectionFunction* func)
+static inline DeclRef<FunctionDeclBase> convert(SlangReflectionFunction* func)
{
- return (FunctionDeclBase*)func;
+ DeclRefBase* declBase = (DeclRefBase*)func;
+ return DeclRef<FunctionDeclBase>(declBase);
}
-static inline SlangReflectionFunction* convert(FunctionDeclBase* func)
+static inline SlangReflectionFunction* convert(DeclRef<FunctionDeclBase> func)
{
- return (SlangReflectionFunction*)func;
+ return (SlangReflectionFunction*)func.declRefBase;
}
static inline VarLayout* convert(SlangReflectionVariableLayout* var)
@@ -773,7 +774,7 @@ SLANG_API SlangReflectionFunction* spReflection_FindFunctionByName(SlangReflecti
{
auto result = program->findDeclFromString(name, &sink);
if (auto funcDeclRef = result.as<FunctionDeclBase>())
- return (SlangReflectionFunction*)funcDeclRef.getDecl();
+ return convert(funcDeclRef);
}
catch (...)
{
@@ -2621,6 +2622,9 @@ SLANG_API SlangReflectionModifier* spReflectionVariable_FindModifier(SlangReflec
case SLANG_MODIFIER_DIFFERENTIABLE:
modifier = var->findModifier<DifferentiableAttribute>();
break;
+ case SLANG_MODIFIER_MUTATING:
+ modifier = var->findModifier<MutatingAttribute>();
+ break;
default:
return nullptr;
}
@@ -2647,6 +2651,17 @@ SLANG_API SlangReflectionUserAttribute* spReflectionVariable_FindUserAttributeBy
return findUserAttributeByName(asInternal(session), varDecl, name);
}
+SLANG_API bool spReflectionVariable_HasDefaultValue(SlangReflectionVariable* inVar)
+{
+ auto decl = convert(inVar);
+ if (auto varDecl = as<VarDeclBase>(decl))
+ {
+ return varDecl->initExpr != nullptr;
+ }
+
+ return false;
+}
+
// Variable Layout Reflection
SLANG_API SlangReflectionVariable* spReflectionVariableLayout_GetVariable(SlangReflectionVariableLayout* inVarLayout)
@@ -2793,11 +2808,18 @@ SLANG_API SlangStage spReflectionVariableLayout_getStage(
// Function Reflection
+SLANG_API SlangReflectionDecl* spReflectionFunction_asDecl(SlangReflectionFunction* inFunc)
+{
+ auto func = convert(inFunc);
+ if (!func) return nullptr;
+ return (SlangReflectionDecl*)func.getDecl();
+}
+
SLANG_API char const* spReflectionFunction_GetName(SlangReflectionFunction* inFunc)
{
auto func = convert(inFunc);
if (!func) return nullptr;
- return getText(func->getName()).getBuffer();
+ return getText(func.getDecl()->getName()).getBuffer();
}
SLANG_API SlangReflectionType* spReflectionFunction_GetResultType(SlangReflectionFunction* inFunc)
@@ -2805,42 +2827,146 @@ SLANG_API SlangReflectionType* spReflectionFunction_GetResultType(SlangReflectio
auto func = convert(inFunc);
if (!func) return nullptr;
- return convert(func->returnType.type);
+ auto rawType = func.getDecl()->returnType.type;
+ auto astBuilder = rawType->getASTBuilderForReflection();
+
+ return convert((Type*)rawType->substitute(astBuilder, SubstitutionSet(func.declRefBase)));
+}
+
+SLANG_API SlangReflectionModifier* spReflectionFunction_FindModifier(SlangReflectionFunction* inFunc, SlangModifierID modifierID)
+{
+ auto funcDeclRef = convert(inFunc);
+ auto varRefl = convert(funcDeclRef.getDecl());
+ if (!varRefl) return nullptr;
+
+ return spReflectionVariable_FindModifier(varRefl, modifierID);
}
SLANG_API unsigned int spReflectionFunction_GetUserAttributeCount(SlangReflectionFunction* inFunc)
{
auto func = convert(inFunc);
if (!func) return 0;
- return getUserAttributeCount(func);
+ return getUserAttributeCount(func.getDecl());
}
SLANG_API SlangReflectionUserAttribute* spReflectionFunction_GetUserAttribute(SlangReflectionFunction* inFunc, unsigned int index)
{
auto func = convert(inFunc);
if (!func) return nullptr;
- return getUserAttributeByIndex(func, index);
+ return getUserAttributeByIndex(func.getDecl(), index);
}
SLANG_API SlangReflectionUserAttribute* spReflectionFunction_FindUserAttributeByName(SlangReflectionFunction* inFunc, SlangSession* session, char const* name)
{
auto func = convert(inFunc);
if (!func) return nullptr;
- return findUserAttributeByName(asInternal(session), func, name);
+ return findUserAttributeByName(asInternal(session), func.getDecl(), name);
}
SLANG_API unsigned int spReflectionFunction_GetParameterCount(SlangReflectionFunction* inFunc)
{
auto func = convert(inFunc);
if (!func) return 0;
- return (unsigned int)func->getParameters().getCount();
+ return (unsigned int)func.getDecl()->getParameters().getCount();
}
SLANG_API SlangReflectionVariable* spReflectionFunction_GetParameter(SlangReflectionFunction* inFunc, unsigned int index)
{
auto func = convert(inFunc);
if (!func) return nullptr;
- return convert(as<Decl>(func->getParameters()[index]));
+ return convert(as<Decl>(func.getDecl()->getParameters()[index]));
+}
+
+// Abstract decl reflection
+
+SLANG_API unsigned int spReflectionDecl_getChildrenCount(SlangReflectionDecl* parentDecl)
+{
+ Decl* decl = (Decl*)parentDecl;
+ if (as<ContainerDecl>(decl))
+ {
+ return (unsigned int)as<ContainerDecl>(decl)->members.getCount();
+ }
+
+ return 0;
+}
+
+SLANG_API SlangReflectionDecl* spReflectionDecl_getChild(SlangReflectionDecl* parentDecl, unsigned int index)
+{
+ Decl* decl = (Decl*)parentDecl;
+ if (auto containerDecl = as<ContainerDecl>(decl))
+ {
+ if (containerDecl->members.getCount() > index)
+ return (SlangReflectionDecl*)containerDecl->members[index];
+ }
+
+ return nullptr;
+}
+
+SLANG_API SlangDeclKind spReflectionDecl_getKind(SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*)decl;
+ if (as<StructDecl>(slangDecl))
+ {
+ return SLANG_DECL_KIND_STRUCT;
+ }
+ else if (as<VarDeclBase>(slangDecl))
+ {
+ return SLANG_DECL_KIND_VARIABLE;
+ }
+ else if (as<GenericDecl>(slangDecl))
+ {
+ return SLANG_DECL_KIND_GENERIC;
+ }
+ else if (as<FunctionDeclBase>(slangDecl))
+ {
+ return SLANG_DECL_KIND_FUNC;
+ }
+ else if (as<ModuleDecl>(slangDecl))
+ {
+ return SLANG_DECL_KIND_MODULE;
+ }
+ else
+ return SLANG_DECL_KIND_UNSUPPORTED_FOR_REFLECTION;
+}
+
+SLANG_API SlangReflectionFunction* spReflectionDecl_castToFunction(SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*) decl;
+ if (auto funcDecl = as<FunctionDeclBase>(slangDecl))
+ {
+ return convert(DeclRef<FunctionDeclBase>(funcDecl->getDefaultDeclRef()));
+ }
+
+ // Improper cast
+ return nullptr;
+}
+
+SLANG_API SlangReflectionVariable* spReflectionDecl_castToVariable(SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*) decl;
+ if (auto varDecl = as<VarDeclBase>(slangDecl))
+ {
+ return (SlangReflectionVariable*) varDecl;
+ }
+
+ // Improper cast
+ return nullptr;
+
+}
+
+SLANG_API SlangReflectionType* spReflection_getTypeFromDecl(SlangSession* session, SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*)decl;
+ auto slangSession = asInternal(session);
+
+ ASTBuilder* builder = slangSession->getGlobalASTBuilder();
+ if (auto type = DeclRefType::create(builder, slangDecl->getDefaultDeclRef()))
+ {
+ return convert(type);
+ }
+
+ // Couldn't create a type from the decl
+ return nullptr;
}
// Shader Parameter Reflection
@@ -2906,7 +3032,7 @@ SLANG_API SlangReflectionFunction* spReflectionEntryPoint_GetFunction(SlangRefle
auto entryPointLayout = convert(inEntryPoint);
if (entryPointLayout)
{
- return (SlangReflectionFunction*)entryPointLayout->entryPoint.getDecl();
+ return convert(entryPointLayout->entryPoint);
}
return nullptr;
}