Пример #1
0
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>();
}
Пример #2
0
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");
}
Пример #3
0
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();
}
Пример #4
0
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)));
}