summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2020-04-08 10:56:00 -0400
committerGitHub <noreply@github.com>2020-04-08 10:56:00 -0400
commita9214f34358b2fc0bf61ef90e3719a13b180b423 (patch)
tree115b49d976f871a9f529436e201cf2f4a1a59401
parentba232e44cbb016a4e7c111b42458394027369c5e (diff)
Remove static struct members from layout and reflection (#1310)
* * Added MemberFilterStyle - controls action of FilteredMemberList and FilteredMemberRefList * Splt out template implementations * Use more standard method names dofr FilteredMemberRefList * Added reflect-static.slang test * Added isNotEmpty/isEmpty to filtered lists * Added ability to index into filtered list (so not require building of array) * Default MemberFilterStyle to All. * Remove explicit MemberFilterStyle::All
-rw-r--r--source/slang/slang-check-conversion.cpp2
-rw-r--r--source/slang/slang-check-decl.cpp4
-rw-r--r--source/slang/slang-check-overload.cpp4
-rw-r--r--source/slang/slang-check-shader.cpp5
-rw-r--r--source/slang/slang-lower-to-ir.cpp34
-rw-r--r--source/slang/slang-mangle.cpp2
-rw-r--r--source/slang/slang-parameter-binding.cpp2
-rw-r--r--source/slang/slang-reflection.cpp7
-rw-r--r--source/slang/slang-syntax.cpp146
-rw-r--r--source/slang/slang-syntax.h211
-rw-r--r--source/slang/slang-type-layout.cpp6
-rw-r--r--source/slang/slang-type-layout.h2
-rw-r--r--tests/reflection/reflect-static.slang34
-rw-r--r--tests/reflection/reflect-static.slang.expected125
14 files changed, 446 insertions, 138 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 4b781643e..f14855fba 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -379,7 +379,7 @@ namespace Slang
// We will go through the fields in order and try to match them
// up with initializer arguments.
//
- for(auto fieldDeclRef : getMembersOfType<VarDecl>(toStructDeclRef))
+ for(auto fieldDeclRef : getMembersOfType<VarDecl>(toStructDeclRef, MemberFilterStyle::Instance))
{
RefPtr<Expr> coercedArg;
bool argResult = _readValueFromInitializerList(
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index 5054b00bc..fef24e920 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -2314,8 +2314,8 @@ namespace Slang
{
// TODO(tfoley): This copies the parameter array, which is bad for performance.
- auto fstParams = GetParameters(fst).ToArray();
- auto sndParams = GetParameters(snd).ToArray();
+ auto fstParams = GetParameters(fst).toArray();
+ auto sndParams = GetParameters(snd).toArray();
// If the functions have different numbers of parameters, then
// their signatures trivially don't match.
diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp
index 0cad2875a..8eba71767 100644
--- a/source/slang/slang-check-overload.cpp
+++ b/source/slang/slang-check-overload.cpp
@@ -219,7 +219,7 @@ namespace Slang
switch (candidate.flavor)
{
case OverloadCandidate::Flavor::Func:
- params = GetParameters(candidate.item.declRef.as<CallableDecl>()).ToArray();
+ params = GetParameters(candidate.item.declRef.as<CallableDecl>()).toArray();
break;
case OverloadCandidate::Flavor::Generic:
@@ -904,7 +904,7 @@ namespace Slang
// to match it up with the arguments accordingly...
if (auto funcDeclRef = unspecializedInnerRef.as<CallableDecl>())
{
- auto params = GetParameters(funcDeclRef).ToArray();
+ auto params = GetParameters(funcDeclRef).toArray();
Index argCount = context.getArgCount();
Index paramCount = params.getCount();
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp
index 53c3f8d89..b8a2a1d5e 100644
--- a/source/slang/slang-check-shader.cpp
+++ b/source/slang/slang-check-shader.cpp
@@ -92,11 +92,8 @@ namespace Slang
// A structure type should recursively introduce
// existential slots for its fields.
//
- for( auto fieldDeclRef : GetFields(structDeclRef) )
+ for( auto fieldDeclRef : GetFields(structDeclRef, MemberFilterStyle::Instance) )
{
- if(fieldDeclRef.getDecl()->HasModifier<HLSLStaticModifier>())
- continue;
-
_collectExistentialSpecializationParamsRec(
ioSpecializationParams,
fieldDeclRef);
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index a52f67b8a..009e776bb 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -582,7 +582,7 @@ LoweredValInfo emitCallToDeclRef(
DeclRef<GetterDecl> getterDeclRef;
bool justAGetter = true;
- for (auto accessorDeclRef : getMembersOfType<AccessorDecl>(subscriptDeclRef))
+ for (auto accessorDeclRef : getMembersOfType<AccessorDecl>(subscriptDeclRef, MemberFilterStyle::Instance))
{
// We want to track whether this subscript has any accessors other than
// `get` (assuming that everything except `get` can be used for setting...).
@@ -786,8 +786,8 @@ top:
// in case the `get` operation has a natural translation for
// a target, while the general `ref` case does not...)
- auto getters = getMembersOfType<GetterDecl>(boundSubscriptInfo->declRef);
- if (getters.Count())
+ auto getters = getMembersOfType<GetterDecl>(boundSubscriptInfo->declRef, MemberFilterStyle::Instance);
+ if (getters.getCount())
{
lowered = emitCallToDeclRef(
context,
@@ -798,8 +798,8 @@ top:
goto top;
}
- auto refAccessors = getMembersOfType<RefAccessorDecl>(boundSubscriptInfo->declRef);
- if(refAccessors.Count())
+ auto refAccessors = getMembersOfType<RefAccessorDecl>(boundSubscriptInfo->declRef, MemberFilterStyle::Instance);
+ if(refAccessors.getCount())
{
// The `ref` accessor will return a pointer to the value, so
// we need to reflect that in the type of our `call` instruction.
@@ -2198,11 +2198,8 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
if (auto aggTypeDeclRef = declRef.as<AggTypeDecl>())
{
List<IRInst*> args;
- for (auto ff : getMembersOfType<VarDecl>(aggTypeDeclRef))
+ for (auto ff : getMembersOfType<VarDecl>(aggTypeDeclRef, MemberFilterStyle::Instance))
{
- if (ff.getDecl()->HasModifier<HLSLStaticModifier>())
- continue;
-
auto irFieldVal = getSimpleVal(context, getDefaultVal(ff));
args.add(irFieldVal);
}
@@ -2322,11 +2319,8 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
if (auto aggTypeDeclRef = declRef.as<AggTypeDecl>())
{
UInt argCounter = 0;
- for (auto ff : getMembersOfType<VarDecl>(aggTypeDeclRef))
+ for (auto ff : getMembersOfType<VarDecl>(aggTypeDeclRef, MemberFilterStyle::Instance))
{
- if (ff.getDecl()->HasModifier<HLSLStaticModifier>())
- continue;
-
UInt argIndex = argCounter++;
if (argIndex < argCount)
{
@@ -3908,15 +3902,15 @@ LoweredValInfo tryGetAddress(
// where we really want/need a pointer to be able to make progress.
//
if(mode != TryGetAddressMode::Aggressive
- && getMembersOfType<SetterDecl>(subscriptInfo->declRef).Count())
+ && getMembersOfType<SetterDecl>(subscriptInfo->declRef, MemberFilterStyle::Instance).isNonEmpty())
{
// There is a setter that we should consider using,
// so don't go and aggressively collapse things just yet.
return val;
}
- auto refAccessors = getMembersOfType<RefAccessorDecl>(subscriptInfo->declRef);
- if(refAccessors.Count())
+ auto refAccessors = getMembersOfType<RefAccessorDecl>(subscriptInfo->declRef, MemberFilterStyle::Instance);
+ if(refAccessors.isNonEmpty())
{
// The `ref` accessor will return a pointer to the value, so
// we need to reflect that in the type of our `call` instruction.
@@ -4140,8 +4134,8 @@ top:
auto subscriptInfo = left.getBoundSubscriptInfo();
// Search for an appropriate "setter" declaration
- auto setters = getMembersOfType<SetterDecl>(subscriptInfo->declRef);
- if (setters.Count())
+ auto setters = getMembersOfType<SetterDecl>(subscriptInfo->declRef, MemberFilterStyle::Instance);
+ if (setters.isNonEmpty())
{
auto allArgs = subscriptInfo->args;
addArgs(context, &allArgs, right);
@@ -4155,8 +4149,8 @@ top:
return;
}
- auto refAccessors = getMembersOfType<RefAccessorDecl>(subscriptInfo->declRef);
- if(refAccessors.Count())
+ auto refAccessors = getMembersOfType<RefAccessorDecl>(subscriptInfo->declRef, MemberFilterStyle::Instance);
+ if(refAccessors.isNonEmpty())
{
// The `ref` accessor will return a pointer to the value, so
// we need to reflect that in the type of our `call` instruction.
diff --git a/source/slang/slang-mangle.cpp b/source/slang/slang-mangle.cpp
index 2ad84d3d3..19e6ed234 100644
--- a/source/slang/slang-mangle.cpp
+++ b/source/slang/slang-mangle.cpp
@@ -358,7 +358,7 @@ namespace Slang
if( auto callableDeclRef = declRef.as<CallableDecl>())
{
auto parameters = GetParameters(callableDeclRef);
- UInt parameterCount = parameters.Count();
+ UInt parameterCount = parameters.getCount();
emitRaw(context, "p");
emit(context, parameterCount);
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index 786433836..353888b69 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -1911,7 +1911,7 @@ static RefPtr<TypeLayout> processEntryPointVaryingParameter(
//
Decl* firstExplicit = nullptr;
Decl* firstImplicit = nullptr;
- for( auto field : GetFields(structDeclRef) )
+ for( auto field : GetFields(structDeclRef, MemberFilterStyle::Instance) )
{
RefPtr<VarLayout> fieldVarLayout = new VarLayout();
fieldVarLayout->varDecl = field;
diff --git a/source/slang/slang-reflection.cpp b/source/slang/slang-reflection.cpp
index fe709222b..a3cb88892 100644
--- a/source/slang/slang-reflection.cpp
+++ b/source/slang/slang-reflection.cpp
@@ -304,7 +304,7 @@ SLANG_API unsigned int spReflectionType_GetFieldCount(SlangReflectionType* inTyp
auto declRef = declRefType->declRef;
if( auto structDeclRef = declRef.as<StructDecl>())
{
- return GetFields(structDeclRef).Count();
+ return (unsigned int)GetFields(structDeclRef, MemberFilterStyle::Instance).getCount();
}
}
@@ -323,7 +323,8 @@ SLANG_API SlangReflectionVariable* spReflectionType_GetFieldByIndex(SlangReflect
auto declRef = declRefType->declRef;
if( auto structDeclRef = declRef.as<StructDecl>())
{
- auto fieldDeclRef = GetFields(structDeclRef).ToArray()[index];
+ auto fields = GetFields(structDeclRef, MemberFilterStyle::Instance);
+ auto fieldDeclRef = fields[index];
return (SlangReflectionVariable*) fieldDeclRef.getDecl();
}
}
@@ -1405,7 +1406,7 @@ SLANG_API SlangReflectionType* spReflectionTypeParameter_GetConstraintByIndex(Sl
if( auto globalGenericParamDecl = as<GlobalGenericParamDecl>(genericParamLayout->decl) )
{
auto constraints = globalGenericParamDecl->getMembersOfType<GenericTypeConstraintDecl>();
- return (SlangReflectionType*)constraints.toArray()[index]->sup.Ptr();
+ return (SlangReflectionType*)constraints[index]->sup.Ptr();
}
// TODO: Add case for entry-point generic parameters.
}
diff --git a/source/slang/slang-syntax.cpp b/source/slang/slang-syntax.cpp
index 1dcaafec5..334273870 100644
--- a/source/slang/slang-syntax.cpp
+++ b/source/slang/slang-syntax.cpp
@@ -184,12 +184,154 @@ static bool _checkSubClassRange()
return SLANG_OK;
}
+ // Free functions
-void Type::accept(IValVisitor* visitor, void* extra)
+const RefPtr<Decl>* adjustFilterCursorImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end)
{
- accept((ITypeVisitor*)visitor, extra);
+ switch (filterStyle)
+ {
+ default:
+ case MemberFilterStyle::All:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ if (decl->getClassInfo().isSubClassOf(clsInfo))
+ {
+ return ptr;
+ }
+ }
+ break;
+ }
+ case MemberFilterStyle::Instance:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ if (decl->getClassInfo().isSubClassOf(clsInfo) && !decl->HasModifier<HLSLStaticModifier>())
+ {
+ return ptr;
+ }
+ }
+ break;
+ }
+ case MemberFilterStyle::Static:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ if (decl->getClassInfo().isSubClassOf(clsInfo) && decl->HasModifier<HLSLStaticModifier>())
+ {
+ return ptr;
+ }
+ }
+ break;
+ }
+ }
+ return end;
+}
+
+const RefPtr<Decl>* getFilterCursorByIndexImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end, Index index)
+{
+ switch (filterStyle)
+ {
+ default:
+ case MemberFilterStyle::All:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ if (decl->getClassInfo().isSubClassOf(clsInfo))
+ {
+ if (index <= 0)
+ {
+ return ptr;
+ }
+ index--;
+ }
+ }
+ break;
+ }
+ case MemberFilterStyle::Instance:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ if (decl->getClassInfo().isSubClassOf(clsInfo) && !decl->HasModifier<HLSLStaticModifier>())
+ {
+ if (index <= 0)
+ {
+ return ptr;
+ }
+ index--;
+ }
+ }
+ break;
+ }
+ case MemberFilterStyle::Static:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ if (decl->getClassInfo().isSubClassOf(clsInfo) && decl->HasModifier<HLSLStaticModifier>())
+ {
+ if (index <= 0)
+ {
+ return ptr;
+ }
+ index--;
+ }
+ }
+ break;
+ }
+ }
+ return nullptr;
}
+Index getFilterCountImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end)
+{
+ Index count = 0;
+ switch (filterStyle)
+ {
+ default:
+ case MemberFilterStyle::All:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ count += Index(decl->getClassInfo().isSubClassOf(clsInfo));
+ }
+ break;
+ }
+ case MemberFilterStyle::Instance:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ count += Index(decl->getClassInfo().isSubClassOf(clsInfo)&& !decl->HasModifier<HLSLStaticModifier>());
+ }
+ break;
+ }
+ case MemberFilterStyle::Static:
+ {
+ for (; ptr != end; ptr++)
+ {
+ Decl* decl = *ptr;
+ count += Index(decl->getClassInfo().isSubClassOf(clsInfo) && decl->HasModifier<HLSLStaticModifier>());
+ }
+ break;
+ }
+ }
+ return count;
+}
+
+ // Type
+
+ void Type::accept(IValVisitor* visitor, void* extra)
+ {
+ accept((ITypeVisitor*)visitor, extra);
+ }
+
// TypeExp
bool TypeExp::Equals(Type* other)
diff --git a/source/slang/slang-syntax.h b/source/slang/slang-syntax.h
index 061ca4d26..db9b7284b 100644
--- a/source/slang/slang-syntax.h
+++ b/source/slang/slang-syntax.h
@@ -754,6 +754,43 @@ namespace Slang
return DeclRef<T>(decl, nullptr);
}
+ enum class MemberFilterStyle
+ {
+ All, ///< All members
+ Instance, ///< Only instance members
+ Static, ///< Only static (ie non instance) members
+ };
+
+ const RefPtr<Decl>* adjustFilterCursorImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end);
+ const RefPtr<Decl>* getFilterCursorByIndexImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end, Index index);
+ Index getFilterCountImpl(const SyntaxClassBase::ClassInfo& clsInfo, MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end);
+
+
+ template <typename T>
+ const RefPtr<Decl>* adjustFilterCursor(MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end)
+ {
+ return adjustFilterCursorImpl(SyntaxClassBase::Impl<T>::kClassInfo, filterStyle, ptr, end);
+ }
+
+ /// Finds the element at index. If there is no element at the index (for example has too few elements), returns nullptr.
+ template <typename T>
+ const RefPtr<Decl>* getFilterCursorByIndex(MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end, Index index)
+ {
+ return getFilterCursorByIndexImpl(SyntaxClassBase::Impl<T>::kClassInfo, filterStyle, ptr, end, index);
+ }
+
+ template <typename T>
+ Index getFilterCount(MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end)
+ {
+ return getFilterCountImpl(SyntaxClassBase::Impl<T>::kClassInfo, filterStyle, ptr, end);
+ }
+
+ template <typename T>
+ bool isFilterNonEmpty(MemberFilterStyle filterStyle, const RefPtr<Decl>* ptr, const RefPtr<Decl>* end)
+ {
+ return adjustFilterCursorImpl(SyntaxClassBase::Impl<T>::kClassInfo, filterStyle, ptr, end) != end;
+ }
+
template<typename T>
struct FilteredMemberList
{
@@ -765,69 +802,59 @@ namespace Slang
{}
explicit FilteredMemberList(
- List<Element> const& list)
- : m_begin(adjust(list.begin(), list.end()))
+ List<Element> const& list,
+ MemberFilterStyle filterStyle = MemberFilterStyle::All)
+ : m_begin(adjustFilterCursor<T>(filterStyle, list.begin(), list.end()))
, m_end(list.end())
+ , m_filterStyle(filterStyle)
{}
struct Iterator
{
const Element* m_cursor;
const Element* m_end;
+ MemberFilterStyle m_filterStyle;
- bool operator!=(Iterator const& other)
- {
- return m_cursor != other.m_cursor;
- }
+ bool operator!=(Iterator const& other) const { return m_cursor != other.m_cursor; }
- void operator++()
- {
- m_cursor = adjust(m_cursor + 1, m_end);
- }
+ void operator++() { m_cursor = adjustFilterCursor<T>(m_filterStyle, m_cursor + 1, m_end); }
- const RefPtr<T>& operator*()
- {
- return *(RefPtr<T>*)(m_cursor);
- }
+ const RefPtr<T>& operator*() { return *(RefPtr<T>*)(m_cursor); }
};
Iterator begin()
{
- Iterator iter = { m_begin, m_end };
+ Iterator iter = { m_begin, m_end, m_filterStyle };
return iter;
}
Iterator end()
{
- Iterator iter = { m_end, m_end };
+ Iterator iter = { m_end, m_end, m_filterStyle };
return iter;
}
- static const Element* adjust(const Element* cursor, const Element* end)
- {
- while (cursor != end)
- {
- if (as<T>(*cursor))
- return cursor;
- cursor++;
- }
- return cursor;
- }
-
// TODO(tfoley): It is ugly to have these.
// We should probably fix the call sites instead.
const RefPtr<T>& getFirst() { return *begin(); }
- Index getCount()
+ Index getCount() { return getFilterCount<T>(m_filterStyle, m_begin, m_end); }
+
+ RefPtr<T> operator[](Index index) const
{
- Index count = 0;
- for (auto iter : (*this))
- {
- (void)iter;
- count++;
- }
- return count;
+ const RefPtr<Decl>* ptr = getFilterCursorByIndex<T>(m_filterStyle, m_begin, m_end, index);
+ SLANG_ASSERT(ptr);
+ return *(RefPtr<T>*)(ptr);
}
+ /// Returns true if empty (equivalent to getCount() == 0)
+ bool isEmpty() const
+ {
+ /// Note we don't have to scan, because m_begin has already been adjusted, when the FilteredMemberList is constructed
+ return m_begin == m_end;
+ }
+ /// Returns true if non empty (equivalent to getCount() != 0 but faster)
+ bool isNonEmpty() const { return !isEmpty(); }
+
List<RefPtr<T>> toArray()
{
List<RefPtr<T>> result;
@@ -837,12 +864,10 @@ namespace Slang
}
return result;
}
-
- bool isEmpty() const { return m_end == m_begin; }
- bool isNonEmpty() const { return m_end != m_begin; }
-
- const Element* m_begin;
+
+ const Element* m_begin; ///< Is either equal to m_end, or points to first *valid* filtered member
const Element* m_end;
+ MemberFilterStyle m_filterStyle;
};
struct TransparentMemberInfo
@@ -854,25 +879,34 @@ namespace Slang
template<typename T>
struct FilteredMemberRefList
{
- List<RefPtr<Decl>> const& decls;
- SubstitutionSet substitutions;
+ List<RefPtr<Decl>> const& m_decls;
+ SubstitutionSet m_substitutions;
+ MemberFilterStyle m_filterStyle;
FilteredMemberRefList(
List<RefPtr<Decl>> const& decls,
- SubstitutionSet substitutions)
- : decls(decls)
- , substitutions(substitutions)
+ SubstitutionSet substitutions,
+ MemberFilterStyle filterStyle = MemberFilterStyle::All)
+ : m_decls(decls)
+ , m_substitutions(substitutions)
+ , m_filterStyle(filterStyle)
{}
- int Count() const
+ Index getCount() const { return getFilterCount<T>(m_filterStyle, m_decls.begin(), m_decls.end()); }
+
+ /// True if empty (equivalent to getCount == 0, but faster)
+ bool isEmpty() const { return !isNonEmpty(); }
+ /// True if non empty (equivalent to getCount() != 0 but faster)
+ bool isNonEmpty() const { return isFilterNonEmpty<T>(m_filterStyle, m_decls.begin(), m_decls.end()); }
+
+ DeclRef<T> operator[](Index index) const
{
- int count = 0;
- for (auto d : *this)
- count++;
- return count;
+ const RefPtr<Decl>* decl = getFilterCursorByIndex<T>(m_filterStyle, m_decls.begin(), m_decls.end(), index);
+ SLANG_ASSERT(decl);
+ return DeclRef<T>((T*) decl->Ptr(), m_substitutions);
}
- List<DeclRef<T>> ToArray() const
+ List<DeclRef<T>> toArray() const
{
List<DeclRef<T>> result;
for (auto d : *this)
@@ -882,50 +916,33 @@ namespace Slang
struct Iterator
{
- FilteredMemberRefList const* list;
- const RefPtr<Decl>* ptr;
- const RefPtr<Decl>* end;
+ FilteredMemberRefList const* m_list;
+ const RefPtr<Decl>* m_ptr;
+ const RefPtr<Decl>* m_end;
+ MemberFilterStyle m_filterStyle;
- Iterator() : list(nullptr), ptr(nullptr) {}
+ Iterator() : m_list(nullptr), m_ptr(nullptr), m_filterStyle(MemberFilterStyle::All) {}
Iterator(
- FilteredMemberRefList const* inList,
- const RefPtr<Decl>* inPtr,
- const RefPtr<Decl>* inEnd)
- : list(inList)
- , ptr(inPtr)
- , end(inEnd)
+ FilteredMemberRefList const* list,
+ const RefPtr<Decl>* ptr,
+ const RefPtr<Decl>* end,
+ MemberFilterStyle filterStyle
+ )
+ : m_list(list)
+ , m_ptr(ptr)
+ , m_end(end)
+ , m_filterStyle(filterStyle)
{}
- bool operator!=(Iterator other)
- {
- return ptr != other.ptr;
- }
+ bool operator!=(const Iterator& other) const { return m_ptr != other.m_ptr; }
- void operator++()
- {
- ptr = list->Adjust(ptr + 1, end);
- }
+ void operator++() { m_ptr = adjustFilterCursor<T>(m_filterStyle, m_ptr + 1, m_end); }
- DeclRef<T> operator*()
- {
- return DeclRef<T>((T*) ptr->Ptr(), list->substitutions);
- }
+ DeclRef<T> operator*() { return DeclRef<T>((T*) m_ptr->Ptr(), m_list->m_substitutions); }
};
- Iterator begin() const { return Iterator(this, Adjust(decls.begin(), decls.end()), decls.end()); }
- Iterator end() const { return Iterator(this, decls.end(), decls.end()); }
-
- const RefPtr<Decl>* Adjust(const RefPtr<Decl>* ptr, const RefPtr<Decl>* end) const
- {
- for (; ptr != end; ptr++)
- {
- if (ptr->is<T>())
- {
- return ptr;
- }
- }
- return end;
- }
+ Iterator begin() const { return Iterator(this, adjustFilterCursor<T>(m_filterStyle, m_decls.begin(), m_decls.end()), m_decls.end(), m_filterStyle); }
+ Iterator end() const { return Iterator(this, m_decls.end(), m_decls.end(), m_filterStyle); }
};
//
@@ -1400,28 +1417,28 @@ namespace Slang
return declRef.getDecl()->candidateExtensions;
}
- inline FilteredMemberRefList<Decl> getMembers(DeclRef<ContainerDecl> const& declRef)
+ inline FilteredMemberRefList<Decl> getMembers(DeclRef<ContainerDecl> const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All)
{
- return FilteredMemberRefList<Decl>(declRef.getDecl()->Members, declRef.substitutions);
+ return FilteredMemberRefList<Decl>(declRef.getDecl()->Members, declRef.substitutions, filterStyle);
}
template<typename T>
- inline FilteredMemberRefList<T> getMembersOfType(DeclRef<ContainerDecl> const& declRef)
+ inline FilteredMemberRefList<T> getMembersOfType( DeclRef<ContainerDecl> const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All)
{
- return FilteredMemberRefList<T>(declRef.getDecl()->Members, declRef.substitutions);
+ return FilteredMemberRefList<T>(declRef.getDecl()->Members, declRef.substitutions, filterStyle);
}
template<typename T>
- inline List<DeclRef<T>> getMembersOfTypeWithExt(DeclRef<ContainerDecl> const& declRef)
+ inline List<DeclRef<T>> getMembersOfTypeWithExt(DeclRef<ContainerDecl> const& declRef, MemberFilterStyle filterStyle = MemberFilterStyle::All)
{
List<DeclRef<T>> rs;
- for (auto d : getMembersOfType<T>(declRef))
+ for (auto d : getMembersOfType<T>(declRef, filterStyle))
rs.add(d);
if (auto aggDeclRef = declRef.as<AggTypeDecl>())
{
for (auto ext = GetCandidateExtensions(aggDeclRef); ext; ext = ext->nextCandidateExtension)
{
- auto extMembers = getMembersOfType<T>(DeclRef<ContainerDecl>(ext, declRef.substitutions));
+ auto extMembers = getMembersOfType<T>(DeclRef<ContainerDecl>(ext, declRef.substitutions), filterStyle);
for (auto mbr : extMembers)
rs.add(mbr);
}
@@ -1469,11 +1486,13 @@ namespace Slang
return declRef.Substitute(declRef.getDecl()->targetType.Ptr());
}
- inline FilteredMemberRefList<VarDecl> GetFields(DeclRef<StructDecl> const& declRef)
+ inline FilteredMemberRefList<VarDecl> GetFields(DeclRef<StructDecl> const& declRef, MemberFilterStyle filterStyle)
{
- return getMembersOfType<VarDecl>(declRef);
+ return getMembersOfType<VarDecl>(declRef, filterStyle);
}
+
+
inline RefPtr<Type> getBaseType(DeclRef<InheritanceDecl> const& declRef)
{
return declRef.Substitute(declRef.getDecl()->base.type);
diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp
index bd0e6e8e0..f8c2bd377 100644
--- a/source/slang/slang-type-layout.cpp
+++ b/source/slang/slang-type-layout.cpp
@@ -3424,12 +3424,8 @@ static TypeLayoutResult _createTypeLayout(
typeLayoutBuilder.beginLayout(type, rules);
auto typeLayout = typeLayoutBuilder.getTypeLayout();
- for (auto field : GetFields(structDeclRef))
+ for (auto field : GetFields(structDeclRef, MemberFilterStyle::Instance))
{
- // Static fields shouldn't take part in layout.
- if(field.getDecl()->HasModifier<HLSLStaticModifier>())
- continue;
-
// The fields of a `struct` type may include existential (interface)
// types (including as nested sub-fields), and any types present
// in those fields will need to be specialized based on the
diff --git a/source/slang/slang-type-layout.h b/source/slang/slang-type-layout.h
index db51e996a..fdf980fa9 100644
--- a/source/slang/slang-type-layout.h
+++ b/source/slang/slang-type-layout.h
@@ -572,7 +572,7 @@ public:
class StructTypeLayout : public TypeLayout
{
public:
- // An ordered list of layouts for the known fields
+ // An ordered list of layouts for the known per *instance* fields
List<RefPtr<VarLayout>> fields;
// Map a variable to its layout directly.
diff --git a/tests/reflection/reflect-static.slang b/tests/reflection/reflect-static.slang
new file mode 100644
index 000000000..f7a44cde8
--- /dev/null
+++ b/tests/reflection/reflect-static.slang
@@ -0,0 +1,34 @@
+//TEST:REFLECTION:-profile cs_6_0 -target hlsl -entry computeMain
+
+struct Thing
+{
+ static int value;
+};
+
+struct AnotherThing
+{
+ int a;
+ int b;
+ static Texture2D t;
+};
+
+
+ConstantBuffer<Thing> cbThing;
+ConstantBuffer<AnotherThing> cbAnotherThing;
+
+//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer
+RWStructuredBuffer<int> outputBuffer;
+
+[numthreads(4, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ Texture2D t = AnotherThing::t;
+
+ float4 v = t.Load(int3(dispatchThreadID.x, dispatchThreadID.y, 0));
+
+ int m = cbAnotherThing.a + cbAnotherThing.b + Thing::value;
+
+ m += int(v.x);
+
+ outputBuffer[dispatchThreadID.x] = m;
+}
diff --git a/tests/reflection/reflect-static.slang.expected b/tests/reflection/reflect-static.slang.expected
new file mode 100644
index 000000000..46bae4a17
--- /dev/null
+++ b/tests/reflection/reflect-static.slang.expected
@@ -0,0 +1,125 @@
+result code = 0
+standard error = {
+}
+standard output = {
+{
+ "parameters": [
+ {
+ "name": "cbThing",
+ "type": {
+ "kind": "constantBuffer",
+ "elementType": {
+ "kind": "struct",
+ "name": "Thing",
+ "fields": [
+
+ ]
+ },
+ "containerVarLayout": {
+
+ },
+ "elementVarLayout": {
+ "type": {
+ "kind": "struct",
+ "name": "Thing",
+ "fields": [
+
+ ]
+ }
+ }
+ }
+ },
+ {
+ "name": "cbAnotherThing",
+ "binding": {"kind": "constantBuffer", "index": 0},
+ "type": {
+ "kind": "constantBuffer",
+ "elementType": {
+ "kind": "struct",
+ "name": "AnotherThing",
+ "fields": [
+ {
+ "name": "a",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 0, "size": 4}
+ },
+ {
+ "name": "b",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 4, "size": 4}
+ }
+ ]
+ },
+ "containerVarLayout": {
+ "binding": {"kind": "constantBuffer", "index": 0}
+ },
+ "elementVarLayout": {
+ "type": {
+ "kind": "struct",
+ "name": "AnotherThing",
+ "fields": [
+ {
+ "name": "a",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 0, "size": 4}
+ },
+ {
+ "name": "b",
+ "type": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ },
+ "binding": {"kind": "uniform", "offset": 4, "size": 4}
+ }
+ ]
+ },
+ "binding": {"kind": "uniform", "offset": 0, "size": 8}
+ }
+ }
+ },
+ {
+ "name": "outputBuffer",
+ "binding": {"kind": "unorderedAccess", "index": 0},
+ "type": {
+ "kind": "resource",
+ "baseShape": "structuredBuffer",
+ "access": "readWrite",
+ "resultType": {
+ "kind": "scalar",
+ "scalarType": "int32"
+ }
+ }
+ }
+ ],
+ "entryPoints": [
+ {
+ "name": "computeMain",
+ "stage:": "compute",
+ "parameters": [
+ {
+ "name": "dispatchThreadID",
+ "semanticName": "SV_DISPATCHTHREADID",
+ "type": {
+ "kind": "vector",
+ "elementCount": 3,
+ "elementType": {
+ "kind": "scalar",
+ "scalarType": "uint32"
+ }
+ }
+ }
+ ],
+ "threadGroupSize": [4, 1, 1]
+ }
+ ]
+}
+}