content: # ### Runnables ###
  #
  # The mappings here specify rules that annotate all descendant overrides of
  # virtual runnable methods so that when we encounter them in the crossref
  # process that we are able to generate `RunnableConstructor` slot edges to their
  # constructors and corresponding `RunnableMethod` slot edges back from the
  # constructors to the runnable methods.  These will be followed by the
  # "traverse" command instead of getting into the infrastructure boilerplate
  # around runnables.
  #
  # This heuristic can also be used for general callback interfaces like
  # nsIRequestObserver on each of its listener methods as the effects are
  # additive.  For example, a reference to a constructor then becomes a reference
  # to both OnStartRequest and OnStopRequest assuming both methods were marked
  # as runnable.
  #
  # TODO: Need to deal with situations like
  # https://searchfox.org/mozilla-central/rev/6220909421e5cdb2e706a87f77ba7c6f4f21e4d0/dom/quota/ActorsParent.cpp#7064
  # where we have an explicit call to Run made from inside the class.  Although we
  # want to avoid including the calls to the base class signature of the method,
  # we absolutely want to process in-class concrete references to the Run method,
  # maybe even all the way up the hierarchy short of the runnable method itself.
  # This case will shortly change in https://phabricator.services.mozilla.com/D182182
  # so that OriginOperationBase::RunImmediately will directly be invoking Run
  # itself.
  
  [pretty."nsIRunnable::Run"]
  runnable = "constructor"
  
  [pretty."mozilla::dom::WorkerRunnable::WorkerRun"]
  runnable = "constructor"
  
  [pretty."mozilla::dom::WorkerMainThreadRunnable::MainThreadRun"]
  runnable = "constructor"
  
  [pretty."mozilla::dom::WorkerThreadProxySyncRunnable::RunOnMainThread"]
  runnable = "constructor"
  
  [pretty."nsIProgressEventSink::OnProgress"]
  runnable = "constructor"
  
  [pretty."nsIProgressEventSink::OnStatus"]
  runnable = "constructor"
  
  [pretty."nsIRequestObserver::OnStartRequest"]
  runnable = "constructor"
  
  [pretty."nsIRequestObserver::OnStopRequest"]
  runnable = "constructor"
  
  [pretty."nsIStreamListener::OnDataAavailable"]
  runnable = "constructor"
  
  [pretty."nsIStreamLoaderObserver::OnStreamComplete"]
  runnable = "constructor"
  
  # Treating nsITimerCallback as a runnable is an improvement on the current
  # behavior of citing `nsTimerImpl::Fire` plus random implementations that
  # directly call the Notify method (like `HTMLCanvasPrintState`), but is mainly
  # useful for small one-off classes of a certain era before lambdas would be
  # used.  For larger monolithic classes, it would be better to specialize on the
  # call to setup the timer, and this would also work for the smaller classes too.
  [pretty."nsITimerCallback::Notify"]
  runnable = "constructor"
  
  # #### Java / Kotlin Runnable Things ####
  #
  # These seem like they use reflection to construct the class and so we don't
  # actually see the constructor invoked, so our edges here need to be to
  # references to the class.  We of course also see references to the classes
  # when they are imported, but those thankfully lack a contextsym and so end up
  # being moot.
  [pretty."androidx::work::Worker::doWork"]
  runnable = "class"
  
  [pretty."androidx::work::CoroutineWorker::doWork"]
  runnable = "class"
  
  [pretty."kotlin::Function3::invoke"]
  runnable = "constructor"
  
  # ### Class Diagram Directives ###
  #
  # - "class-diagram:stop" - This is used for cases where the type is notable and
  #   it's potentially worth displaying, but we definitely do not want to traverse
  #   the type because it has so much going on that it will swamp everything else
  #   going on.  An exception is made if the class is explicitly a root of the
  #   diagram (depth is zero).
  #   - It's possible that many uses of this label could be removed by use of
  #     heuristics like:
  #     - Overload heuristics.  We have some of these already, but the core idea
  #       is that sometimes something should not be traversed without explicit
  #       user interaction.
  #     - Subsystem-crossing heuristics.  In many cases, problematic classes live
  #       in other subsystems from what a user is investigating, so a heuristic
  #       that doesn't expand or possibly even show the classes would work.
  #   - It's also possible that more explicit display of the types of fields
  #     either directly in the diagram or contextually via super sidebar/similar
  #     could moot the need to display a number of classes that don't contribute
  #     to the graph topology.
  # - "class-diagram:elide-and-badge:" prefix - A more extensive intervention for
  #   cases where including the class in the graph creates an unhelpful layout
  #   nexus.  For example, tons of things subclass "nsISupports" and "nsIRunnable"
  #   so we use this mechanism to suppress the edge and instead put "nsI" and
  #   "nsIRun" labels on the classes when we would have instead added an edge.
  
  [pretty."JSObject"]
  labels = ["class-diagram:stop"]
  
  [pretty."nsIEventTarget"]
  labels = ["class-diagram:stop"]
  
  [pretty."nsIGlobalObject"]
  labels = ["class-diagram:stop"]
  
  [pretty."nsIInterfaceRequestor"]
  labels = ["class-diagram:stop", "class-diagram:elide-and-badge:nsIIReq"]
  
  [pretty."nsIObserver"]
  labels = ["class-diagram:stop", "class-diagram:elide-and-badge:nsIObs"]
  
  # nsIRunnable is not as bad as nsISupports, but it's sufficiently common that
  # it will create a layout cluster that we really don't need/want.
  [pretty."nsIRunnable"]
  labels = ["class-diagram:stop", "class-diagram:elide-and-badge:nsIRun"]
  
  [pretty."nsISerialEventTarget"]
  labels = ["class-diagram:stop"]
  
  # This will get both `T_nsISupports` and `XPIDL_nsISupports`
  [pretty."nsISupports"]
  labels = ["class-diagram:stop", "class-diagram:elide-and-badge:nsI"]
  
  # calls-between likes to find "NS_TableDrivenQI" calling "nsISupports::AddRef"
  [pretty."nsISupports::AddRef"]
  labels = ["uses-diagram:stop"]
  # adding the release counterpart just in case.
  [pretty."nsISupports::Release"]
  labels = ["uses-diagram:stop"]
  # QueryInterface is only a minor problem but is not helpful.
  [pretty."nsISupports::QueryInterface"]
  labels = ["uses-diagram:stop"]
  
  [pretty."nsIThreadPool"]
  labels = ["class-diagram:stop"]
  
  [pretty."nsSupportsWeakReference"]
  labels = ["class-diagram:stop", "class-diagram:elide-and-badge:nsSupWeak"]
  
  [pretty."nsGlobalWindowInner"]
  labels = ["class-diagram:stop"]
  
  [pretty."nsPIDOMWindowInner"]
  labels = ["class-diagram:stop"]
  
  [pretty."nsWrapperCache"]
  labels = ["class-diagram:stop", "class-diagram:elide-and-badge:WC"]
  
  [pretty."mozilla::DOMEventTargetHelper"]
  labels = ["class-diagram:stop"]
  
  [pretty."mozilla::dom::WorkerPrivate"]
  labels = ["class-diagram:stop"]
  
  [pretty."mozilla::ipc::IProtocol"]
  labels = ["class-diagram:stop"]
  
  [pretty."mozilla::ipc::PBackgroundParent"]
  labels = ["class-diagram:stop"]
  
  [pretty."mozilla::Runnable"]
  labels = ["class-diagram:stop"]
  
  [pretty."mozilla::SupportsWeakPtr"]
  labels = ["class-diagram:stop"]
  
  # calls-between WorkerPrivate and nsITimer found an interesting but distracting path
  # and nsGlobalWindowInner similarly ended up with noise we don't need.  The
  # specific choice of using these impl classes is because they use a lot of
  # overloads so we can specify them more easily based on pretty.  These are not
  # comprehensive.
  #
  # This could be mooted by better traversal heuristics, and/or made more compact
  # if we still see value in the annotation.
  [pretty."TelemetryScalar::Add"]
  labels = ["uses-diagram:stop"]
  [pretty."TelemetryScalar::Set"]
  labels = ["uses-diagram:stop"]
  [pretty."TelemetryScalar::SetMaximum"]
  labels = ["uses-diagram:stop"]
  [pretty."TelemetryHistogram::Accumulate"]
  labels = ["uses-diagram:stop"]
  [pretty."TelemetryHistogram::AccumulateCategorical"]
  labels = ["uses-diagram:stop"]
  [pretty."KeyedHistogram::Add"]
  labels = ["uses-diagram:stop"]
  [pretty."TelemetryEvent::RecordEventNative"]
  labels = ["uses-diagram:stop"]
  
  # Until we are able to understand the observer service arguments and refine the
  # calls to tuple over the argument, we want uses diagrams to stop at the
  # interface because otherwise they entrain impossible control flow paths.
  # TODO: Understand observer notification arguments / subscriptions.
  [pretty."nsIObserver::Observe"]
  labels = ["uses-diagram:stop"]
  
  # stay out of debug spam stuff
  [pretty."NS_warn_if_impl"]
  labels = ["calls-diagram:stop"]
  [pretty."NS_DebugBreak"]
  labels = ["calls-diagram:stop"]
  [pretty."MOZ_ReportAssertionFailure"]
  labels = ["calls-diagram:stop"]
  [pretty."MOZ_ReportCrash"]
  labels = ["calls-diagram:stop"]
  [pretty."NS_IsMainThread"]
  labels = ["calls-diagram:stop"]
  # the above cases should prevent this, but this has an annoying fan-out if we get here
  [pretty."PR_GetEnv"]
  labels = ["calls-diagram:stop"]
  
  # some speculative profiler filters
  [pretty."mozilla::MarkerStack::Capture"]
  labels = ["calls-diagram:stop"]
  [pretty."profiler_thread_is_being_profiled_for_markers"]
  labels = ["calls-diagram:stop"]
  
  # stay out of various logging related things that have fan out
  [pretty."mozilla::ipc::LoggingEnabledFor"]
  labels = ["calls-diagram:stop"]
  [pretty."mozilla::ipc::LogMessageForProtocol"]
  labels = ["calls-diagram:stop"]
  # stay out of IPC internals for IPC protocols we don't have IPDL bindings for
  [pretty."mozilla::ipc::IProtocol::ChannelSend"]
  labels = ["calls-diagram:stop"]
  
  # Avoid some NSPR stuff that comes up; this very much could be handled via subsystem
  # heuristics about NSPR always being boring.
  [pretty."PR_JoinThread"]
  labels = ["calls-diagram:stop"]
  [pretty."PR_Now"]
  labels = ["calls-diagram:stop"]
  
  # ### Refcounted Types ###
  
  [[pretty."nsAutoRefCnt".label_owning_class.labels]]
  label = "rc"
  
  # (Label atomic refcounted things as both "rc" and "arc".)
  [[pretty."mozilla::ThreadSafeAutoRefCnt".label_owning_class.labels]]
  label = "rc"
  [[pretty."mozilla::ThreadSafeAutoRefCnt".label_owning_class.labels]]
  label = "arc"
  
  [[pretty."nsCycleCollectingAutoRefCnt".label_owning_class.labels]]
  label = "rc"
  [[pretty."nsCycleCollectingAutoRefCnt".label_owning_class.labels]]
  label = "ccrc"
  
  [[pretty."mozilla::RefCounted".label_subclasses.labels]]
  label = "rc"
  
  # (Label atomic refcounted things as both "rc" and "arc".)
  [[pretty."mozilla::AtomicRefCounted".label_subclasses.labels]]
  label = "rc"
  [[pretty."mozilla::AtomicRefCounted".label_subclasses.labels]]
  label = "arc"
  
  # #### Webkit
  
  # This is transitive and gets RefCounted too.
  [[pretty."WTF::RefCountedBase".label_subclasses.labels]]
  label = "rc"
  
  [[pretty."WTF::ThreadSafeRefCounted".label_subclasses.labels]]
  label = "rc"
  [[pretty."WTF::ThreadSafeRefCounted".label_subclasses.labels]]
  label = "arc"
  
  # ### Cycle Collection ###
  # We use a containing class rule here because the participant is an inner class
  # of the cycle collected class.  Compare with the refcount objects which are
  # fields on the refcounted class.
  [[pretty."nsCycleCollectionParticipant".label_containing_class.labels]]
  label = "cc"
  
  [[pretty."nsCycleCollectionParticipant".label_containing_class_field_uses.labels]]
  context_sym_suffix = "::cycleCollection::Trace"
  label = "cc-trace"
  [[pretty."nsCycleCollectionParticipant".label_containing_class_field_uses.labels]]
  context_sym_suffix = "::cycleCollection::TraverseNative"
  label = "cc-traverse"
  [[pretty."nsCycleCollectionParticipant".label_containing_class_field_uses.labels]]
  context_sym_suffix = "::cycleCollection::Unlink"
  label = "cc-unlink"
  
  # ### Label Testing ###
  #
  # Okay, so, uh, these are only for testing.
  
  [[pretty."outerNS::CycleCollectingMagic".label_containing_class.labels]]
  label = "cc"
  
  [[pretty."outerNS::CycleCollectingMagic".label_containing_class_field_uses.labels]]
  context_sym_suffix = "::unlink"
  label = "cc-unlink"
  
  # ### Decorator Types ###
  #
  # A type like Atomic or IntializedOnce that provides notable semantics and
  # so we should apply a label, but where the decorator type itself is not
  # the underlying type of interest and we should continue processing its
  # arguments like they existed without the decorator.
  
  [types."mozilla::Atomic".decorator]
  labels = ["atomic"]
  
  [types."std::atomic".decorator]
  labels = ["atomic"]
  
  [types."mozilla::DataMutex".decorator]
  labels = ["synchronized"]
  
  # should this have a "static" label, or is it redundant because the field will
  # be static?
  [types."mozilla::StaticDataMutex".decorator]
  labels = ["synchronized"]
  
  [types."mozilla::ThreadBound".decorator]
  labels = ["threadbound"]
  
  # #### Webkit
  
  [types."WTF::Atomic".decorator]
  labels = ["atomic"]
  
  [types."WTF::DataMutex".decorator]
  labels = ["synchronized"]
  
  # ### Value Types ###
  #
  # Marking something as a value excludes that type itself from being considered
  # for pointer_info purposes and thereby not something that "class-diagram" will
  # show because there's no potential graph edge to generate.  For example, URIs
  # are very interesting properties, but there is nothing interesting about the
  # relationship between a document and its URI fields.  The same for strings.
  #
  # Because the current processing algorithm only potentially looks at a given
  # template arg and its parent, marking something as a value doesn't stop us
  # from potentially processing nested arguments; like if we marked nsTArray as
  # a value, then `nsTArray<RefPtr<Foo> >` would not stop us from seeing the
  # contained RefPtr right now.  Note that nsTArray is explicitly now a container
  # and one should not mark things as values depending on that behavior, as we
  # will potentially fix that problem.
  # TODO: fix that problem
  #
  # Note that we also hope to automatically mark types that only contain value
  # types themselves as values, although it's unclear if we should only do that
  # for primitive types or also inductively for types we've explicitly marked as
  # values here.
  
  [types."nsTString".value]
  [types."nsTSubstring".value]
  
  [types."nsPoint".value]
  
  [types."nsIPrincipal".value]
  [types."mozilla::ipc::PrincipalInfo".value]
  [types."nsIURI".value]
  [types."mozilla::ipc::URIParams".value]
  [types."nsIReferrerInfo".value]
  
  [types."mozilla::ipc::IPDLStructMemberWrapper".value]
  
  # A mutex itself just a value and not inherently interesting, although I wonder
  # if "label_owning_class" should be used to mark a class as having some internal
  # synchronization going on.  Although that might be something that's best done
  # as a first-class thing so that clicking on it would immediately show what
  # fields are guarded and what the guarding relationships are.
  [types."mozilla::Mutex".value]
  
  [types."mozilla::TimeStamp".value]
  
  [types."mozilla::dom::IdType".value]
  
  # The refcount and owning thread are boring and usually there.  These get badged
  # via `pretty` rules.
  [types."nsCycleCollectingAutoRefCnt".value]
  [types."nsAutoRefCnt".value]
  [types."nsAutoOwningThread".value]
  [types."ThreadSafeAutoRefCnt".value]
  
  # #### Webkit
  
  [types."WTF::ApproximateTime".value]
  # this is somewhat notable but not useful to be called out
  [types."WTF::Lock".value]
  [types."WTF::MonotonicTime".value]
  [types."WTF::Seconds".value]
  [types."WTF::String".value]
  [types."WTF::WallTime".value]
  
  
  # ### Containers ###
  #
  # Container types are themselves not interesting classes, but their payloads are
  # and we assume containers have a multiplicity of >1.  For something like
  # "mozilla::Maybe", we currently just model that as a pointer, but we could
  # probably do better.
  
  # Maps/Sets are interesting if their values are interesting, so let's mark
  # them as values right now.
  # TODO: Potentially have this (and arrays) annotate multiplicity.
  [types."nsBaseHashtable".container]
  [types."nsTBaseHashSet".container]
  
  [types."std::array".container]
  [types."std::deque".container]
  [types."std::flat_map".container]
  [types."std::flat_set".container]
  [types."std::flat_multimap".container]
  [types."std::flat_multiset".container]
  [types."std::forward_list".container]
  [types."std::list".container]
  [types."std::map".container]
  [types."std::multiset".container]
  [types."std::multimap".container]
  [types."std::priority_queue".container]
  [types."std::queue".container]
  [types."std::set".container]
  # we really need ownership for this one
  [types."std::span".container]
  [types."std::stack".container]
  [types."std::unordered_map".container]
  [types."std::unordered_set".container]
  [types."std::unordered_multimap".container]
  [types."std::unordered_multiset".container]
  [types."std::vector".container]
  
  
  [types."nsTArray".container]
  [types."AutoTArray".container]
  [types."mozilla::Vector".container]
  [types."HashSet".container]
  
  # nsClassHashtable is somewhat unique in terms of baking in a UniquePtr, so we
  # define it as a pointer.
  # XXX we probably want to be able to specify multiplicity for pointers then.
  [types."nsClassHashtable".pointer]
  kind = "unique"
  arg_index = 1
  
  # ManagedContainer should be a container, but it bakes in retained raw pointers
  # that are conceptually strong but structurally raw.  Notionally, these could
  # probably be considered weak pointers where the ActorLifecycleProxy holds the
  # strong reference, but I think we may be eliding that right now.
  #
  # TODO: Figure out what's going on with ActorLifecycleProxy
  [types."mozilla::ManagedContainer".pointer]
  kind = "strong"
  
  # #### Webkit
  
  [types."WTF::Bag".container]
  [types."WTF::Deque".container]
  [types."WTF::DoublyLinkedList".container]
  # the values are the 2nd arg, don't have container support for this yet.
  [types."WTF::EnumeratedArray".pointer]
  kind = "contains"
  arg_index = 1
  [types."WTF::HashCountedSet".container]
  [types."WTF::HashMap".container]
  [types."WTF::HashSet".container]
  [types."WTF::HashTable".container]
  # the value is the 2nd arg which goes in an underlying Vector
  [types."WTF::IndexMap".pointer]
  kind = "contains"
  arg_index = 1
  # IndexSet has no payload; the underlying storage is just a BitVector
  [types."WTF::ListHashSet".container]
  [types."WTF::LocklessBag".container]
  [types."WTF::MessageQueue".container]
  [types."WTF::PriorityQueue".container]
  [types."WTF::RefCountedFixedVector".container]
  [types."WTF::ReferenceWrapperVector".container]
  # This is a WTF::Vector of WTF::Refs and so this throws away our pointer info;
  # maybe it would be better to not define this and instead heuristically
  # understand what it's subclassing?
  [types."WTF::RefVector".container]
  [types."WTF::SegmentedVector".container]
  [types."WTF::SentinelLinkedList".container]
  [types."WTF::SinglyLinkedList".container]
  [types."WTF::SinglyLinkedListWithTail".container]
  [types."WTF::SmallSet".container]
  [types."WTF::SortedArrayMap".container]
  [types."WTF::ThreadSafeWeakHashSet".container]
  [types."WTF::UniqueArray".container]
  [types."WTF::UniqueRefVector".container]
  [types."WTF::WeakHashCountedSet".container]
  [types."WTF::WeakHashMap".container]
  [types."WTF::WeakListHashSet".container]
  
  [types."WTF::WeakHashSet".container]
  [types."WTF::Vector".container]
  
  # ### Variant Types ###
  [types."mozilla::Variant".variant]
  
  # XXX pair is not a variant, but for our purposes we just want all of its types
  [types."std::pair".variant]
  [types."std::tuple".variant]
  [types."std::variant".variant]
  
  # #### Webkit
  
  # like std::pair, we just want both types
  [types."WTF::KeyValuePair".variant]
  
  
  # ### Sentinel Nothing Types ###
  [types."mozilla::Nothing".nothing]
  
  # ### Pointer Types ###
  #
  # These inform our processing of class fields.
  
  # Doing this for Maybe<ServiceWorkerDescriptor> right now.
  [types."mozilla::Maybe".pointer]
  kind = "contains"
  
  [types."std::optional".pointer]
  kind = "contains"
  
  [types."nsCOMPtr".pointer]
  kind = "strong"
  
  # explicitly not in the mozilla namespace
  [types."RefPtr".pointer]
  kind = "strong"
  
  [types."mozilla::SafeRefPtr".pointer]
  kind = "strong"
  
  [types."mozilla::ThreadSafeWeakPtr".pointer]
  kind = "weak"
  
  [types."mozilla::CheckedUnsafePtr".pointer]
  kind = "raw"
  
  [types."mozilla::UniquePtr".pointer]
  kind = "unique"
  
  [types."mozilla::WeakPtr".pointer]
  kind = "weak"
  
  [types."WeakPtr".pointer]
  kind = "weak"
  
  [types."std::shared_ptr".pointer]
  kind = "strong"
  
  [types."shared_ptr".pointer]
  kind = "strong"
  
  [types."std::unique_ptr".pointer]
  kind = "unique"
  
  [types."unique_ptr".pointer]
  kind = "unique"
  
  [types."std::weak_ptr".pointer]
  kind = "weak"
  
  [types."weak_ptr".pointer]
  kind = "weak"
  
  [types."nsRefPtrHashKey".pointer]
  kind = "strong"
  
  # ### JS Wrapper Types ###
  
  [types."JS::Result".value]
  
  # ### JS Container Types ###
  
  [types."js::HashMap".container]
  
  [types."js::HashSet".container]
  
  [types."js::ProtectedData".container]
  
  [types."js::ProtectedDataNoCheckArgs".container]
  
  [types."js::ProtectedDataWriteOnce".container]
  
  [types."js::Vector".container]
  
  # ### JS Pointer Types ###
  
  [types."js::AtomicRefCounted".pointer]
  kind = "strong"
  
  [types."js::RefCounted".pointer]
  kind = "strong"
  
  # ### JS GC Wrapper Types ###
  
  [types."js::GCPtr".pointer]
  kind = "gcref"
  
  [types."JS::Handle".pointer]
  kind = "gcref"
  
  [types."JS::Heap".pointer]
  kind = "gcref"
  
  [types."js::HeapPtr".pointer]
  kind = "gcref"
  
  [types."JS::TenuredHeap".pointer]
  kind = "gcref"
  
  [types."JS::MutableHandle".pointer]
  kind = "gcref"
  
  [types."JS::PersistentRooted".pointer]
  kind = "gcref"
  
  [types."JS::Rooted".pointer]
  kind = "gcref"
  
  # ### JS GC Collection Types ###
  
  [types."JS::GCHashMap".container]
  
  [types."js::GCRekeyableHashMap".container]
  
  [types."JS::GCVector".container]
  
  [types."JS::PersistentRootedVector".container]
  
  [types."JS::RootedVector".container]
  
  [types."JS::StackGCVector".container]
  
  # #### Webkit
  #
  # Note that a shocking number of the header files provide no documentation and
  # so the kinds are potentially vibe-based.
  
  [types."WTF::Box".pointer]
  kind = "strong"
  
  [types."WTF::BoxPtr".pointer]
  kind = "strong"
  
  [types."WTF::CagedPtr".pointer]
  kind = "raw"
  
  [types."WTF::CagedUniquePtr".pointer]
  kind = "unique"
  
  [types."WTF::CheckedPtr".pointer]
  kind = "raw"
  
  [types."WTF::CheckedRef".pointer]
  kind = "ref"
  
  [types."WTF::CodePtr".pointer]
  kind = "raw"
  
  [types."WTF::CompactPtr".pointer]
  kind = "raw"
  
  [types."WTF::CompactRefPtr".pointer]
  kind = "strong"
  
  [types."WTF::DataRef".pointer]
  kind = "strong"
  
  # this doesn't do destruction so it feels wrong to call it unique
  [types."WTF::MallocPtr".pointer]
  kind = "raw"
  
  [types."WTF::NakedPtr".pointer]
  kind = "raw"
  
  [types."WTF::NakedRef".pointer]
  kind = "ref"
  
  [types."WTF::Packed".pointer]
  kind = "contains"
  
  [types."WTF::RawPointer".pointer]
  kind = "raw"
  
  # RefPtr but no support for null
  [types."WTF::Ref".pointer]
  kind = "strong"
  
  [types."WTF::RefPtr".pointer]
  kind = "strong"
  
  [types."WTF::SignedPtr".pointer]
  kind = "raw"
  
  [types."WTF::ThreadSafeWeakPtr".pointer]
  kind = "weak"
  
  [types."WTF::UniqueRef".pointer]
  kind = "unique"
  
  [types."WTF::WeakPtr".pointer]
  kind = "weak"
  
  [types."WTF::WeakObjCPtr".pointer]
  kind = "weak"
  