diff options
| author | Sai Praveen Bangaru <31557731+saipraveenb25@users.noreply.github.com> | 2024-07-18 13:11:19 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-18 13:11:19 -0400 |
| commit | 0d06ebcefb36a19710d87832fc1ea027e21281af (patch) | |
| tree | 05ac5af6fa26a658348335eac3d63199b6949507 /source/slang/slang-reflection-api.cpp | |
| parent | 89e836d42822e69dcaa4eb0a366d8c66e5aaa7e4 (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.cpp | 152 |
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; } |
