diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-decl-defs.h | 15 | ||||
| -rw-r--r-- | source/slang/slang-lookup.cpp | 31 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 2 |
4 files changed, 32 insertions, 19 deletions
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 473b5e5da..97da31f39 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -189,8 +189,7 @@ namespace Slang // attrDecl->ParentDecl = parentDecl; parentDecl->Members.add(attrDecl); - parentDecl->memberDictionaryIsValid = false; - + // Finally, we perform any required semantic checks on // the newly constructed attribute decl. // diff --git a/source/slang/slang-decl-defs.h b/source/slang/slang-decl-defs.h index b4c3bcfd4..7dc58539c 100644 --- a/source/slang/slang-decl-defs.h +++ b/source/slang/slang-decl-defs.h @@ -18,15 +18,20 @@ ABSTRACT_SYNTAX_CLASS(ContainerDecl, Decl) return FilteredMemberList<T>(Members); } + bool isMemberDictionaryValid() const { return dictionaryLastCount == Members.getCount(); } + + void invalidateMemberDictionary() { dictionaryLastCount = -1; } + + // Denotes how much of Members has been placed into the dictionary/transparentMembers. + // If this value equals the Members.getCount(), the dictionary is completely full and valid. + // If it's >= 0, then the Members after dictionaryLastCount are all that need to be added. + // If it < 0 it means that the dictionary/transparentMembers is invalid and needs to be recreated. + Index dictionaryLastCount = 0; // Dictionary for looking up members by name. // This is built on demand before performing lookup. Dictionary<Name*, Decl*> memberDictionary; - - // Whether the `memberDictionary` is valid. - // Should be set to `false` if any members get added/remoed. - bool memberDictionaryIsValid = false; - + // A list of transparent members, to be used in lookup // Note: this is only valid if `memberDictionaryIsValid` is true List<TransparentMemberInfo> transparentMembers; diff --git a/source/slang/slang-lookup.cpp b/source/slang/slang-lookup.cpp index 6a2d31c32..5f2927ccb 100644 --- a/source/slang/slang-lookup.cpp +++ b/source/slang/slang-lookup.cpp @@ -30,24 +30,35 @@ struct BreadcrumbInfo void buildMemberDictionary(ContainerDecl* decl) { // Don't rebuild if already built - if (decl->memberDictionaryIsValid) + if (decl->isMemberDictionaryValid()) return; - decl->memberDictionary.Clear(); - decl->transparentMembers.clear(); + // If it's < 0 it means that the dictionaries are entirely invalid + if (decl->dictionaryLastCount < 0) + { + decl->dictionaryLastCount = 0; + decl->memberDictionary.Clear(); + decl->transparentMembers.clear(); + } // are we a generic? GenericDecl* genericDecl = as<GenericDecl>(decl); - for (auto m : decl->Members) + const Index membersCount = decl->Members.getCount(); + + SLANG_ASSERT(decl->dictionaryLastCount >= 0 && decl->dictionaryLastCount <= membersCount); + + for (Index i = decl->dictionaryLastCount; i < membersCount; ++i) { + Decl* m = decl->Members[i]; + auto name = m->getName(); // Add any transparent members to a separate list for lookup if (m->HasModifier<TransparentModifier>()) { TransparentMemberInfo info; - info.decl = m.Ptr(); + info.decl = m; decl->transparentMembers.add(info); } @@ -59,17 +70,17 @@ void buildMemberDictionary(ContainerDecl* decl) if (genericDecl && m == genericDecl->inner) continue; - m->nextInContainerWithSameName = nullptr; Decl* next = nullptr; if (decl->memberDictionary.TryGetValue(name, next)) m->nextInContainerWithSameName = next; - decl->memberDictionary[name] = m.Ptr(); - + decl->memberDictionary[name] = m; } - decl->memberDictionaryIsValid = true; + + decl->dictionaryLastCount = membersCount; + SLANG_ASSERT(decl->isMemberDictionaryValid()); } @@ -186,7 +197,7 @@ static void _lookUpDirectAndTransparentMembers( ContainerDecl* containerDecl = containerDeclRef.getDecl(); // Ensure that the lookup dictionary in the container is up to date - if (!containerDecl->memberDictionaryIsValid) + if (!containerDecl->isMemberDictionaryValid()) { buildMemberDictionary(containerDecl); } diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index 03f53634d..4ce4c49b5 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -1080,8 +1080,6 @@ namespace Slang { member->ParentDecl = container.Ptr(); container->Members.add(member); - - container->memberDictionaryIsValid = false; } } |
