diff options
Diffstat (limited to 'source/slang/slang-ast-decl.cpp')
| -rw-r--r-- | source/slang/slang-ast-decl.cpp | 321 |
1 files changed, 269 insertions, 52 deletions
diff --git a/source/slang/slang-ast-decl.cpp b/source/slang/slang-ast-decl.cpp index f37ebef48..4d9b8718f 100644 --- a/source/slang/slang-ast-decl.cpp +++ b/source/slang/slang-ast-decl.cpp @@ -51,80 +51,167 @@ bool isInterfaceRequirement(Decl* decl) } // -// ContainerDecl +// ContainerDeclDirectMemberDecls // -List<Decl*> const& ContainerDecl::getDirectMemberDecls() +void ContainerDeclDirectMemberDecls::_initForOnDemandDeserialization( + RefObject* deserializationContext, + void const* deserializationData, + Count declCount) { - return _directMemberDecls.decls; + SLANG_ASSERT(deserializationContext); + SLANG_ASSERT(deserializationData); + + SLANG_ASSERT(!decls.getCount()); + SLANG_ASSERT(!onDemandDeserialization.context); + + onDemandDeserialization.context = deserializationContext; + onDemandDeserialization.data = deserializationData; + + for (Index i = 0; i < declCount; ++i) + decls.add(nullptr); } -Count ContainerDecl::getDirectMemberDeclCount() +void ContainerDeclDirectMemberDecls::_readAllSerializedDecls() const { - return _directMemberDecls.decls.getCount(); + SLANG_ASSERT(isUsingOnDemandDeserialization()); + + // We start by querying each of the contained decls + // by index, which should cause the entire `decls` + // array to be filled in. + // + auto declCount = getDeclCount(); + for (Index i = 0; i < declCount; ++i) + { + auto decl = getDecl(i); + SLANG_UNUSED(decl); + } + + // At this point, we have loaded all the information + // that was in the serialized representation, and + // don't need to keep doing on-demand loading. + // Thus, we clear out the pointer to the serialized + // data (which will cause later calls to + // `isDoingOnDemandSerialization()` to return `false`). + // + // Note that we do *not* clear out the `context` pointer + // used for on-demand deserialization, because in the + // case where we are storing the members of a `ModuleDecl`, + // that context will hold the additional state needed to + // look up declarations by their mangled names, and we + // want to retain that state. The + // `isUsingOnDemandDeserializationForExports()` query + // is based on the `context` pointer only, so it will + // continue to return `true`. + // + onDemandDeserialization.data = nullptr; + + _invalidateLookupAccelerators(); } -Decl* ContainerDecl::getDirectMemberDecl(Index index) +List<Decl*> const& ContainerDeclDirectMemberDecls::getDecls() const { - return _directMemberDecls.decls[index]; + if (isUsingOnDemandDeserialization()) + { + _readAllSerializedDecls(); + } + + return decls; } -Decl* ContainerDecl::getFirstDirectMemberDecl() +Count ContainerDeclDirectMemberDecls::getDeclCount() const { - if (getDirectMemberDeclCount() == 0) - return nullptr; - return getDirectMemberDecl(0); + // Note: in the case of on-demand deserialization, + // the number of elements in the `decls` list + // will be correct, although one or more of the + // pointers in it might be null. + // + return decls.getCount(); } -DeclsOfNameList ContainerDecl::getDirectMemberDeclsOfName(Name* name) +Decl* ContainerDeclDirectMemberDecls::getDecl(Index index) const { - return DeclsOfNameList(findLastDirectMemberDeclOfName(name)); + auto decl = decls[index]; + if (!decl && isUsingOnDemandDeserialization()) + { + decl = _readSerializedDeclAtIndex(index); + decls[index] = decl; + } + return decl; } -Decl* ContainerDecl::findLastDirectMemberDeclOfName(Name* name) +Decl* ContainerDeclDirectMemberDecls::findLastDeclOfName(Name* name) const { - _ensureLookupAcceleratorsAreValid(); - if (auto found = _directMemberDecls.accelerators.mapNameToLastDeclOfThatName.tryGetValue(name)) - return *found; + if (isUsingOnDemandDeserialization()) + { + if (auto found = accelerators.mapNameToLastDeclOfThatName.tryGetValue(name)) + return *found; + + Decl* decl = _readSerializedDeclsOfName(name); + accelerators.mapNameToLastDeclOfThatName.add(name, decl); + return decl; + } + else + { + _ensureLookupAcceleratorsAreValid(); + if (auto found = accelerators.mapNameToLastDeclOfThatName.tryGetValue(name)) + return *found; + } return nullptr; } -Decl* ContainerDecl::getPrevDirectMemberDeclWithSameName(Decl* decl) +Dictionary<Name*, Decl*> ContainerDeclDirectMemberDecls::getMapFromNameToLastDeclOfThatName() const { - SLANG_ASSERT(decl); - SLANG_ASSERT(decl->parentDecl == this); + if (isUsingOnDemandDeserialization()) + { + // If we have been using on-demand deserialization, + // then the `mapNameToLastDeclOfThatName` dictionary + // may not accurately reflect the contained declarations. + // We need to force all of the declarations to be + // deserialized immediately, which will also have + // the effect of invalidating the accelerators so + // that they can be rebuilt to contain complete information. + // + _readAllSerializedDecls(); + } _ensureLookupAcceleratorsAreValid(); - return decl->_prevInContainerWithSameName; + return accelerators.mapNameToLastDeclOfThatName; } -void ContainerDecl::addDirectMemberDecl(Decl* decl) -{ - if (!decl) - return; - decl->parentDecl = this; - _directMemberDecls.decls.add(decl); +List<Decl*> const& ContainerDeclDirectMemberDecls::getTransparentDecls() const +{ + if (isUsingOnDemandDeserialization()) + { + if (accelerators.filteredListOfTransparentDecls.getCount() == 0) + { + _readSerializedTransparentDecls(); + } + } + else + { + _ensureLookupAcceleratorsAreValid(); + } + return accelerators.filteredListOfTransparentDecls; } -List<Decl*> const& ContainerDecl::getTransparentDirectMemberDecls() +bool ContainerDeclDirectMemberDecls::isUsingOnDemandDeserialization() const { - _ensureLookupAcceleratorsAreValid(); - return _directMemberDecls.accelerators.filteredListOfTransparentDecls; + return onDemandDeserialization.data != nullptr; } -bool ContainerDecl::_areLookupAcceleratorsValid() +bool ContainerDeclDirectMemberDecls::_areLookupAcceleratorsValid() const { - return _directMemberDecls.accelerators.declCountWhenLastUpdated == - _directMemberDecls.decls.getCount(); + return accelerators.declCountWhenLastUpdated == decls.getCount(); } -void ContainerDecl::_invalidateLookupAccelerators() +void ContainerDeclDirectMemberDecls::_invalidateLookupAccelerators() const { - _directMemberDecls.accelerators.declCountWhenLastUpdated = -1; + accelerators.declCountWhenLastUpdated = -1; } -void ContainerDecl::_ensureLookupAcceleratorsAreValid() +void ContainerDeclDirectMemberDecls::_ensureLookupAcceleratorsAreValid() const { if (_areLookupAcceleratorsValid()) return; @@ -133,24 +220,28 @@ void ContainerDecl::_ensureLookupAcceleratorsAreValid() // the accelerators are entirely invalidated, and must be rebuilt // from scratch. // - if (_directMemberDecls.accelerators.declCountWhenLastUpdated < 0) + if (accelerators.declCountWhenLastUpdated < 0) { - _directMemberDecls.accelerators.declCountWhenLastUpdated = 0; - _directMemberDecls.accelerators.mapNameToLastDeclOfThatName.clear(); - _directMemberDecls.accelerators.filteredListOfTransparentDecls.clear(); + accelerators.declCountWhenLastUpdated = 0; + accelerators.mapNameToLastDeclOfThatName.clear(); + accelerators.filteredListOfTransparentDecls.clear(); } - // are we a generic? - GenericDecl* genericDecl = as<GenericDecl>(this); - - Count memberCount = _directMemberDecls.decls.getCount(); - Count memberCountWhenLastUpdated = _directMemberDecls.accelerators.declCountWhenLastUpdated; + Count memberCount = decls.getCount(); + Count memberCountWhenLastUpdated = accelerators.declCountWhenLastUpdated; SLANG_ASSERT(memberCountWhenLastUpdated >= 0 && memberCountWhenLastUpdated <= memberCount); + // are we a generic? + GenericDecl* genericDecl = nullptr; + if (memberCount > 0) + { + genericDecl = as<GenericDecl>(decls[0]->parentDecl); + } + for (Index i = memberCountWhenLastUpdated; i < memberCount; ++i) { - Decl* memberDecl = _directMemberDecls.decls[i]; + Decl* memberDecl = decls[i]; // Transparent member declarations will go into a separate list, // so that they can be conveniently queried later for lookup @@ -163,7 +254,7 @@ void ContainerDecl::_ensureLookupAcceleratorsAreValid() // if (memberDecl->hasModifier<TransparentModifier>()) { - _directMemberDecls.accelerators.filteredListOfTransparentDecls.add(memberDecl); + accelerators.filteredListOfTransparentDecls.add(memberDecl); } // Members that don't have a name don't go into the lookup dictionary. @@ -190,9 +281,7 @@ void ContainerDecl::_ensureLookupAcceleratorsAreValid() // all of the overloaded functions with a given name. // Decl* prevMemberWithSameName = nullptr; - _directMemberDecls.accelerators.mapNameToLastDeclOfThatName.tryGetValue( - memberName, - prevMemberWithSameName); + accelerators.mapNameToLastDeclOfThatName.tryGetValue(memberName, prevMemberWithSameName); memberDecl->_prevInContainerWithSameName = prevMemberWithSameName; // Whether or not there was a previous declaration with this @@ -200,18 +289,131 @@ void ContainerDecl::_ensureLookupAcceleratorsAreValid() // with that name encountered so far, and it is what we will // store in the lookup dictionary. // - _directMemberDecls.accelerators.mapNameToLastDeclOfThatName[memberName] = memberDecl; + accelerators.mapNameToLastDeclOfThatName[memberName] = memberDecl; } - _directMemberDecls.accelerators.declCountWhenLastUpdated = memberCount; + accelerators.declCountWhenLastUpdated = memberCount; SLANG_ASSERT(_areLookupAcceleratorsValid()); } + +// +// ContainerDecl +// + +List<Decl*> const& ContainerDecl::getDirectMemberDecls() +{ + return _directMemberDecls.getDecls(); +} + +Count ContainerDecl::getDirectMemberDeclCount() +{ + return _directMemberDecls.getDeclCount(); +} + +Decl* ContainerDecl::getDirectMemberDecl(Index index) +{ + return _directMemberDecls.getDecl(index); +} + +Decl* ContainerDecl::getFirstDirectMemberDecl() +{ + if (getDirectMemberDeclCount() == 0) + return nullptr; + return getDirectMemberDecl(0); +} + +DeclsOfNameList ContainerDecl::getDirectMemberDeclsOfName(Name* name) +{ + return DeclsOfNameList(findLastDirectMemberDeclOfName(name)); +} + +Decl* ContainerDecl::findLastDirectMemberDeclOfName(Name* name) +{ + return _directMemberDecls.findLastDeclOfName(name); +} + +Decl* ContainerDecl::getPrevDirectMemberDeclWithSameName(Decl* decl) +{ + SLANG_ASSERT(decl); + SLANG_ASSERT(decl->parentDecl == this); + + if (isUsingOnDemandDeserializationForDirectMembers()) + { + // Note: in the case of on-demand deserialization, + // we trust that the caller has previously + // invoked `findLastDirectMemberDeclOfName()` + // in order to get `decl` (or an earlier + // entry in the same linked list), so that + // the list threaded through the declarations + // of the same name is already set up. + // + // If that is ever *not* the case, then this + // query would end up returning the wrong results. + + return decl->_prevInContainerWithSameName; + } + else + { + _ensureLookupAcceleratorsAreValid(); + return decl->_prevInContainerWithSameName; + } +} + +void ContainerDecl::addDirectMemberDecl(Decl* decl) +{ + if (isUsingOnDemandDeserializationForDirectMembers()) + { + SLANG_UNEXPECTED("this operation shouldn't be performed on deserialized declarations"); + } + + if (!decl) + return; + + decl->parentDecl = this; + _directMemberDecls.decls.add(decl); +} + +List<Decl*> const& ContainerDecl::getTransparentDirectMemberDecls() +{ + return _directMemberDecls.getTransparentDecls(); +} + +bool ContainerDecl::isUsingOnDemandDeserializationForDirectMembers() +{ + return _directMemberDecls.isUsingOnDemandDeserialization(); +} + +bool ModuleDecl::isUsingOnDemandDeserializationForExports() +{ + return _directMemberDecls.onDemandDeserialization.context != nullptr; +} + +bool ContainerDecl::_areLookupAcceleratorsValid() +{ + return _directMemberDecls._areLookupAcceleratorsValid(); +} + +void ContainerDecl::_invalidateLookupAccelerators() +{ + _directMemberDecls._invalidateLookupAccelerators(); +} + +void ContainerDecl::_ensureLookupAcceleratorsAreValid() +{ + _directMemberDecls._ensureLookupAcceleratorsAreValid(); +} + void ContainerDecl:: _invalidateLookupAcceleratorsBecauseUnscopedEnumAttributeWillBeTurnedIntoTransparentModifier( UnscopedEnumAttribute* unscopedEnumAttr, TransparentModifier* transparentModifier) { + if (isUsingOnDemandDeserializationForDirectMembers()) + { + SLANG_UNEXPECTED("this operation shouldn't be performed on deserialized declarations"); + } + SLANG_ASSERT(unscopedEnumAttr); SLANG_ASSERT(transparentModifier); @@ -225,6 +427,11 @@ void ContainerDecl:: _removeDirectMemberConstructorDeclBecauseSynthesizedAnotherDefaultConstructorInstead( ConstructorDecl* decl) { + if (isUsingOnDemandDeserializationForDirectMembers()) + { + SLANG_UNEXPECTED("this operation shouldn't be performed on deserialized declarations"); + } + SLANG_ASSERT(decl); _invalidateLookupAccelerators(); @@ -237,6 +444,11 @@ void ContainerDecl:: VarDecl* oldDecl, PropertyDecl* newDecl) { + if (isUsingOnDemandDeserializationForDirectMembers()) + { + SLANG_UNEXPECTED("this operation shouldn't be performed on deserialized declarations"); + } + SLANG_ASSERT(oldDecl); SLANG_ASSERT(newDecl); SLANG_ASSERT(index >= 0 && index < getDirectMemberDeclCount()); @@ -251,6 +463,11 @@ void ContainerDecl::_insertDirectMemberDeclAtIndexForBitfieldPropertyBackingMemb Index index, VarDecl* backingVarDecl) { + if (isUsingOnDemandDeserializationForDirectMembers()) + { + SLANG_UNEXPECTED("this operation shouldn't be performed on deserialized declarations"); + } + SLANG_ASSERT(backingVarDecl); SLANG_ASSERT(index >= 0 && index <= getDirectMemberDeclCount()); |
