diff --git a/include/revng-c/RestructureCFGPass/ASTNode.h b/include/revng-c/RestructureCFGPass/ASTNode.h index 41880f084..15adedac9 100644 --- a/include/revng-c/RestructureCFGPass/ASTNode.h +++ b/include/revng-c/RestructureCFGPass/ASTNode.h @@ -257,6 +257,8 @@ public: void dump(std::ofstream &ASTFile); + void updateASTNodesPointers(ASTNodeMap &SubstitutionMap); + ASTNode *Clone() const { return new ScsNode(*this); } bool isStandard() const { return LoopType == Type::Standard; } @@ -580,12 +582,43 @@ inline ASTNode *ASTNode::Clone() const { } inline void ASTNode::updateASTNodesPointers(ASTNodeMap &SubstitutionMap) { - if (IfNode *If = llvm::dyn_cast(this)) { + if (Successor) + Successor = SubstitutionMap.at(Successor); + + switch (getKind()) { + case ASTNode::NK_If: { + auto *If = llvm::cast(this); If->updateASTNodesPointers(SubstitutionMap); - } else if (SequenceNode *Seq = llvm::dyn_cast(this)) { - Seq->updateASTNodesPointers(SubstitutionMap); - } else if (SwitchNode *Switch = llvm::dyn_cast(this)) { + } break; + + case ASTNode::NK_Switch: { + auto *Switch = llvm::dyn_cast(this); Switch->updateASTNodesPointers(SubstitutionMap); + } break; + + case ASTNode::NK_Scs: { + } break; + + case ASTNode::NK_Continue: { + auto *Continue = llvm::dyn_cast(this); + // If it has a computation we have to update it. + revng_assert(not Continue->hasComputation()); + } break; + + case ASTNode::NK_Code: + case ASTNode::NK_Break: + case ASTNode::NK_SwitchBreak: + case ASTNode::NK_Set: { + // They only have a successor + } break; + + case ASTNode::NK_List: { + auto *Seq = llvm::cast(this); + Seq->updateASTNodesPointers(SubstitutionMap); + } break; + + default: + revng_abort("AST node type not expected"); } } diff --git a/include/revng-c/RestructureCFGPass/GenerateAst.h b/include/revng-c/RestructureCFGPass/GenerateAst.h index b10c21026..9a8d850da 100644 --- a/include/revng-c/RestructureCFGPass/GenerateAst.h +++ b/include/revng-c/RestructureCFGPass/GenerateAst.h @@ -44,35 +44,46 @@ inline ASTNode *createSequence(ASTTree &Tree, ASTNode *RootNode) { RootSequenceNode->addNode(RootNode); for (ASTNode *Node : RootSequenceNode->nodes()) { - if (auto *If = llvm::dyn_cast(Node)) { - if (If->hasThen()) { - If->setThen(createSequence(Tree, If->getThen())); - } - if (If->hasElse()) { - If->setElse(createSequence(Tree, If->getElse())); - } - } else if (llvm::isa(Node)) { - // TODO: confirm that doesn't make sense to process a code node. - } else if (llvm::isa(Node)) { - // TODO: confirm that this phase is not needed since the processing is - // done inside the processing of each SCS region. - } else if (auto *Switch = llvm::dyn_cast(Node)) { + switch (Node->getKind()) { + + case ASTNode::NK_If: { + auto *If = llvm::cast(Node); + + if (If->hasThen()) + If->setThen(createSequence(Tree, If->getThen())); + if (If->hasElse()) + If->setElse(createSequence(Tree, If->getElse())); + } break; + + case ASTNode::NK_Switch: { + auto *Switch = llvm::cast(Node); for (auto &LabelCasePair : Switch->cases()) LabelCasePair.second = createSequence(Tree, LabelCasePair.second); if (ASTNode *Default = Switch->getDefault()) Switch->replaceDefault(createSequence(Tree, Default)); + } break; - } else if (llvm::isa(Node)) { - // Stop here during the analysis. - } else if (llvm::isa(Node)) { - // Stop here during the analysis. - } else if (llvm::isa(Node)) { - // Stop here during the analysis. - } else if (llvm::isa(Node)) { - // Stop here during the analysis. - } else { + case ASTNode::NK_Scs: { + auto *Scs = llvm::cast(Node); + if (Scs->hasBody()) + Scs->setBody(createSequence(Tree, Scs->getBody())); + } break; + + case ASTNode::NK_Code: { + // TODO: confirm that doesn't make sense to process a code node. + } break; + + case ASTNode::NK_Continue: + case ASTNode::NK_Break: + case ASTNode::NK_SwitchBreak: + case ASTNode::NK_Set: { + // Do nothing for these nodes + } break; + + case ASTNode::NK_List: + default: revng_abort("AST node type not expected"); } } @@ -122,7 +133,12 @@ inline void simplifyDummies(ASTNode *RootNode) { } break; - case ASTNode::NK_Scs: + case ASTNode::NK_Scs: { + auto *Scs = llvm::cast(RootNode); + if (Scs->hasBody()) + simplifyDummies(Scs->getBody()); + } break; + case ASTNode::NK_Code: case ASTNode::NK_Continue: case ASTNode::NK_Break: @@ -207,9 +223,6 @@ inline ASTNode *simplifyAtomicSequence(ASTNode *RootNode) { } break; case ASTNode::NK_Scs: { - // TODO: check if this is not needed as the simplification is done for each - // SCS region. - // After flattening this situation may arise again. auto *Scs = llvm::cast(RootNode); if (Scs->hasBody()) Scs->setBody(simplifyAtomicSequence(Scs->getBody())); diff --git a/lib/RestructureCFGPass/ASTNode.cpp b/lib/RestructureCFGPass/ASTNode.cpp index ebf6c12dd..5ce9974ac 100644 --- a/lib/RestructureCFGPass/ASTNode.cpp +++ b/lib/RestructureCFGPass/ASTNode.cpp @@ -49,6 +49,13 @@ void IfNode::updateASTNodesPointers(ASTNodeMap &SubstitutionMap) { } } +void ScsNode::updateASTNodesPointers(ASTNodeMap &SubstitutionMap) { + if (RelatedCondition) + Body = SubstitutionMap.at(RelatedCondition); + revng_assert(Body); + Body = SubstitutionMap.at(Body); +} + void SequenceNode::updateASTNodesPointers(ASTNodeMap &SubstitutionMap) { // Update all the pointers of the sequence node. for (auto NodeIt = NodeList.begin(); NodeIt != NodeList.end(); NodeIt++) {