Previously without -disable-free, -clear-ast-before-backend would crash in ~ASTContext() due to various reasons.
This works around that by doing a lot of the cleanup ahead of the destructor so that the destructor doesn't actually do any manual cleanup if we've already cleaned up beforehand.
This actually does save a measurable amount of memory with -clear-ast-before-backend, although at an almost unnoticeable runtime cost:
https://llvm-compile-time-tracker.com/compare.php?from=5d755b32f2775b9219f6d6e2feda5e1417dc993b&to=58ef1c7ad7e2ad45f9c97597905a8cf05a26258c&stat=max-rss
Previously we weren't doing any cleanup with -disable-free, so I tried measuring the impact of always doing the cleanup and didn't measure anything noticeable on llvm-compile-time-tracker.
Any chance of refactoring such that the ASTContext is scoped such that it is destroyed here, rather than rendered unusable - to reduce the chance that it'd be accidentally used after this point?
Like what happens if CompilerInstance::setASTContext(nullptr) is called? It wouldn't null out everyone's ASTContext pointers, but would mean there's no object there - perhaps crash harder/faster than a "cleaned up" ASTContext being used?