#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Regex.h"
#include <tuple>
// An event can be either the begin or the end of an interval.
enum EventType {
ET_Begin = 1,
+ ET_Insert = 0,
ET_End = -1,
};
// one will be processed before, disallowing the second one, and the
// end point of the first one will also be processed before,
// disallowing the first one.
- if (Type == ET_Begin)
+ switch (Type) {
+ case ET_Begin:
Priority = std::make_tuple(Begin, Type, -End, -ErrorSize, ErrorId);
- else
+ break;
+ case ET_Insert:
+ Priority = std::make_tuple(Begin, Type, -End, ErrorSize, ErrorId);
+ break;
+ case ET_End:
Priority = std::make_tuple(End, Type, -Begin, ErrorSize, ErrorId);
+ break;
+ }
}
bool operator<(const Event &Other) const {
}
// Build events from error intervals.
- std::map<std::string, std::vector<Event>> FileEvents;
+ llvm::StringMap<std::vector<Event>> FileEvents;
for (unsigned I = 0; I < ErrorFixes.size(); ++I) {
for (const auto &FileAndReplace : *ErrorFixes[I].second) {
for (const auto &Replace : FileAndReplace.second) {
unsigned Begin = Replace.getOffset();
unsigned End = Begin + Replace.getLength();
- const std::string &FilePath = std::string(Replace.getFilePath());
- // FIXME: Handle empty intervals, such as those from insertions.
- if (Begin == End)
- continue;
- auto &Events = FileEvents[FilePath];
- Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]);
- Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]);
+ auto &Events = FileEvents[Replace.getFilePath()];
+ if (Begin == End) {
+ Events.emplace_back(Begin, End, Event::ET_Insert, I, Sizes[I]);
+ } else {
+ Events.emplace_back(Begin, End, Event::ET_Begin, I, Sizes[I]);
+ Events.emplace_back(Begin, End, Event::ET_End, I, Sizes[I]);
+ }
}
}
}
llvm::sort(Events);
int OpenIntervals = 0;
for (const auto &Event : Events) {
- if (Event.Type == Event::ET_End)
- --OpenIntervals;
- // This has to be checked after removing the interval from the count if it
- // is an end event, or before adding it if it is a begin event.
- if (OpenIntervals != 0)
- Apply[Event.ErrorId] = false;
- if (Event.Type == Event::ET_Begin)
- ++OpenIntervals;
+ switch (Event.Type) {
+ case Event::ET_Begin:
+ if (OpenIntervals++ != 0)
+ Apply[Event.ErrorId] = false;
+ break;
+ case Event::ET_Insert:
+ if (OpenIntervals != 0)
+ Apply[Event.ErrorId] = false;
+ break;
+ case Event::ET_End:
+ if (--OpenIntervals != 0)
+ Apply[Event.ErrorId] = false;
+ break;
+ }
}
assert(OpenIntervals == 0 && "Amount of begin/end points doesn't match");
}