diff options
Diffstat (limited to 'source/slang/slang-reflection-api.cpp')
| -rw-r--r-- | source/slang/slang-reflection-api.cpp | 342 |
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; } |
