Skip to content

Commit e9caf5d

Browse files
authoredNov 21, 2024
Change how DeclRef::toText works (shader-slang#5592)
* Change how DeclRef::toText works We now ignore the decl-ref heirarchy since that only includes nodes with specialization info & simply walk up the tree of decls, while emitting any specializations present in the decl-ref. * Update some tests. Add cases for direct refs to generic params & Lookup decl refs
1 parent 3d36e0c commit e9caf5d

File tree

4 files changed

+86
-6
lines changed

4 files changed

+86
-6
lines changed
 

‎source/slang/slang-ast-decl-ref.cpp

+76-1
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,82 @@ DeclRefBase* DeclRefBase::getBase()
312312
}
313313
void DeclRefBase::toText(StringBuilder& out)
314314
{
315-
SLANG_AST_NODE_VIRTUAL_CALL(DeclRefBase, toText, (out));
315+
if (auto lookupDeclRef = as<LookupDeclRef>(this))
316+
{
317+
lookupDeclRef->_toTextOverride(out);
318+
return;
319+
}
320+
321+
if (as<GenericTypeParamDecl>(this->getDecl()))
322+
{
323+
SLANG_ASSERT(as<DirectDeclRef>(this));
324+
out << this->getDecl()->getName()->text;
325+
return;
326+
}
327+
else if (as<GenericValueParamDecl>(this->getDecl()))
328+
{
329+
SLANG_ASSERT(as<DirectDeclRef>(this));
330+
out << this->getDecl()->getName()->text;
331+
return;
332+
}
333+
334+
SubstitutionSet substSet(this);
335+
336+
List<Decl*> decls;
337+
for (auto dd = getDecl(); dd; dd = dd->parentDecl)
338+
{
339+
// Skip the top-level decl.
340+
if (as<ModuleDecl>(dd))
341+
continue;
342+
343+
// Skip base decls in generic containers. We will handle them when we handle the generic
344+
// decl.
345+
//
346+
if (dd->parentDecl && as<GenericDecl>(dd->parentDecl))
347+
continue;
348+
349+
decls.add(dd);
350+
}
351+
352+
decls.reverse();
353+
354+
bool first = true;
355+
for (auto decl : decls)
356+
{
357+
if (!first)
358+
out << ".";
359+
first = false;
360+
361+
if (auto name = decl->getName())
362+
{
363+
out << name->text;
364+
365+
// If there are any specializations for this decl, emit them here:
366+
if (auto genericDecl = as<GenericDecl>(decl))
367+
{
368+
if (auto genericAppDeclRef = substSet.findGenericAppDeclRef(genericDecl))
369+
{
370+
Index paramCount = 0;
371+
for (auto member : genericDecl->members)
372+
if (as<GenericTypeParamDeclBase>(member) ||
373+
as<GenericValueParamDecl>(member))
374+
paramCount++;
375+
out << "<";
376+
auto args = genericAppDeclRef->getArgs();
377+
Index argCount = args.getCount();
378+
for (Index aa = 0; aa < Math::Min(paramCount, argCount); ++aa)
379+
{
380+
if (aa != 0)
381+
out << ", ";
382+
args[aa]->toText(out);
383+
}
384+
out << ">";
385+
}
386+
}
387+
388+
// TODO: What do we do about extensions?
389+
}
390+
}
316391
}
317392

318393
Name* DeclRefBase::getName() const

‎tests/diagnostics/mismatching-types.slang.expected

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ tests/diagnostics/mismatching-types.slang(57): error 30019: expected an expressi
1515
tests/diagnostics/mismatching-types.slang(59): error 30019: expected an expression of type 'GenericOuter<int>.NonGenericInner', got 'GenericOuter<float>.NonGenericInner'
1616
a.ng = b.ng;
1717
^~
18-
tests/diagnostics/mismatching-types.slang(61): error 30019: expected an expression of type 'GenericInner<int>', got 'int'
18+
tests/diagnostics/mismatching-types.slang(61): error 30019: expected an expression of type 'NonGenericOuter.GenericInner<int>', got 'int'
1919
c.i = 0;
2020
^
21-
tests/diagnostics/mismatching-types.slang(63): error 30019: expected an expression of type 'GenericInner<int>', got 'GenericInner<float>'
21+
tests/diagnostics/mismatching-types.slang(63): error 30019: expected an expression of type 'NonGenericOuter.GenericInner<int>', got 'NonGenericOuter.GenericInner<float>'
2222
c.i = c.f;
2323
^
24-
tests/diagnostics/mismatching-types.slang(65): error 30019: expected an expression of type 'GenericInner<int>.ReallyNested', got 'int'
24+
tests/diagnostics/mismatching-types.slang(65): error 30019: expected an expression of type 'NonGenericOuter.GenericInner<int>.ReallyNested', got 'int'
2525
c.i.n = 0;
2626
^
2727
tests/diagnostics/mismatching-types.slang(74): error 30019: expected an expression of type 'Texture1D<int>', got 'Texture1D<float>'

‎tools/slang-unit-test/unit-test-decl-tree-reflection.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,6 @@ SLANG_UNIT_TEST(declTreeReflection)
242242
{
243243
auto type = compositeProgram->getLayout()->findTypeByName("MyGenericType<half>");
244244
SLANG_CHECK(type != nullptr);
245-
// SLANG_CHECK(type->getKind() == slang::DeclReflection::Kind::Struct);
246245
SLANG_CHECK(getTypeFullName(type) == "MyGenericType<half>");
247246
auto funcReflection = compositeProgram->getLayout()->findFunctionByNameInType(type, "g");
248247
SLANG_CHECK(funcReflection != nullptr);
@@ -485,6 +484,12 @@ SLANG_UNIT_TEST(declTreeReflection)
485484
SLANG_CHECK(getTypeFullName(specializedMethodWithFloat->getReturnType()) == "float");
486485
}
487486

487+
// Check getTypeFullName() on nested objects.
488+
{
489+
auto structType = compositeProgram->getLayout()->findTypeByName("MyNamespace::MyStruct");
490+
SLANG_CHECK(getTypeFullName(structType) == "MyNamespace.MyStruct");
491+
}
492+
488493
// Check iterators
489494
{
490495
unsigned int count = 0;

0 commit comments

Comments
 (0)