diff options
| -rw-r--r-- | mutator.cpp | 108 | 
1 files changed, 105 insertions, 3 deletions
| diff --git a/mutator.cpp b/mutator.cpp index 3af8e2b..e634acc 100644 --- a/mutator.cpp +++ b/mutator.cpp @@ -28,7 +28,8 @@ using namespace clang::driver;  using namespace clang::tooling;  /**********************************************************************************************************************/  /*global vars*/ - +/*the variable that holds the previously-matched SOC for class StmtTrap.*/ +std::string g_linenoold;  static llvm::cl::OptionCategory MatcherSampleCategory("Matcher Sample");  /**********************************************************************************************************************/ @@ -41,7 +42,6 @@ public:    {      if (MR.Nodes.getNodeAs<clang::BinaryOperator>("binopeq") != nullptr)      { -      /*underdev*/        /*get the matched node.*/        const BinaryOperator *BinOp = MR.Nodes.getNodeAs<clang::BinaryOperator>("binopeq"); @@ -59,7 +59,9 @@ public:        }        /*replace it.*/ +#if 0        Rewrite.ReplaceText(BinOpSL, 2U , "XXX"); +#endif      }      else      { @@ -71,12 +73,110 @@ private:    Rewriter &Rewrite;  };  /**********************************************************************************************************************/ +class StmtTrapIf : public MatchFinder::MatchCallback { +public: +  StmtTrapIf (Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run (const MatchFinder::MatchResult &MR) +  { +    /*just in case*/ +    if (MR.Nodes.getNodeAs<clang::IfStmt>("iftrap") != nullptr) +    { +      /*getting the matched ifStmt.*/ +      const IfStmt *TrapIf = MR.Nodes.getNodeAs<clang::IfStmt>("iftrap"); + +      /*getting the condition of the matched ifStmt.*/ +      const Expr *IfCond = TrapIf->getCond(); + +      /*getting the sourcerange of the condition of the trapped ifstmt.*/ +      SourceLocation TrapIfCondSL = IfCond->getLocStart(); +      SourceLocation TrapIfCondSLEnd = IfCond->getLocEnd(); +      SourceRange TrapIfCondSR; +      TrapIfCondSR.setBegin(TrapIfCondSL); +      TrapIfCondSR.setEnd(TrapIfCondSLEnd); + +      /*replacing the condition with the utility trap function.*/ +      Rewrite.ReplaceText(TrapIfCondSR, "C_Trap_P()"); +    } +    else +    { +      std::cout << "the matcher -iftrap- returned nullptr!" << std::endl; +    } +  } + +private: +  Rewriter &Rewrite; +}; +/**********************************************************************************************************************/ +class StmtTrap : public MatchFinder::MatchCallback { +public: +  StmtTrap (Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  /*if there are more than 2 statements in the traditional sense in one line, the behavior is undefined.*/ +  /*for now this class only finds an SOC. later to be used for something useful.*/ +  virtual void run (const MatchFinder::MatchResult &MR) +  { +    /*out of paranoia*/ +    if (MR.Nodes.getNodeAs<clang::Stmt>("stmttrap") != nullptr) +    { +      const Stmt *StmtTrapMR = MR.Nodes.getNodeAs<clang::Stmt>("stmttrap"); + +      SourceLocation STSL = StmtTrapMR->getLocStart(); +      SourceLocation STSLE = StmtTrapMR->getLocEnd(); + +      /*just getting the SOC of the matched statement out of its sourcelocation.*/ +      /*this only works since we are guaranteed the same and known matching pattern by MatchFinder.*/ +      size_t startloc = 0U; +      size_t endloc = 0U; +      std::string lineno; +      startloc = STSL.printToString(*MR.SourceManager).find(":", 0U); +      endloc = STSLE.printToString(*MR.SourceManager).find(":", startloc + 1U); +      lineno = STSL.printToString(*MR.SourceManager).substr(startloc, endloc - startloc); + +      /*just prints out the sourcelocations for diagnostics.*/ +#if 0 +      std::cout << STSL.printToString(*MR.SourceManager) << std::endl; +      std::cout << STSLE.printToString(*MR.SourceManager) << std::endl; +      std::cout << startloc << "---" << endloc << "---" << lineno << std::endl; +#endif + +      /*have we matched a new SOC? if yes:*/ +      if (lineno != g_linenoold) +      { +        SourceRange SR; +        SR.setBegin(StmtTrapMR->getLocStart()); +        SR.setEnd(StmtTrapMR->getLocEnd()); + +        //Rewrite.InsertText(StmtTrapMR->getLocStart(), "XXX", "true", "true"); +      } +      else +      { +        /*intentionally left blank.*/ +      } + +      /*set the string representing the old SOC line number to the one matched now.*/ +      g_linenoold = lineno; +    } +    else +    { +      std::cout << "the matcher -stmttrap- returned nullptr!" << std::endl; +    } +  } + +private: +  Rewriter &Rewrite; +}; +/**********************************************************************************************************************/  /**********************************************************************************************************************/  class MyASTConsumer : public ASTConsumer {  public: -  MyASTConsumer(Rewriter &R) : HandlerForFunction(R) { +  MyASTConsumer(Rewriter &R) : HandlerForFunction(R), HandlerForIfTrap(R), HandlerForStmtTrap(R) {      Matcher.addMatcher(binaryOperator(hasOperatorName("==")).bind("binopeq"), &HandlerForFunction); + +    Matcher.addMatcher(ifStmt(hasCondition(anything())).bind("iftrap"), &HandlerForIfTrap); + +    Matcher.addMatcher(stmt().bind("stmttrap") , &HandlerForStmtTrap);    }    void HandleTranslationUnit(ASTContext &Context) override { @@ -85,6 +185,8 @@ public:  private:    FunctionHandler HandlerForFunction; +  StmtTrapIf HandlerForIfTrap; +  StmtTrap HandlerForStmtTrap;    MatchFinder Matcher;  };  /**********************************************************************************************************************/ | 
