/// ScanReachableFromBlock - Mark all blocks reachable from Start.
/// Returns the total number of blocks that were marked reachable.
unsigned ScanReachableFromBlock(const CFGBlock &Start,
                                llvm::BitVector &Reachable) {
  unsigned count = 0;
  llvm::SmallVector<const CFGBlock*, 32> WL;

    // Prep work queue
  Reachable.set(Start.getBlockID());
  ++count;
  WL.push_back(&Start);

  // Find the reachable blocks from 'Start'.
  CFGBlock::FilterOptions FO;
  FO.IgnoreDefaultsWithCoveredEnums = 1;

  while (!WL.empty()) {
    const CFGBlock *item = WL.back();
    WL.pop_back();

      // Look at the successors and mark then reachable.
    for (CFGBlock::filtered_succ_iterator I= item->filtered_succ_start_end(FO);
         I.hasMore(); ++I)
      if (const CFGBlock *B = *I) {
        unsigned blockID = B->getBlockID();
        if (!Reachable[blockID]) {
          Reachable.set(blockID);
          ++count;
          WL.push_back(B);
        }
      }
  }
  return count;
}
static SourceLocation MarkLiveTop(const CFGBlock *Start,
                                  llvm::BitVector &reachable,
                                  SourceManager &SM) {

  // Prep work worklist.
  llvm::SmallVector<const CFGBlock*, 32> WL;
  WL.push_back(Start);

  SourceRange R1, R2;
  SourceLocation top = GetUnreachableLoc(*Start, R1, R2);

  bool FromMainFile = false;
  bool FromSystemHeader = false;
  bool TopValid = false;

  if (top.isValid()) {
    FromMainFile = SM.isFromMainFile(top);
    FromSystemHeader = SM.isInSystemHeader(top);
    TopValid = true;
  }

  // Solve
  CFGBlock::FilterOptions FO;
  FO.IgnoreDefaultsWithCoveredEnums = 1;

  while (!WL.empty()) {
    const CFGBlock *item = WL.back();
    WL.pop_back();

    SourceLocation c = GetUnreachableLoc(*item, R1, R2);
    if (c.isValid()
        && (!TopValid
            || (SM.isFromMainFile(c) && !FromMainFile)
            || (FromSystemHeader && !SM.isInSystemHeader(c))
            || SM.isBeforeInTranslationUnit(c, top))) {
          top = c;
          FromMainFile = SM.isFromMainFile(top);
          FromSystemHeader = SM.isInSystemHeader(top);
        }

    reachable.set(item->getBlockID());
    for (CFGBlock::filtered_succ_iterator I =
	   item->filtered_succ_start_end(FO); I.hasMore(); ++I)
      if (const CFGBlock *B = *I) {
        unsigned blockID = B->getBlockID();
        if (!reachable[blockID]) {
          reachable.set(blockID);
          WL.push_back(B);
        }
      }
  }

  return top;
}
Exemple #3
0
unsigned ScanReachableFromBlock(const CFGBlock *Start,
                                llvm::BitVector &Reachable) {
    unsigned count = 0;

    // Prep work queue
    SmallVector<const CFGBlock*, 32> WL;

    // The entry block may have already been marked reachable
    // by the caller.
    if (!Reachable[Start->getBlockID()]) {
        ++count;
        Reachable[Start->getBlockID()] = true;
    }

    WL.push_back(Start);

    // Find the reachable blocks from 'Start'.
    while (!WL.empty()) {
        const CFGBlock *item = WL.pop_back_val();

        // Look at the successors and mark then reachable.
        for (CFGBlock::const_succ_iterator I = item->succ_begin(),
                E = item->succ_end(); I != E; ++I)
            if (const CFGBlock *B = *I) {
                unsigned blockID = B->getBlockID();
                if (!Reachable[blockID]) {
                    Reachable.set(blockID);
                    WL.push_back(B);
                    ++count;
                }
            }
    }
    return count;
}
Exemple #4
0
static unsigned scanFromBlock(const CFGBlock *Start,
                              llvm::BitVector &Reachable,
                              Preprocessor *PP,
                              bool IncludeSometimesUnreachableEdges) {
  unsigned count = 0;
  
  // Prep work queue
  SmallVector<const CFGBlock*, 32> WL;
  
  // The entry block may have already been marked reachable
  // by the caller.
  if (!Reachable[Start->getBlockID()]) {
    ++count;
    Reachable[Start->getBlockID()] = true;
  }
  
  WL.push_back(Start);
  
  // Find the reachable blocks from 'Start'.
  while (!WL.empty()) {
    const CFGBlock *item = WL.pop_back_val();

    // There are cases where we want to treat all successors as reachable.
    // The idea is that some "sometimes unreachable" code is not interesting,
    // and that we should forge ahead and explore those branches anyway.
    // This allows us to potentially uncover some "always unreachable" code
    // within the "sometimes unreachable" code.
    // Look at the successors and mark then reachable.
    Optional<bool> TreatAllSuccessorsAsReachable;
    if (!IncludeSometimesUnreachableEdges)
      TreatAllSuccessorsAsReachable = false;

    for (CFGBlock::const_succ_iterator I = item->succ_begin(), 
         E = item->succ_end(); I != E; ++I) {
      const CFGBlock *B = *I;
      if (!B) do {
        const CFGBlock *UB = I->getPossiblyUnreachableBlock();
        if (!UB)
          break;

        if (!TreatAllSuccessorsAsReachable.hasValue()) {
          assert(PP);
          TreatAllSuccessorsAsReachable =
            shouldTreatSuccessorsAsReachable(item, *PP);
        }

        if (TreatAllSuccessorsAsReachable.getValue()) {
          B = UB;
          break;
        }
      }
      while (false);

      if (B) {
        unsigned blockID = B->getBlockID();
        if (!Reachable[blockID]) {
          Reachable.set(blockID);
          WL.push_back(B);
          ++count;
        }
      }
    }
  }
  return count;
}
void BlockState::startTrackingLocation(llvm::BitVector &BV, unsigned i) {
    BV.set(i);
}