Index: lib/Basic/Diagnostic.cpp =================================================================== --- lib/Basic/Diagnostic.cpp +++ lib/Basic/Diagnostic.cpp @@ -163,21 +163,28 @@ assert(DiagStatePoints.front().Loc.isInvalid() && "Should have created a DiagStatePoint for command-line"); - if (!SourceMgr) + if (!SourceMgr || DiagStatePoints.size() == 1) return DiagStatePoints.end() - 1; FullSourceLoc Loc(L, *SourceMgr); if (Loc.isInvalid()) return DiagStatePoints.end() - 1; - DiagStatePointsTy::iterator Pos = DiagStatePoints.end(); + // Most frequent case: L is after the last diag state change. FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; - if (LastStateChangePos.isValid() && - Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) - Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), - DiagStatePoint(nullptr, Loc)); - --Pos; - return Pos; + assert(LastStateChangePos.isValid()); + if (!Loc.isBeforeInTranslationUnitThan(LastStateChangePos)) + return DiagStatePoints.end() - 1; + + // 2nd most frequent case: L is before the first diag state change. + FullSourceLoc FirstStateChangePos = DiagStatePoints[1].Loc; + assert(FirstStateChangePos.isValid()); + if (Loc.isBeforeInTranslationUnitThan(FirstStateChangePos)) + return DiagStatePoints.begin(); + + // Fall back to binary search. + return std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(), + DiagStatePoint(nullptr, Loc)) - 1; } void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,