modernize-macro-to-enum
creates a bunch of little insertions around a cluster of macros to turn this:
#define FOO1 1
#define FOO2 2
#define FOO3 3
into this
enum {
FOO1 = 1,
FOO2 = 2,
FOO3 = 3
};
The problem is that when the fixes are exported, the insertions of the =
are not de-duplicated by clang-apply-replacements. So if clang-tidy is run with header-filter set to apply to application header files, the header files that have fixits issued in the course of analyzing multiple source files end up with invalid syntax llike this:
enum {
FOO1 = = 1,
FOO2 = = 2,
FOO3 = = 3
};
};
I think I remember something about fixits issued by clang-tidy that there is a way to mark them as belonging to a single comprehensive set of changes around a source range, or something like that?
Currently I’m appending all the changes to a single instance of a DiagnosticBuilder
(MacroToEnumCheck.cpp:468)
void MacroToEnumCallbacks::fixEnumMacro(const MacroList &MacroList) const {
SourceLocation Begin =
MacroList.front().Directive->getMacroInfo()->getDefinitionLoc();
Begin = SM.translateLineCol(SM.getFileID(Begin),
SM.getSpellingLineNumber(Begin), 1);
DiagnosticBuilder Diagnostic =
Check->diag(Begin, "replace macro with enum")
<< FixItHint::CreateInsertion(Begin, "enum {\n");
for (size_t I = 0u; I < MacroList.size(); ++I) {
const EnumMacro &Macro = MacroList[I];
SourceLocation DefineEnd =
Macro.Directive->getMacroInfo()->getDefinitionLoc();
SourceLocation DefineBegin = SM.translateLineCol(
SM.getFileID(DefineEnd), SM.getSpellingLineNumber(DefineEnd), 1);
CharSourceRange DefineRange;
DefineRange.setBegin(DefineBegin);
DefineRange.setEnd(DefineEnd);
Diagnostic << FixItHint::CreateRemoval(DefineRange);
SourceLocation NameEnd = Lexer::getLocForEndOfToken(
Macro.Directive->getMacroInfo()->getDefinitionLoc(), 0, SM, LangOpts);
Diagnostic << FixItHint::CreateInsertion(NameEnd, " =");
SourceLocation ValueEnd = Lexer::getLocForEndOfToken(
Macro.Directive->getMacroInfo()->getDefinitionEndLoc(), 0, SM,
LangOpts);
if (I < MacroList.size() - 1)
Diagnostic << FixItHint::CreateInsertion(ValueEnd, ",");
}
SourceLocation End = Lexer::getLocForEndOfToken(
MacroList.back().Directive->getMacroInfo()->getDefinitionEndLoc(), 0, SM,
LangOpts);
End = SM.translateLineCol(SM.getFileID(End),
SM.getSpellingLineNumber(End) + 1, 1);
Diagnostic << FixItHint::CreateInsertion(End, "};\n");
}