FormatterContainerPair is (as its name indicates) a very thin wrapper
over two formatter containers, one for exact matches and another one for
regex matches. The logic to decide which subcontainer to access is
replicated everywhere FormatterContainerPairs are used.
So, for example, when we look for a formatter there's some adhoc code
that does a lookup in the exact match formatter container, and if it
fails it does a lookup in the regex match formatter container. The same
logic is then copied and pasted for summaries, filters, and synthetic
child providers.
This change introduces a new TieredFormatterContainer that has two
main characteristics:
- It generalizes FormatterContainerPair from 2 to any number of subcontainers, that are looked up in priority order.
- It centralizes all the logic to choose which subcontainer to use for lookups, add/delete, and indexing.
This allows us to have a single copy of the same logic, templatized for
each kind of formatter. It also simplifies the upcoming addition of a
new tier of callback-based matches. See
https://discourse.llvm.org/t/rfc-python-callback-for-data-formatters-type-matching/64204
for more details about this.
The rest of the change is mostly replacing copy-pasted code with calls
to methods of the relevant TieredFormatterContainer, and adding some
methods to the TypeCategoryImpl class so we can remove some of this
copy-pasted code from SBTypeCategory.
According to https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements this loop body should not use the {} braces.