Commit 9a3ff478 authored by Stephen Kelly's avatar Stephen Kelly
Browse files

Fix the invisible-traversal to ignore more nodes

parent 39f13354
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -2900,6 +2900,12 @@ static Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
  return IgnoreImplicitSingleStep(E);
}

static Expr *IgnoreParensOnlySingleStep(Expr *E) {
  if (auto *PE = dyn_cast<ParenExpr>(E))
    return PE->getSubExpr();
  return E;
}

static Expr *IgnoreParensSingleStep(Expr *E) {
  if (auto *PE = dyn_cast<ParenExpr>(E))
    return PE->getSubExpr();
@@ -3026,7 +3032,8 @@ Expr *Expr::IgnoreUnlessSpelledInSource() {
  Expr *LastE = nullptr;
  while (E != LastE) {
    LastE = E;
    E = E->IgnoreParenImpCasts();
    E = IgnoreExprNodes(E, IgnoreImplicitSingleStep, IgnoreImpCastsSingleStep,
                        IgnoreParensOnlySingleStep);

    auto SR = E->getSourceRange();

+84 −1
Original line number Diff line number Diff line
@@ -260,7 +260,90 @@ TemplateArgument
            19u);
}

TEST(Traverse, IgnoreUnlessSpelledInSource) {
TEST(Traverse, IgnoreUnlessSpelledInSourceStructs) {
  auto AST = buildASTFromCode(R"cpp(

struct MyStruct {
  MyStruct();
  MyStruct(int i) {
    MyStruct();
  }
  ~MyStruct();
};

)cpp");

  auto BN = ast_matchers::match(
      cxxConstructorDecl(hasName("MyStruct"),
                         hasParameter(0, parmVarDecl(hasType(isInteger()))))
          .bind("ctor"),
      AST->getASTContext());
  EXPECT_EQ(BN.size(), 1u);

  EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
                          BN[0].getNodeAs<Decl>("ctor")),
            R"cpp(
CXXConstructorDecl 'MyStruct'
|-ParmVarDecl 'i'
`-CompoundStmt
  `-CXXTemporaryObjectExpr
)cpp");

  EXPECT_EQ(
      dumpASTString(ast_type_traits::TK_AsIs, BN[0].getNodeAs<Decl>("ctor")),
      R"cpp(
CXXConstructorDecl 'MyStruct'
|-ParmVarDecl 'i'
`-CompoundStmt
  `-ExprWithCleanups
    `-CXXBindTemporaryExpr
      `-CXXTemporaryObjectExpr
)cpp");
}

TEST(Traverse, IgnoreUnlessSpelledInSourceReturnStruct) {

  auto AST = buildASTFromCode(R"cpp(
struct Retval {
  Retval() {}
  ~Retval() {}
};

Retval someFun();

void foo()
{
    someFun();
}
)cpp");

  auto BN = ast_matchers::match(functionDecl(hasName("foo")).bind("fn"),
                                AST->getASTContext());
  EXPECT_EQ(BN.size(), 1u);

  EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
                          BN[0].getNodeAs<Decl>("fn")),
            R"cpp(
FunctionDecl 'foo'
`-CompoundStmt
  `-CallExpr
    `-DeclRefExpr 'someFun'
)cpp");

  EXPECT_EQ(
      dumpASTString(ast_type_traits::TK_AsIs, BN[0].getNodeAs<Decl>("fn")),
      R"cpp(
FunctionDecl 'foo'
`-CompoundStmt
  `-ExprWithCleanups
    `-CXXBindTemporaryExpr
      `-CallExpr
        `-ImplicitCastExpr
          `-DeclRefExpr 'someFun'
)cpp");
}

TEST(Traverse, IgnoreUnlessSpelledInSourceReturns) {

  auto AST = buildASTFromCode(R"cpp(