summaryrefslogtreecommitdiffstats
path: root/source/slang/reflection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/reflection.cpp')
-rw-r--r--source/slang/reflection.cpp158
1 files changed, 157 insertions, 1 deletions
diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp
index 44920fb9f..9a5a5faf9 100644
--- a/source/slang/reflection.cpp
+++ b/source/slang/reflection.cpp
@@ -3,7 +3,7 @@
#include "compiler.h"
#include "type-layout.h"
-
+#include "syntax.h"
#include <assert.h>
// Don't signal errors for stuff we don't implement here,
@@ -18,7 +18,19 @@ using namespace Slang;
// Conversion routines to help with strongly-typed reflection API
+static inline Session* convert(SlangSession* session)
+{
+ return (Session*)session;
+}
+static inline UserDefinedAttribute* convert(SlangReflectionUserAttribute* attrib)
+{
+ return (UserDefinedAttribute*)attrib;
+}
+static inline SlangReflectionUserAttribute* convert(UserDefinedAttribute* attrib)
+{
+ return (SlangReflectionUserAttribute*)attrib;
+}
static inline Type* convert(SlangReflectionType* type)
{
return (Type*) type;
@@ -85,6 +97,101 @@ static inline SlangReflection* convert(ProgramLayout* program)
return (SlangReflection*) program;
}
+// user attaribute
+
+unsigned int getUserAttributeCount(Decl* decl)
+{
+ unsigned int count = 0;
+ for (auto x : decl->GetModifiersOfType<UserDefinedAttribute>())
+ {
+ SLANG_UNUSED(x);
+ count++;
+ }
+ return count;
+}
+
+SlangReflectionUserAttribute* findUserAttributeByName(Session* session, Decl* decl, const char* name)
+{
+ auto nameObj = session->tryGetNameObj(name);
+ for (auto x : decl->GetModifiersOfType<UserDefinedAttribute>())
+ {
+ if (x->name == nameObj)
+ return (SlangReflectionUserAttribute*)(x);
+ }
+ return nullptr;
+}
+
+SlangReflectionUserAttribute* getUserAttributeByIndex(Decl* decl, unsigned int index)
+{
+ unsigned int id = 0;
+ for (auto x : decl->GetModifiersOfType<UserDefinedAttribute>())
+ {
+ if (id == index)
+ return convert(x);
+ id++;
+ }
+ return nullptr;
+}
+
+SLANG_API char const* spReflectionUserAttribute_GetName(SlangReflectionUserAttribute* attrib)
+{
+ auto userAttr = convert(attrib);
+ if (!userAttr) return nullptr;
+ return userAttr->getName()->text.Buffer();
+}
+SLANG_API unsigned int spReflectionUserAttribute_GetArgumentCount(SlangReflectionUserAttribute* attrib)
+{
+ auto userAttr = convert(attrib);
+ if (!userAttr) return 0;
+ return (unsigned int)userAttr->args.Count();
+}
+SlangReflectionType* spReflectionUserAttribute_GetArgumentType(SlangReflectionUserAttribute* attrib, unsigned int index)
+{
+ auto userAttr = convert(attrib);
+ if (!userAttr) return nullptr;
+ return convert(userAttr->args[index]->type.type.Ptr());
+}
+SLANG_API SlangResult spReflectionUserAttribute_GetArgumentValueInt(SlangReflectionUserAttribute* attrib, unsigned int index, int * rs)
+{
+ auto userAttr = convert(attrib);
+ if (!userAttr) return SLANG_ERROR_INVALID_PARAMETER;
+ if (index >= userAttr->args.Count()) return SLANG_ERROR_INVALID_PARAMETER;
+ RefPtr<RefObject> val;
+ if (userAttr->intArgVals.TryGetValue(index, val))
+ {
+ *rs = (int)val.As<ConstantIntVal>()->value;
+ return 0;
+ }
+ return SLANG_ERROR_INVALID_PARAMETER;
+}
+SLANG_API SlangResult spReflectionUserAttribute_GetArgumentValueFloat(SlangReflectionUserAttribute* attrib, unsigned int index, float * rs)
+{
+ auto userAttr = convert(attrib);
+ if (!userAttr) return SLANG_ERROR_INVALID_PARAMETER;
+ if (index >= userAttr->args.Count()) return SLANG_ERROR_INVALID_PARAMETER;
+ if (auto cexpr = userAttr->args[index].As<FloatingPointLiteralExpr>())
+ {
+ *rs = (float)cexpr->value;
+ return 0;
+ }
+ return SLANG_ERROR_INVALID_PARAMETER;
+}
+SLANG_API const char* spReflectionUserAttribute_GetArgumentValueString(SlangReflectionUserAttribute* attrib, unsigned int index, size_t* bufLen)
+{
+ auto userAttr = convert(attrib);
+ if (!userAttr) return nullptr;
+ if (index >= userAttr->args.Count()) return nullptr;
+ if (auto cexpr = userAttr->args[index].As<StringLiteralExpr>())
+ {
+ if (bufLen)
+ *bufLen = cexpr->token.Content.size();
+ return cexpr->token.Content.begin();
+ }
+ return nullptr;
+}
+
+
+
// type Reflection
@@ -352,6 +459,37 @@ SLANG_API SlangScalarType spReflectionType_GetScalarType(SlangReflectionType* in
return SLANG_SCALAR_TYPE_NONE;
}
+SLANG_API unsigned int spReflectionType_GetUserAttributeCount(SlangReflectionType* inType)
+{
+ auto type = convert(inType);
+ if (!type) return 0;
+ if (auto declRefType = type->AsDeclRefType())
+ {
+ return getUserAttributeCount(declRefType->declRef.getDecl());
+ }
+ return 0;
+}
+SLANG_API SlangReflectionUserAttribute* spReflectionType_GetUserAttribute(SlangReflectionType* inType, unsigned int index)
+{
+ auto type = convert(inType);
+ if (!type) return 0;
+ if (auto declRefType = type->AsDeclRefType())
+ {
+ return getUserAttributeByIndex(declRefType->declRef.getDecl(), index);
+ }
+ return 0;
+}
+SLANG_API SlangReflectionUserAttribute* spReflectionType_FindUserAttributeByName(SlangReflectionType* inType, char const* name)
+{
+ auto type = convert(inType);
+ if (!type) return 0;
+ if (auto declRefType = type->AsDeclRefType())
+ {
+ return findUserAttributeByName(declRefType->getSession(), declRefType->declRef.getDecl(), name);
+ }
+ return 0;
+}
+
SLANG_API SlangResourceShape spReflectionType_GetResourceShape(SlangReflectionType* inType)
{
auto type = convert(inType);
@@ -757,6 +895,24 @@ SLANG_API SlangReflectionModifier* spReflectionVariable_FindModifier(SlangReflec
return (SlangReflectionModifier*) modifier;
}
+SLANG_API unsigned int spReflectionVariable_GetUserAttributeCount(SlangReflectionVariable* inVar)
+{
+ auto varDecl = convert(inVar);
+ if (!varDecl) return 0;
+ return getUserAttributeCount(varDecl);
+}
+SLANG_API SlangReflectionUserAttribute* spReflectionVariable_GetUserAttribute(SlangReflectionVariable* inVar, unsigned int index)
+{
+ auto varDecl = convert(inVar);
+ if (!varDecl) return 0;
+ return getUserAttributeByIndex(varDecl, index);
+}
+SLANG_API SlangReflectionUserAttribute* spReflectionVariable_FindUserAttributeByName(SlangReflectionVariable* inVar, SlangSession* session, char const* name)
+{
+ auto varDecl = convert(inVar);
+ if (!varDecl) return 0;
+ return findUserAttributeByName(convert(session), varDecl, name);
+}
// Variable Layout Reflection