[cfe-dev] Calling an ASTMatcher from inside a MatchCallback results in Duplicate runs of the ASTMatcher

Farzad Sadeghi via cfe-dev cfe-dev at lists.llvm.org
Mon Mar 30 07:29:28 PDT 2020


I have the following two MatchCallbacks:
/***********************************************************************************************/
class TraceVarHandlerSub : public MatchFinder::MatchCallback {
public:
  explicit TraceVarHandlerSub(Rewriter &Rewrite) : Rewrite(Rewrite) {}

  virtual void run(const MatchFinder::MatchResult &MR) {
    const DeclRefExpr *DRE =
        MR.Nodes.getNodeAs<clang::DeclRefExpr>("tracevardeclrefexpr");
    if (DRE) {
      if (DRE->getFoundDecl() == ND) {
        std::cout << DRE->getLocation().printToString(*(MR.SourceManager))
                  << "\n";
      }
    }
  }

  void setND(NamedDecl const * Original_Declaration) {
    ND = Original_Declaration;
  }

private:
  Rewriter &Rewrite [[maybe_unused]];
  NamedDecl const *ND;
};
/***********************************************************************************************/
class TraceVarHandler : public MatchFinder::MatchCallback {
public:
  explicit TraceVarHandler(Rewriter &Rewrite)
      : Rewrite(Rewrite), SubMatcher(Rewrite) {}

  virtual void run(const MatchFinder::MatchResult &MR) {
    const VarDecl *VD = MR.Nodes.getNodeAs<clang::VarDecl>("tracevar");
    if (VD) {
      SourceRange SR = VD->getSourceRange();
      SourceLocation SL = SR.getBegin();
      auto NameRef = VD->getName();
      if (!NameRef.empty()) {
        SubMatcher.setND(VD->getCanonicalDecl()->getUnderlyingDecl());
        Matcher.addMatcher(declRefExpr(to(varDecl(hasName(VD->getName()))))
                               .bind("tracevardeclrefexpr"),
                           &SubMatcher);
        Matcher.matchAST(*(MR.Context));
      }
    }
  }

private:
  MatchFinder Matcher;
  Rewriter &Rewrite [[maybe_unused]];
  TraceVarHandlerSub SubMatcher;
};
/***********************************************************************************************/
TraceVarHandler is called whenever there is a match for a "varDecl",
then it runs TraceVarHandlerSub to match "declRefExpr"s that have that
have the same name and "NamedDecl".

When i run the following code on this example(main.c):
/***********************************************************************************************/
int aloha(int a) {
  return a + a;
}

int dodo(int a) {
  return a * a * 2;
}

int main (int argc, char** argv) {
  int a = 10;
  return a*a;
}
/***********************************************************************************************/
I get this:
main.c:2:10
main.c:2:14
main.c:6:10
main.c:6:10
main.c:6:14
main.c:6:14
main.c:11:10
main.c:11:10
main.c:11:10
main.c:11:12
main.c:11:12
main.c:11:12

The second  and third set of matches get double and triple the matches.
My llvm/clang version:
clang version 9.0.0-2~ubuntu18.04.2 (tags/RELEASE_900/final)

what I've tried:
It's not a simple output print duplicaiton. the output matches to
exactly how many times
TraceVarHandlerSub ::run() gets called.
Not using the same instance of TraceVarHandlerSub(calling new to
create a new instance inside TraceVarHandler::run()) will result in
the same output except some other results get doubled or trippled.

Do I need to set or reset something? Do something with ASTContext?



-- 
Farzad Sadeghi
project mutator-https://github.com/bloodstalker/mutator


More information about the cfe-dev mailing list