static llvm::Optional<bool> compareControlFlow(const PathDiagnosticControlFlowPiece &X, const PathDiagnosticControlFlowPiece &Y) { FullSourceLoc XSL = X.getStartLocation().asLocation(); FullSourceLoc YSL = Y.getStartLocation().asLocation(); if (XSL != YSL) return XSL.isBeforeInProgramThan(YSL); FullSourceLoc XEL = X.getEndLocation().asLocation(); FullSourceLoc YEL = Y.getEndLocation().asLocation(); if (XEL != YEL) return XEL.isBeforeInProgramThan(YEL); return llvm::Optional<bool>(); }
static llvm::Optional<bool> comparePiece(const PathDiagnosticPiece &X, const PathDiagnosticPiece &Y) { if (X.getKind() != Y.getKind()) return X.getKind() < Y.getKind(); FullSourceLoc XL = X.getLocation().asLocation(); FullSourceLoc YL = Y.getLocation().asLocation(); if (XL != YL) return XL.isBeforeInProgramThan(YL); if (X.getString() != Y.getString()) return X.getString() < Y.getString(); if (X.getRanges().size() != Y.getRanges().size()) return X.getRanges().size() < Y.getRanges().size(); const SourceManager &SM = XL.getManager(); for (unsigned i = 0, n = X.getRanges().size(); i < n; ++i) { SourceRange XR = X.getRanges()[i]; SourceRange YR = Y.getRanges()[i]; if (XR != YR) { if (XR.getBegin() != YR.getBegin()) return SM.isBeforeInProgram(XR.getBegin(), YR.getBegin()); return SM.isBeforeInProgram(XR.getEnd(), YR.getEnd()); } } switch (X.getKind()) { case lfort::ento::PathDiagnosticPiece::ControlFlow: return compareControlFlow(cast<PathDiagnosticControlFlowPiece>(X), cast<PathDiagnosticControlFlowPiece>(Y)); case lfort::ento::PathDiagnosticPiece::Event: return llvm::Optional<bool>(); case lfort::ento::PathDiagnosticPiece::Macro: return compareMacro(cast<PathDiagnosticMacroPiece>(X), cast<PathDiagnosticMacroPiece>(Y)); case lfort::ento::PathDiagnosticPiece::Call: return compareCall(cast<PathDiagnosticCallPiece>(X), cast<PathDiagnosticCallPiece>(Y)); } llvm_unreachable("all cases handled"); }
static bool compare(const PathDiagnostic &X, const PathDiagnostic &Y) { FullSourceLoc XL = X.getLocation().asLocation(); FullSourceLoc YL = Y.getLocation().asLocation(); if (XL != YL) return XL.isBeforeInProgramThan(YL); if (X.getBugType() != Y.getBugType()) return X.getBugType() < Y.getBugType(); if (X.getCategory() != Y.getCategory()) return X.getCategory() < Y.getCategory(); if (X.getVerboseDescription() != Y.getVerboseDescription()) return X.getVerboseDescription() < Y.getVerboseDescription(); if (X.getShortDescription() != Y.getShortDescription()) return X.getShortDescription() < Y.getShortDescription(); if (X.getDeclWithIssue() != Y.getDeclWithIssue()) { const Decl *XD = X.getDeclWithIssue(); if (!XD) return true; const Decl *YD = Y.getDeclWithIssue(); if (!YD) return false; SourceLocation XDL = XD->getLocation(); SourceLocation YDL = YD->getLocation(); if (XDL != YDL) { const SourceManager &SM = XL.getManager(); return SM.isBeforeInProgram(XDL, YDL); } } PathDiagnostic::meta_iterator XI = X.meta_begin(), XE = X.meta_end(); PathDiagnostic::meta_iterator YI = Y.meta_begin(), YE = Y.meta_end(); if (XE - XI != YE - YI) return (XE - XI) < (YE - YI); for ( ; XI != XE ; ++XI, ++YI) { if (*XI != *YI) return (*XI) < (*YI); } llvm::Optional<bool> b = comparePath(X.path, Y.path); assert(b.hasValue()); return b.getValue(); }
void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map, SourceLocation L) { assert(Diag < diag::DIAG_UPPER_LIMIT && "Can only map builtin diagnostics"); assert((Diags->isBuiltinWarningOrExtension(Diag) || (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) && "Cannot map errors into warnings!"); assert(!DiagStatePoints.empty()); assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location"); FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc(); FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc; // Don't allow a mapping to a warning override an error/fatal mapping. if (Map == diag::MAP_WARNING) { DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag); if (Info.getMapping() == diag::MAP_ERROR || Info.getMapping() == diag::MAP_FATAL) Map = Info.getMapping(); } DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L); // Common case; setting all the diagnostics of a group in one place. if (Loc.isInvalid() || Loc == LastStateChangePos) { GetCurDiagState()->setMappingInfo(Diag, MappingInfo); return; } // Another common case; modifying diagnostic state in a source location // after the previous one. if ((Loc.isValid() && LastStateChangePos.isInvalid()) || LastStateChangePos.isBeforeInProgramThan(Loc)) { // A diagnostic pragma occurred, create a new DiagState initialized with // the current one and a new DiagStatePoint to record at which location // the new state became active. DiagStates.push_back(*GetCurDiagState()); PushDiagStatePoint(&DiagStates.back(), Loc); GetCurDiagState()->setMappingInfo(Diag, MappingInfo); return; } // We allow setting the diagnostic state in random source order for // completeness but it should not be actually happening in normal practice. DiagStatePointsTy::iterator Pos = GetDiagStatePointForLoc(Loc); assert(Pos != DiagStatePoints.end()); // Update all diagnostic states that are active after the given location. for (DiagStatePointsTy::iterator I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) { GetCurDiagState()->setMappingInfo(Diag, MappingInfo); } // If the location corresponds to an existing point, just update its state. if (Pos->Loc == Loc) { GetCurDiagState()->setMappingInfo(Diag, MappingInfo); return; } // Create a new state/point and fit it into the vector of DiagStatePoints // so that the vector is always ordered according to location. Pos->Loc.isBeforeInProgramThan(Loc); DiagStates.push_back(*Pos->State); DiagState *NewState = &DiagStates.back(); GetCurDiagState()->setMappingInfo(Diag, MappingInfo); DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState, FullSourceLoc(Loc, *SourceMgr))); }