List of usage examples for com.google.common.collect FluentIterable toString
@Override
@CheckReturnValue
public String toString()
From source file:org.sosy_lab.cpachecker.util.cwriter.PathToCWithLoopsTranslator.java
/** * Recreates the code of one (or more nested) loops with gotos. * @param pCFAEdge the edge into the loop * @param currentBlock the current block * @param loopsAfter the loops which we are in after the edge * @return the complete c-code for the recreated loop *///ww w .j a va 2 s . c o m private Pair<String, CFAEdge> recreateLoop(CFAEdge pCFAEdge, BasicBlock currentBlock, List<Loop> loopsAfter) { // clear all necessary things resetLoopAndIfMaps(); CFAEdge lastEdge = null; // start actual loop recreation StringBuilder wholeLoopString = new StringBuilder(); // we go into a loop thus we have to uproll it right now, and add all // handled edges to the handledEdges list, so they wont occur twice in the // generated c code // this should be already handled by the handledEdges check at the beginning // of the processEdge method assert loopsAfter.get(loopsAfter.size() - 1).getIncomingEdges().contains(pCFAEdge); Loop loop = loopsAfter.get(loopsAfter.size() - 1); // create necessary mappings String labelStayInLoop = createFreshLabelForLoop(pCFAEdge, loop); // uproll loop and write code wholeLoopString.append(labelStayInLoop).append(": ;\n"); Deque<CFAEdge> edgesToHandle = new ArrayDeque<>(); edgesToHandle.offer(pCFAEdge); Deque<Loop> loopStack = new ArrayDeque<>(); loopStack.push(loop); Deque<CFAEdge> ifStack = new ArrayDeque<>(); Deque<CFAEdge> outOfLoopEdgesStack = new ArrayDeque<>(); while ((!edgesToHandle.isEmpty() || !outOfLoopEdgesStack.isEmpty() || !ifStack.isEmpty())) { // all nodes from the current loop handled, so we can go on to the // next one if (edgesToHandle.isEmpty()) { // at first we need to handle ifs if (!ifStack.isEmpty()) { edgesToHandle.offer(ifStack.pop()); wholeLoopString.append("goto ").append(ifOutLabels.get(edgesToHandle.peek())).append(";\n") .append(ifElseLabels.get(edgesToHandle.peek())).append(": ;\n"); } else { edgesToHandle.offer(outOfLoopEdgesStack.pop()); Loop oldLoop = loopStack.pop(); wholeLoopString.append("goto ").append(loopInLabels.get(oldLoop)).append(";\n") .append(loopOutLabels.get(oldLoop)).append(": ;\n"); } } CFANode currentEdgePredecessor = edgesToHandle.peek().getPredecessor(); handleIfOutLabels(wholeLoopString, currentEdgePredecessor); // only continue if we didn't already visit this edge if (handledEdges.contains(edgesToHandle.peek())) { edgesToHandle.pop(); continue; } CFAEdge currentEdge = edgesToHandle.pop(); handledEdges.add(currentEdge); FluentIterable<CFAEdge> leaving = CFAUtils.leavingEdges(currentEdge.getSuccessor()) .filter(not(instanceOf(FunctionCallEdge.class))); // there was a function call, we need to replace it with the correct successor // as we are sure that there is only one, this is safe, we also don't // need to update loops here if (leaving.isEmpty()) { CFAEdge realLeavingEdge = currentEdge.getSuccessor().getLeavingEdge(0); CFAEdge leavingSummaryEdge = currentEdge.getSuccessor().getLeavingSummaryEdge(); wholeLoopString.append(processSimpleWithLoop(realLeavingEdge, currentBlock, "")); handledFunctions.add(((CFunctionEntryNode) realLeavingEdge.getSuccessor()).getFunctionName()); leaving = leaving.append(leavingSummaryEdge); // no function call just and ordinary statement, add it as it is // to the loopString } else if (leaving.size() == 1) { wholeLoopString.append(processSimpleWithLoop(leaving.get(0), currentBlock, "")); } // only one successor, to handle // we need to check the loops so that we know if we need // to update the loopStack, or only the handledEdges if (leaving.size() == 1) { CFAEdge onlyEdge = leaving.get(0); // this is an edge from inside the loop back to the loop if (loopToHead.get(loopStack.peek()) == onlyEdge.getSuccessor() && !loopStack.peek().getIncomingEdges().contains(onlyEdge)) { handledEdges.add(onlyEdge); handleIfOutLabels(wholeLoopString, onlyEdge.getPredecessor()); } else { edgesToHandle.offer(onlyEdge); updateLoopStack(wholeLoopString, loopStack, onlyEdge); } // more sucessors, we have to add some gotos } else { // there can be at most two leaving edges assert leaving.size() == 2 : leaving.toString(); CFAEdge leaving1 = leaving.get(0); CFAEdge leaving2 = leaving.get(1); // outgoing edges have to be handled first, this way // we can create the goto easier ImmutableSet<CFAEdge> outOfCurrentLoop = loopStack.peek().getOutgoingEdges(); boolean isOutOfLoopContained = false; CFAEdge leavingLoopEdge = null; if (outOfCurrentLoop.contains(leaving1)) { handleOutOfLoopEdge(currentBlock, wholeLoopString, edgesToHandle, loopStack, leaving1, leaving2); leavingLoopEdge = leaving1; isOutOfLoopContained = true; } else if (outOfCurrentLoop.contains(leaving2)) { handleOutOfLoopEdge(currentBlock, wholeLoopString, edgesToHandle, loopStack, leaving2, leaving1); leavingLoopEdge = leaving2; isOutOfLoopContained = true; } if (isOutOfLoopContained) { // we are alredy in the outermost loop that should be handled // if we have an edge which is leaving this loop we just need // to create a goto if (loopStack.size() == 1) { lastEdge = leavingLoopEdge; handledEdges.add(leavingLoopEdge); // deeper loopstack, potentially the same code as above // we do only need to handle the successor of the outOfLoopEdge, too } else { outOfLoopEdgesStack.push(leavingLoopEdge); } // end this loop iteration here continue; } // now comes the case where both edges stay in the loop, this means // this is a "simple" if statement // we need to find the merging point of both branches, such that we // know where the gotos and labels have to go if (!handledEdges.contains(leaving1)) { wholeLoopString.append(processSimpleWithLoop(leaving1, currentBlock, createFreshLabelForIf(leaving2, findEndOfBranches(singletonList(loopToHead.get(loopStack.peek())), currentEdgePredecessor, leaving1.getSuccessor(), leaving2.getSuccessor())))); edgesToHandle.push(leaving1); ifStack.push(leaving2); } } } wholeLoopString.append("goto ").append(loopInLabels.get(loop)).append(";\n").append(loopOutLabels.get(loop)) .append(": ;\n"); // assert ifOutLabelEnd.isEmpty() && loopStack.isEmpty(); return Pair.of(wholeLoopString.toString(), lastEdge); }