This allows for extensibility in how the target type info is obtained,
serving two purposes:
- Small step towards "Dialects in LLVM", in providing extensibility for users of LLVM. Users of LLVM can now define their own "target" extension types (now a somewhat misleading name) with custom layout and properties, to represent high-level concepts that are lowered away before code reaches the actual backend.
- By storing a pointer to the type class in the type itself, we can avoid string comparisons when looking up type info.
Maybe add an assert that TypeClass is not yet registered?