Currently we warn when MI->isBuiltinMacro, but this is only true for builtin macros that require processing when expanding. Checking SourceMgr.isWrittenInBuiltinFile in addition to this will mean that we catch all builtin macros, though we shouldn't warn on feature test macros.
As part of doing this I've also moved the handling of undefining from CheckMacroName to HandleUndefDirective, as it doesn't really make sense to handle undefining in CheckMacroName but defining in HandleDefineDirective. It would be nice to instead handle both in CheckMacroName, but that isn't possible as the handling of defines requires looking at what the name is being defined to.
Should this diagnostic be suppressed in a system header on the assumption that system headers are part of the implementation and thus free to undefine/redefine macros at will?