[clang] Reland: separate recursive instantiation check from CodeSynthesisContext (#164177)
This makes pushing / popping CodeSynthesisContexts much cheaper, as it
delegates to another class this functionality which is not actually
needed in most cases.
It also converts a bunch of these uses into just asserts.
This improves compiler performance a little bit:
Some diagnostics change a little bit, because we avoid printing a
redundant context notes.
This relands #162224 with no changes, turns out the buildbot failure was
unrelated.