summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-reflection-api.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-reflection-api.cpp')
-rw-r--r--source/slang/slang-reflection-api.cpp342
1 files changed, 318 insertions, 24 deletions
diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp
index a212f0d1b..edfd27489 100644
--- a/source/slang/slang-reflection-api.cpp
+++ b/source/slang/slang-reflection-api.cpp
@@ -8,6 +8,7 @@
#include "slang-compiler.h"
#include "slang-type-layout.h"
#include "slang-syntax.h"
+#include "slang-check.h"
#include <assert.h>
// Don't signal errors for stuff we don't implement here,
@@ -55,14 +56,14 @@ static inline SpecializationParamLayout* convert(SlangReflectionTypeParameter *
return (SpecializationParamLayout*) typeParam;
}
-static inline Decl* convert(SlangReflectionVariable* var)
+static inline DeclRef<Decl> convert(SlangReflectionVariable* var)
{
- return (Decl*) var;
+ return DeclRef<Decl>((DeclRefBase*) var);
}
-static inline SlangReflectionVariable* convert(Decl* var)
+static inline SlangReflectionVariable* convert(DeclRef<Decl> var)
{
- return (SlangReflectionVariable*) var;
+ return (SlangReflectionVariable*) var.declRefBase;
}
static inline DeclRef<FunctionDeclBase> convert(SlangReflectionFunction* func)
@@ -76,6 +77,17 @@ static inline SlangReflectionFunction* convert(DeclRef<FunctionDeclBase> func)
return (SlangReflectionFunction*)func.declRefBase;
}
+static inline DeclRef<Decl> convertGenericToDeclRef(SlangReflectionGeneric* func)
+{
+ DeclRefBase* declBase = (DeclRefBase*)func;
+ return DeclRef<Decl>(declBase);
+}
+
+static inline SlangReflectionGeneric* convertDeclToGeneric(DeclRef<Decl> func)
+{
+ return (SlangReflectionGeneric*)func.declRefBase;
+}
+
static inline VarLayout* convert(SlangReflectionVariableLayout* var)
{
return (VarLayout*) var;
@@ -482,7 +494,7 @@ SLANG_API SlangReflectionVariable* spReflectionType_GetFieldByIndex(SlangReflect
auto fields = getFields(
getModule(declRef.getDecl())->getLinkage()->getASTBuilder(), structDeclRef, MemberFilterStyle::Instance);
auto fieldDeclRef = fields[index];
- return (SlangReflectionVariable*) fieldDeclRef.getDecl();
+ return convert(fieldDeclRef);
}
}
@@ -786,6 +798,52 @@ SLANG_API SlangReflectionFunction* spReflection_FindFunctionByName(SlangReflecti
return nullptr;
}
+SLANG_API SlangReflectionFunction* spReflection_FindFunctionByNameInType(SlangReflection* reflection, SlangReflectionType* reflType, char const* name)
+{
+ auto programLayout = convert(reflection);
+ auto program = programLayout->getProgram();
+
+ auto type = convert(reflType);
+
+ Slang::DiagnosticSink sink(
+ programLayout->getTargetReq()->getLinkage()->getSourceManager(),
+ Lexer::sourceLocationLexer);
+
+ try
+ {
+ auto result = program->findDeclFromStringInType(type, name, LookupMask::Function, &sink);
+ if (auto funcDeclRef = result.as<FunctionDeclBase>())
+ return convert(funcDeclRef);
+ }
+ catch (...)
+ {
+ }
+ return nullptr;
+}
+
+SLANG_API SlangReflectionVariable* spReflection_FindVarByNameInType(SlangReflection* reflection, SlangReflectionType* reflType, char const* name)
+{
+ auto programLayout = convert(reflection);
+ auto program = programLayout->getProgram();
+
+ auto type = convert(reflType);
+
+ Slang::DiagnosticSink sink(
+ programLayout->getTargetReq()->getLinkage()->getSourceManager(),
+ Lexer::sourceLocationLexer);
+
+ try
+ {
+ auto result = program->findDeclFromStringInType(type, name, LookupMask::Value, &sink);
+ if (auto varDeclRef = result.as<VarDeclBase>())
+ return convert(varDeclRef.as<Decl>());
+ }
+ catch (...)
+ {
+ }
+ return nullptr;
+}
+
SLANG_API SlangReflectionType * spReflection_FindTypeByName(SlangReflection * reflection, char const * name)
{
auto programLayout = convert(reflection);
@@ -811,6 +869,35 @@ SLANG_API SlangReflectionType * spReflection_FindTypeByName(SlangReflection * re
}
}
+SlangReflectionGeneric* getInnermostGenericParent(DeclRef<Decl> declRef)
+{
+ auto decl = declRef.getDecl();
+ auto astBuilder = getModule(decl)->getLinkage()->getASTBuilder();
+ auto parentDecl = decl;
+ while(parentDecl)
+ {
+ if(parentDecl->parentDecl && as<GenericDecl>(parentDecl->parentDecl))
+ return convertDeclToGeneric(
+ substituteDeclRef(
+ SubstitutionSet(declRef),
+ astBuilder,
+ createDefaultSubstitutionsIfNeeded(astBuilder, nullptr, DeclRef(parentDecl))));
+ parentDecl = parentDecl->parentDecl;
+ }
+
+ return nullptr;
+}
+
+SLANG_API SlangReflectionGeneric* spReflectionType_GetGenericContainer(SlangReflectionType* type)
+{
+ auto declRefType = as<DeclRefType>(convert(type));
+ if (!declRefType)
+ return nullptr;
+
+ auto declRef = declRefType->getDeclRef();
+ return getInnermostGenericParent(declRef);
+}
+
SLANG_API SlangReflectionTypeLayout* spReflection_GetTypeLayout(
SlangReflection* reflection,
SlangReflectionType* inType,
@@ -2228,7 +2315,7 @@ SLANG_API SlangReflectionVariable* spReflectionTypeLayout_getBindingRangeLeafVar
return 0;
auto& bindingRange = extTypeLayout->m_bindingRanges[index];
- return convert(bindingRange.leafVariable);
+ return convert(DeclRef<Decl>(bindingRange.leafVariable));
}
@@ -2571,7 +2658,7 @@ SLANG_API SlangInt spReflectionTypeLayout_getSubObjectRangeDescriptorRangeSpaceO
SLANG_API char const* spReflectionVariable_GetName(SlangReflectionVariable* inVar)
{
- auto var = convert(inVar);
+ auto var = convert(inVar).getDecl();
if (as<InheritanceDecl>(var))
return "$base";
@@ -2589,17 +2676,26 @@ SLANG_API SlangReflectionType* spReflectionVariable_GetType(SlangReflectionVaria
{
auto var = convert(inVar);
- if (auto inheritanceDecl = as<InheritanceDecl>(var))
- return convert(inheritanceDecl->base.type);
-
if(!var) return nullptr;
- return convert(as<VarDeclBase>(var)->getType());
+ auto astBuilder = getModule(var.getDecl())->getLinkage()->getASTBuilder();
+
+ if (auto inheritanceDecl = as<InheritanceDecl>(var.getDecl()))
+ return convert(inheritanceDecl->base.type);
+
+ if (auto varDecl = as<VarDeclBase>(var.getDecl()))
+ return convert(
+ substituteType(
+ SubstitutionSet(var),
+ astBuilder,
+ varDecl->getType()));
+
+ return nullptr;
}
SLANG_API SlangReflectionModifier* spReflectionVariable_FindModifier(SlangReflectionVariable* inVar, SlangModifierID modifierID)
{
- auto var = convert(inVar);
+ auto var = convert(inVar).getDecl();
if(!var) return nullptr;
@@ -2648,26 +2744,26 @@ SLANG_API SlangReflectionModifier* spReflectionVariable_FindModifier(SlangReflec
SLANG_API unsigned int spReflectionVariable_GetUserAttributeCount(SlangReflectionVariable* inVar)
{
- auto varDecl = convert(inVar);
+ auto varDecl = convert(inVar).getDecl();
if (!varDecl) return 0;
return getUserAttributeCount(varDecl);
}
SLANG_API SlangReflectionUserAttribute* spReflectionVariable_GetUserAttribute(SlangReflectionVariable* inVar, unsigned int index)
{
- auto varDecl = convert(inVar);
+ auto varDecl = convert(inVar).getDecl();
if (!varDecl) return 0;
return getUserAttributeByIndex(varDecl, index);
}
SLANG_API SlangReflectionUserAttribute* spReflectionVariable_FindUserAttributeByName(SlangReflectionVariable* inVar, SlangSession* session, char const* name)
{
- auto varDecl = convert(inVar);
+ auto varDecl = convert(inVar).getDecl();
if (!varDecl) return 0;
return findUserAttributeByName(asInternal(session), varDecl, name);
}
SLANG_API bool spReflectionVariable_HasDefaultValue(SlangReflectionVariable* inVar)
{
- auto decl = convert(inVar);
+ auto decl = convert(inVar).getDecl();
if (auto varDecl = as<VarDeclBase>(decl))
{
return varDecl->initExpr != nullptr;
@@ -2676,6 +2772,12 @@ SLANG_API bool spReflectionVariable_HasDefaultValue(SlangReflectionVariable* inV
return false;
}
+SLANG_API SlangReflectionGeneric* spReflectionVariable_GetGenericContainer(SlangReflectionVariable* var)
+{
+ auto declRef = convert(var);
+ return getInnermostGenericParent(declRef);
+}
+
// Variable Layout Reflection
SLANG_API SlangReflectionVariable* spReflectionVariableLayout_GetVariable(SlangReflectionVariableLayout* inVarLayout)
@@ -2683,7 +2785,7 @@ SLANG_API SlangReflectionVariable* spReflectionVariableLayout_GetVariable(SlangR
auto varLayout = convert(inVarLayout);
if(!varLayout) return nullptr;
- return (SlangReflectionVariable*)(varLayout->varDecl.getDecl());
+ return convert(varLayout->varDecl);
}
SLANG_API SlangReflectionTypeLayout* spReflectionVariableLayout_GetTypeLayout(SlangReflectionVariableLayout* inVarLayout)
@@ -2850,7 +2952,7 @@ SLANG_API SlangReflectionType* spReflectionFunction_GetResultType(SlangReflectio
SLANG_API SlangReflectionModifier* spReflectionFunction_FindModifier(SlangReflectionFunction* inFunc, SlangModifierID modifierID)
{
auto funcDeclRef = convert(inFunc);
- auto varRefl = convert(funcDeclRef.getDecl());
+ auto varRefl = convert(funcDeclRef.as<Decl>());
if (!varRefl) return nullptr;
return spReflectionVariable_FindModifier(varRefl, modifierID);
@@ -2888,7 +2990,16 @@ SLANG_API SlangReflectionVariable* spReflectionFunction_GetParameter(SlangReflec
{
auto func = convert(inFunc);
if (!func) return nullptr;
- return convert(as<Decl>(func.getDecl()->getParameters()[index]));
+
+ auto astBuilder = getModule(func.getDecl())->getLinkage()->getASTBuilder();
+
+ return convert(getParameters(astBuilder, func)[index]);
+}
+
+SLANG_API SlangReflectionGeneric* spReflectionFunction_GetGenericContainer(SlangReflectionFunction* func)
+{
+ auto declRef = convert(func);
+ return getInnermostGenericParent(declRef);
}
// Abstract decl reflection
@@ -2960,20 +3071,31 @@ SLANG_API SlangReflectionVariable* spReflectionDecl_castToVariable(SlangReflecti
Decl* slangDecl = (Decl*) decl;
if (auto varDecl = as<VarDeclBase>(slangDecl))
{
- return (SlangReflectionVariable*) varDecl;
+ return convert(DeclRef(varDecl));
}
// Improper cast
return nullptr;
+}
+
+SLANG_API SlangReflectionGeneric* spReflectionDecl_castToGeneric(SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*) decl;
+ if (auto genericInnerDecl = as<GenericDecl>(slangDecl)->inner)
+ {
+ return convertDeclToGeneric(genericInnerDecl);
+ }
+ // Improper cast
+ return nullptr;
}
-SLANG_API SlangReflectionType* spReflection_getTypeFromDecl(SlangSession* session, SlangReflectionDecl* decl)
+SLANG_API SlangReflectionType* spReflection_getTypeFromDecl(SlangReflectionDecl* decl)
{
Decl* slangDecl = (Decl*)decl;
- auto slangSession = asInternal(session);
- ASTBuilder* builder = slangSession->getGlobalASTBuilder();
+ ASTBuilder* builder = getModule(slangDecl)->getLinkage()->getASTBuilder();
+ // TODO: create default substitutions
if (auto type = DeclRefType::create(builder, slangDecl->getDefaultDeclRef()))
{
return convert(type);
@@ -2983,6 +3105,178 @@ SLANG_API SlangReflectionType* spReflection_getTypeFromDecl(SlangSession* sessio
return nullptr;
}
+SLANG_API SlangReflectionDecl* spReflectionDecl_getParent(SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*)decl;
+ if (auto parentDecl = slangDecl->parentDecl)
+ {
+ return (SlangReflectionDecl*)parentDecl;
+ }
+
+ return nullptr;
+}
+
+// Generic Reflection
+
+SLANG_API SlangReflectionDecl* spReflectionGeneric_asDecl(SlangReflectionGeneric* generic)
+{
+ return (SlangReflectionDecl*) convertGenericToDeclRef(generic).getDecl()->parentDecl;
+}
+
+SLANG_API char const* spReflectionGeneric_GetName(SlangReflectionGeneric* generic)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+ return getText(slangGeneric.getDecl()->getName()).getBuffer();
+}
+
+SLANG_API unsigned int spReflectionGeneric_GetTypeParameterCount(SlangReflectionGeneric* generic)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return 0;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ return (unsigned int) getMembersOfType<GenericTypeParamDecl>(astBuilder, slangGeneric.getDecl()->parentDecl).getCount();
+}
+
+SLANG_API SlangReflectionVariable* spReflectionGeneric_GetTypeParameter(SlangReflectionGeneric* generic, unsigned index)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ auto paramDeclRef = getMembersOfType<GenericTypeParamDecl>(astBuilder, slangGeneric.getDecl()->parentDecl)[index];
+
+ return convert(substituteDeclRef(SubstitutionSet(slangGeneric), astBuilder, paramDeclRef));
+}
+
+SLANG_API unsigned int spReflectionGeneric_GetValueParameterCount(SlangReflectionGeneric* generic)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return 0;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ return (unsigned int) getMembersOfType<GenericValueParamDecl>(astBuilder, slangGeneric.getDecl()->parentDecl).getCount();
+}
+
+SLANG_API SlangReflectionVariable* spReflectionGeneric_GetValueParameter(SlangReflectionGeneric* generic, unsigned index)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ auto paramDeclRef = getMembersOfType<GenericValueParamDecl>(astBuilder, slangGeneric.getDecl()->parentDecl)[index];
+
+ return convert(substituteDeclRef(SubstitutionSet(slangGeneric), astBuilder, paramDeclRef));
+}
+
+SLANG_API unsigned int spReflectionGeneric_GetTypeParameterConstraintCount(SlangReflectionGeneric* generic, SlangReflectionVariable* typeParam)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return 0;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ if (auto typeParamDecl = as<GenericTypeParamDecl>(convert(typeParam).getDecl()))
+ {
+ auto constraints = getCanonicalGenericConstraints(
+ astBuilder,
+ DeclRef<GenericDecl>(slangGeneric.getDecl()->parentDecl));
+ return (unsigned int)(constraints[typeParamDecl]).getValue().getCount();
+ }
+
+ return 0;
+}
+
+SLANG_API SlangReflectionType* spReflectionGeneric_GetTypeParameterConstraintType(SlangReflectionGeneric* generic, SlangReflectionVariable* typeParam, unsigned index)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ if (auto typeParamDecl = as<GenericTypeParamDecl>(convert(typeParam).getDecl()))
+ {
+ auto constraints = getCanonicalGenericConstraints(
+ astBuilder,
+ DeclRef<GenericDecl>(slangGeneric.getDecl()->parentDecl));
+ if (auto constraint = (constraints[typeParamDecl]).getValue()[index])
+ {
+ return convert(substituteType(SubstitutionSet(slangGeneric), astBuilder, constraint));
+ }
+ }
+
+ return nullptr;
+}
+
+SLANG_API SlangDeclKind spReflectionGeneric_GetInnerKind(SlangReflectionGeneric* generic)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return SLANG_DECL_KIND_UNSUPPORTED_FOR_REFLECTION;
+
+ return spReflectionDecl_getKind((SlangReflectionDecl*)slangGeneric.getDecl());
+}
+
+SLANG_API SlangReflectionDecl* spReflectionGeneric_GetInnerDecl(SlangReflectionGeneric* generic)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+
+ return (SlangReflectionDecl*)slangGeneric.getDecl();
+}
+
+SLANG_API SlangReflectionGeneric* spReflectionGeneric_GetOuterGenericContainer(SlangReflectionGeneric* generic)
+{
+ auto declRef = convertGenericToDeclRef(generic);
+
+ auto astBuilder = getModule(declRef.getDecl())->getLinkage()->getASTBuilder();
+
+ return getInnermostGenericParent(
+ substituteDeclRef(
+ SubstitutionSet(declRef),
+ astBuilder,
+ createDefaultSubstitutionsIfNeeded(astBuilder, nullptr, DeclRef(declRef.getDecl()->parentDecl))));
+}
+
+SLANG_API SlangReflectionType* spReflectionGeneric_GetConcreteType(SlangReflectionGeneric* generic, SlangReflectionVariable* typeParam)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ auto genericType = DeclRefType::create(astBuilder, convert(typeParam));
+
+ auto substType = substituteType(SubstitutionSet(slangGeneric), astBuilder, genericType);
+
+ if (genericType != substType)
+ {
+ return convert(substType);
+ }
+
+ return nullptr;
+}
+
+SLANG_API int64_t spReflectionGeneric_GetConcreteIntVal(SlangReflectionGeneric* generic, SlangReflectionVariable* valueParam)
+{
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return 0;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ auto valueParamDeclRef = convert(valueParam);
+
+ Val* valResult = astBuilder->getOrCreate<GenericParamIntVal>(
+ valueParamDeclRef.substitute(astBuilder, as<GenericValueParamDecl>(valueParamDeclRef.getDecl())->getType()),
+ valueParamDeclRef);
+ valResult = valResult->substitute(astBuilder, SubstitutionSet(slangGeneric));
+
+ auto intVal = as<ConstantIntVal>(valResult);
+ if (intVal)
+ {
+ return intVal->getValue();
+ }
+
+ return 0;
+}
+
+
// Shader Parameter Reflection
SLANG_API unsigned spReflectionParameter_GetBindingIndex(SlangReflectionParameter* inVarLayout)
@@ -3046,7 +3340,7 @@ SLANG_API SlangReflectionFunction* spReflectionEntryPoint_GetFunction(SlangRefle
auto entryPointLayout = convert(inEntryPoint);
if (entryPointLayout)
{
- return convert(entryPointLayout->entryPoint);
+ return convert(entryPointLayout->entryPoint.as<FunctionDeclBase>());
}
return nullptr;
}