summaryrefslogtreecommitdiffstats
path: root/source/slang/parser.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-08-25 15:18:10 -0700
committerTim Foley <tfoley@nvidia.com>2017-08-25 15:48:49 -0700
commit8c68434d6fa6ff1b2e54586637869cceace9d1bb (patch)
tree69f257a9357fa1962ec4a76b258c06abdafef1bc /source/slang/parser.cpp
parent7e05e062a0b7c39dbce6e850227d2038aca2f38e (diff)
Fix some resources-in-structs bugs
Fixes #171 Fixes #172 These two bugs related to bad logic in handling of splitting resource-containing `cbuffer` declarations. - Issue #171 was the case where a `cbuffer` *only* had resource fields, in which case we crashed whenever referencing any field (some code was assuming there had to be non-resource fields) - Issue #172 was a case where two fields were declared with a single declaration (`Texture2D a, b;`), and the logic we had for tracking resource-type fields was accidentally tagging *both* fields with a single modifier so that field `b` would get confused for `a` in some contexts, and attempts to access `b` would crash. Both issues are now fixed, and regression tests have been added.
Diffstat (limited to 'source/slang/parser.cpp')
-rw-r--r--source/slang/parser.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 7ea3fe864..c3969be42 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -549,9 +549,30 @@ namespace Slang
{
RefPtr<Modifier>*& modifierLink = *ioModifierLink;
- while(*modifierLink)
+ // We'd like to add the modifier to the end of the list,
+ // but we need to be careful, in case there is a "shared"
+ // section of modifiers for multiple declarations.
+ //
+ // TODO: This whole approach is a mess because we are "accidentally quadratic"
+ // when adding many modifiers.
+ for(;;)
+ {
+ // At end of the chain? Done.
+ if(!*modifierLink)
+ break;
+
+ // About to look at shared modifiers? Done.
+ RefPtr<Modifier> linkMod = *modifierLink;
+ if(linkMod.As<SharedModifiers>())
+ break;
+
+ // Otherwise: keep traversing the modifier list.
modifierLink = &(*modifierLink)->next;
+ }
+
+ // Splice the modifier into the linked list
+ modifier->next = *modifierLink;
*modifierLink = modifier;
modifierLink = &modifier->next;
}