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.cpp188
1 files changed, 183 insertions, 5 deletions
diff --git a/source/slang/slang-reflection-api.cpp b/source/slang/slang-reflection-api.cpp
index edfd27489..efa9a20a9 100644
--- a/source/slang/slang-reflection-api.cpp
+++ b/source/slang/slang-reflection-api.cpp
@@ -670,6 +670,17 @@ SLANG_API SlangReflectionUserAttribute* spReflectionType_FindUserAttributeByName
return 0;
}
+SLANG_API SlangReflectionType* spReflectionType_applySpecializations(SlangReflectionType* inType, SlangReflectionGeneric* generic)
+{
+ auto type = convert(inType);
+ auto genericDeclRef = convertGenericToDeclRef(generic);
+
+ if (!type || !genericDeclRef)
+ return nullptr;
+
+ return convert(substituteType(SubstitutionSet(genericDeclRef), type->getASTBuilderForReflection(), type));
+}
+
SLANG_API SlangResourceShape spReflectionType_GetResourceShape(SlangReflectionType* inType)
{
auto type = convert(inType);
@@ -859,6 +870,21 @@ SLANG_API SlangReflectionType * spReflection_FindTypeByName(SlangReflection * re
try
{
Type* result = program->getTypeFromString(name, &sink);
+
+ ASTBuilder* astBuilder = program->getLinkage()->getASTBuilder();
+
+ if (auto genericType = as<GenericDeclRefType>(result))
+ {
+ auto genericDeclRef = genericType->getDeclRef();
+ auto innerDeclRef = substituteDeclRef(
+ SubstitutionSet(genericDeclRef), astBuilder, genericDeclRef.getDecl()->inner);
+ return convert(
+ DeclRefType::create(
+ astBuilder,
+ createDefaultSubstitutionsIfNeeded(
+ astBuilder, nullptr, innerDeclRef)));
+ }
+
if (as<ErrorType>(result))
return nullptr;
return (SlangReflectionType*)result;
@@ -869,6 +895,35 @@ SLANG_API SlangReflectionType * spReflection_FindTypeByName(SlangReflection * re
}
}
+
+SLANG_API bool spReflection_isSubType(
+ SlangReflection * reflection,
+ SlangReflectionType* subType,
+ SlangReflectionType* superType)
+{
+ auto programLayout = convert(reflection);
+ auto program = programLayout->getProgram();
+
+ // TODO: We should extend this API to support getting error messages
+ // when type lookup fails.
+ //
+ Slang::DiagnosticSink sink(
+ programLayout->getTargetReq()->getLinkage()->getSourceManager(),
+ Lexer::sourceLocationLexer);
+
+ try
+ {
+ auto sub = convert(subType);
+ auto super = convert(superType);
+
+ return program->isSubType(sub, super);
+ }
+ catch( ... )
+ {
+ return false;
+ }
+}
+
SlangReflectionGeneric* getInnermostGenericParent(DeclRef<Decl> declRef)
{
auto decl = declRef.getDecl();
@@ -890,12 +945,17 @@ SlangReflectionGeneric* getInnermostGenericParent(DeclRef<Decl> declRef)
SLANG_API SlangReflectionGeneric* spReflectionType_GetGenericContainer(SlangReflectionType* type)
{
- auto declRefType = as<DeclRefType>(convert(type));
- if (!declRefType)
- return nullptr;
+ auto slangType = convert(type);
+ if (auto declRefType = as<DeclRefType>(slangType))
+ {
+ return getInnermostGenericParent(declRefType->getDeclRef());
+ }
+ else if (auto genericDeclRefType = as<GenericDeclRefType>(slangType))
+ {
+ return getInnermostGenericParent(genericDeclRefType->getDeclRef());
+ }
- auto declRef = declRefType->getDeclRef();
- return getInnermostGenericParent(declRef);
+ return nullptr;
}
SLANG_API SlangReflectionTypeLayout* spReflection_GetTypeLayout(
@@ -2778,6 +2838,19 @@ SLANG_API SlangReflectionGeneric* spReflectionVariable_GetGenericContainer(Slang
return getInnermostGenericParent(declRef);
}
+SLANG_API SlangReflectionVariable* spReflectionVariable_applySpecializations(SlangReflectionVariable* var, SlangReflectionGeneric* generic)
+{
+ auto declRef = convert(var);
+ auto genericDeclRef = convertGenericToDeclRef(generic);
+ if (!declRef || !genericDeclRef)
+ return nullptr;
+
+ auto astBuilder = getModule(declRef.getDecl())->getLinkage()->getASTBuilder();
+
+ auto substDeclRef = substituteDeclRef(SubstitutionSet(genericDeclRef), astBuilder, declRef);
+ return convert(substDeclRef);
+}
+
// Variable Layout Reflection
SLANG_API SlangReflectionVariable* spReflectionVariableLayout_GetVariable(SlangReflectionVariableLayout* inVarLayout)
@@ -3002,6 +3075,19 @@ SLANG_API SlangReflectionGeneric* spReflectionFunction_GetGenericContainer(Slang
return getInnermostGenericParent(declRef);
}
+SLANG_API SlangReflectionFunction* spReflectionFunction_applySpecializations(SlangReflectionFunction* func, SlangReflectionGeneric* generic)
+{
+ auto declRef = convert(func);
+ auto genericDeclRef = convertGenericToDeclRef(generic);
+ if (!declRef || !genericDeclRef)
+ return nullptr;
+
+ auto astBuilder = getModule(declRef.getDecl())->getLinkage()->getASTBuilder();
+
+ auto substDeclRef = substituteDeclRef(SubstitutionSet(genericDeclRef), astBuilder, declRef);
+ return convert(substDeclRef.as<FunctionDeclBase>());
+}
+
// Abstract decl reflection
SLANG_API unsigned int spReflectionDecl_getChildrenCount(SlangReflectionDecl* parentDecl)
@@ -3027,6 +3113,16 @@ SLANG_API SlangReflectionDecl* spReflectionDecl_getChild(SlangReflectionDecl* pa
return nullptr;
}
+SLANG_API char const* spReflectionDecl_getName(SlangReflectionDecl* decl)
+{
+ Decl* slangDecl = (Decl*)decl;
+
+ if (auto name = slangDecl->getName())
+ return getText(name).getBuffer();
+
+ return nullptr;
+}
+
SLANG_API SlangDeclKind spReflectionDecl_getKind(SlangReflectionDecl* decl)
{
Decl* slangDecl = (Decl*)decl;
@@ -3050,6 +3146,10 @@ SLANG_API SlangDeclKind spReflectionDecl_getKind(SlangReflectionDecl* decl)
{
return SLANG_DECL_KIND_MODULE;
}
+ else if (as<NamespaceDecl>(slangDecl))
+ {
+ return SLANG_DECL_KIND_NAMESPACE;
+ }
else
return SLANG_DECL_KIND_UNSUPPORTED_FOR_REFLECTION;
}
@@ -3276,6 +3376,19 @@ SLANG_API int64_t spReflectionGeneric_GetConcreteIntVal(SlangReflectionGeneric*
return 0;
}
+SLANG_API SlangReflectionGeneric* spReflectionGeneric_applySpecializations(SlangReflectionGeneric* currGeneric, SlangReflectionGeneric* generic)
+{
+ auto declRef = convertGenericToDeclRef(currGeneric);
+ auto genericDeclRef = convertGenericToDeclRef(generic);
+ if (!declRef || !genericDeclRef)
+ return nullptr;
+
+ auto astBuilder = getModule(declRef.getDecl())->getLinkage()->getASTBuilder();
+
+ auto substDeclRef = substituteDeclRef(SubstitutionSet(genericDeclRef), astBuilder, declRef);
+ return convertDeclToGeneric(substDeclRef);
+}
+
// Shader Parameter Reflection
@@ -3681,6 +3794,71 @@ SLANG_API SlangReflectionType* spReflection_specializeType(
return convert(specializedType);
}
+
+SLANG_API SlangReflectionGeneric* spReflection_specializeGeneric(
+ SlangReflection* inProgramLayout,
+ SlangReflectionGeneric* generic,
+ SlangInt argCount,
+ SlangReflectionGenericArgType const* argTypes,
+ SlangReflectionGenericArg const* args,
+ ISlangBlob** outDiagnostics)
+{
+ auto programLayout = convert(inProgramLayout);
+ auto slangGeneric = convertGenericToDeclRef(generic);
+ if (!slangGeneric) return nullptr;
+ auto astBuilder = getModule(slangGeneric.getDecl())->getLinkage()->getASTBuilder();
+
+ auto linkage = programLayout->getProgram()->getLinkage();
+
+ DiagnosticSink sink(linkage->getSourceManager(), Lexer::sourceLocationLexer);
+
+ List<Expr*> argExprs;
+ for (SlangInt i = 0; i < argCount; ++i)
+ {
+ auto argType = argTypes[i];
+ auto arg = args[i];
+
+ switch (argType)
+ {
+ case SLANG_GENERIC_ARG_TYPE:
+ {
+ auto type = convert(arg.typeVal);
+ auto declRefType = as<DeclRefType>(type);
+ auto declRefExpr = astBuilder->create<DeclRefExpr>();
+ declRefExpr->declRef = declRefType->getDeclRef();
+ declRefExpr->type.type = astBuilder->getOrCreate<TypeType>(type);
+ argExprs.add(declRefExpr);
+ break;
+ }
+ case SLANG_GENERIC_ARG_INT:
+ {
+ auto literalExpr = astBuilder->create<IntegerLiteralExpr>();
+ literalExpr->value = args[i].intVal;
+ literalExpr->type = astBuilder->getIntType();
+ argExprs.add(literalExpr);
+ break;
+ }
+ case SLANG_GENERIC_ARG_BOOL:
+ {
+ auto literalExpr = astBuilder->create<BoolLiteralExpr>();
+ literalExpr->value = args[i].boolVal;
+ literalExpr->type = astBuilder->getBoolType();
+ argExprs.add(literalExpr);
+ break;
+ }
+ default:
+ // abort (TODO: throw a proper error)
+ return nullptr;
+ }
+ }
+
+ auto specialized = linkage->specializeGeneric(slangGeneric, argExprs, &sink);
+ sink.getBlobIfNeeded(outDiagnostics);
+
+ return convertDeclToGeneric(specialized);
+}
+
+
SLANG_API SlangUInt spReflection_getHashedStringCount(
SlangReflection* reflection)
{