diff options
| -rw-r--r-- | mutator.cpp | 97 | 
1 files changed, 88 insertions, 9 deletions
| diff --git a/mutator.cpp b/mutator.cpp index 301e4a5..a1c4bb7 100644 --- a/mutator.cpp +++ b/mutator.cpp @@ -36,7 +36,7 @@ using namespace clang::tooling;  /*the variable that holds the previously-matched SOC for class StmtTrap.*/  std::string g_linenoold; -static llvm::cl::OptionCategory MatcherSampleCategory("Matcher Sample"); +static llvm::cl::OptionCategory MutatorLVL1Cat("mutator-lvl1 options category");  /**********************************************************************************************************************/  /*matcher callback for something.*/  class FunctionHandler : public MatchFinder::MatchCallback { @@ -221,15 +221,23 @@ public:      {        const ForStmt *MRFor = MR.Nodes.getNodeAs<clang::ForStmt>("mrfor"); +      Rewriter::RewriteOptions opts; +        SourceLocation MRForSL = MRFor->getBody()->getLocStart();        MRForSL = Devi::SourceLocationHasMacro(MRForSL, Rewrite, "start");        SourceLocation MRForSLE = MRFor->getBody()->getLocEnd();        MRForSLE = Devi::SourceLocationHasMacro(MRForSLE, Rewrite, "end"); +      SourceRange SR; +      SR.setBegin(MRForSL); +      SR.setEnd(MRForSLE); + +      int RangeSize = Rewrite.getRangeSize(SR, opts); +        Rewrite.InsertText(MRForSL, "{\n", true, false);        /*we're getting the endloc with an offset of 2 to accomodate unary operators like '++'.*/        /*line-terminating semicolons are not included in the matches.*/ -      Rewrite.InsertTextAfterToken(MRForSLE.getLocWithOffset(2U), "\n}"); +      Rewrite.InsertTextAfterToken(MRForSL.getLocWithOffset(RangeSize), "\n}");      }      else      { @@ -450,12 +458,76 @@ private:    Rewriter &Rewrite;  };  /**********************************************************************************************************************/ +class IfConstSwapper : public MatchFinder::MatchCallback +{ +public: +  IfConstSwapper (Rewriter &Rewrite) : Rewrite(Rewrite) {} + +  virtual void run(const MatchFinder::MatchResult &MR) +  { +    if (MR.Nodes.getNodeAs<clang::BinaryOperator>("ifconstswapbinop") != nullptr) +    { +      const BinaryOperator* BO = MR.Nodes.getNodeAs<clang::BinaryOperator>("ifconstswapbinop"); + +      const Expr* LHS = BO->getLHS(); +      const Expr* RHS = BO->getRHS(); + +      ASTContext *const ASTC = MR.Context; +      SourceManager *const SM = MR.SourceManager; + +      if (RHS->isEvaluatable(*ASTC, Expr::SideEffectsKind::SE_NoSideEffects) && !LHS->isEvaluatable(*ASTC, Expr::SideEffectsKind::SE_NoSideEffects)) +      { +        SourceLocation SLLHS = LHS->getLocStart(); +        SLLHS = Devi::SourceLocationHasMacro(SLLHS, Rewrite, "start"); +        SourceLocation SLELHS = LHS->getLocStart(); +        SLELHS = Devi::SourceLocationHasMacro(SLELHS, Rewrite, "start"); +        SourceRange SRLHS; +        SRLHS.setBegin(SLLHS); +        SRLHS.setEnd(SLELHS); + +        if (!SM->isInMainFile(SLLHS)) +        { +          return void(); +        } + +        if (SM->isInSystemHeader(SLLHS)) +        { +          return void(); +        } + +        SourceLocation SLRHS = RHS->getLocStart(); +        SLRHS = Devi::SourceLocationHasMacro(SLRHS, Rewrite, "start"); +        SourceLocation SLERHS = RHS->getLocEnd(); +        SLERHS = Devi::SourceLocationHasMacro(SLERHS, Rewrite, "start"); +        SourceRange SRRHS; +        SRRHS.setBegin(SLRHS); +        SRRHS.setEnd(SLERHS); + +        const std::string LHSString = Rewrite.getRewrittenText(SRLHS); +        const std::string RHSString = Rewrite.getRewrittenText(SRRHS); + +        StringRef LHSRef = StringRef(LHSString); +        StringRef RHSRef = StringRef(RHSString); + +        Rewriter::RewriteOptions opts; +        int RangeSizeLHS = Rewrite.getRangeSize(SRLHS, opts); +        int RangeSizeRHS = Rewrite.getRangeSize(SRRHS, opts); + +        Rewrite.ReplaceText(SRLHS.getBegin(), RangeSizeLHS, RHSRef); +        Rewrite.ReplaceText(SRRHS.getBegin(), RangeSizeRHS, LHSRef); +      } +    } +  } + +private: +  Rewriter &Rewrite; +};  /**********************************************************************************************************************/  class MyASTConsumer : public ASTConsumer {  public:    MyASTConsumer(Rewriter &R) : HandlerForFunction(R), HandlerForIfTrap(R), HandlerForStmtTrap(R), HandlerForStmtRet(R), HandlerForFixer(R), \ -    HandlerForWhile(R), HandlerForIfElse(R), HandlerForIfFixer(R), HandlerForSwitchFixer(R), HandlerForSwitchDf(R) +    HandlerForWhile(R), HandlerForIfElse(R), HandlerForIfFixer(R), HandlerForSwitchFixer(R), HandlerForSwitchDf(R), HandlerForIfConstSwap(R)    {      Matcher.addMatcher(binaryOperator(hasOperatorName("==")).bind("binopeq"), &HandlerForFunction); @@ -476,9 +548,11 @@ public:      Matcher.addMatcher(switchStmt(forEachDescendant(caseStmt(unless(hasDescendant(compoundStmt()))).bind("bubba-hotep"))), &HandlerForSwitchFixer);      Matcher.addMatcher(switchStmt(hasDescendant(defaultStmt(unless(hasDescendant(compoundStmt()))).bind("mumma-hotep"))), &HandlerForSwitchDf); + +    Matcher.addMatcher(ifStmt(hasDescendant(binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("="))).bind("ifconstswapbinop"))).bind("ifconstswapper"), &HandlerForIfConstSwap);    } -  void HandleTranslationUnit(ASTContext &Context) override { +  void HandleTranslationUnit(ASTContext & Context) override {      Matcher.matchAST(Context);    } @@ -493,17 +567,21 @@ private:    IfFixer HandlerForIfFixer;    SwitchFixer HandlerForSwitchFixer;    SwitchDfFixer HandlerForSwitchDf; +  IfConstSwapper HandlerForIfConstSwap;    MatchFinder Matcher;  };  /**********************************************************************************************************************/ -class MyFrontendAction : public ASTFrontendAction { +class MyFrontendAction : public ASTFrontendAction +{  public:    MyFrontendAction() {} -  void EndSourceFileAction() override { +  void EndSourceFileAction() override +  {      TheRewriter.getEditBuffer(TheRewriter.getSourceMgr().getMainFileID()).write(llvm::outs());    } -  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) override { +  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef file) override +  {      TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());      return llvm::make_unique<MyASTConsumer>(TheRewriter);    } @@ -513,8 +591,9 @@ private:  };  /**********************************************************************************************************************/  /*Main*/ -int main(int argc, const char **argv) { -  CommonOptionsParser op(argc, argv, MatcherSampleCategory); +int main(int argc, const char **argv) +{ +  CommonOptionsParser op(argc, argv, MutatorLVL1Cat);    ClangTool Tool(op.getCompilations(), op.getSourcePathList());    return Tool.run(newFrontendActionFactory<MyFrontendAction>().get()); | 
