Re: r361033 - Add a Visit overload for DynTypedNode to ASTNodeTraverser

2019-05-17 Thread Nico Weber via cfe-commits
*From: *Stephen Kelly via cfe-commits 
*Date: *Fri, May 17, 2019 at 1:56 PM
*To: *Yitzhak Mandelbaum
*Cc: *cfe-commits

Hmm, thanks for letting me know!
>
> Is that an old compiler?
>
> I'm not near a computer for the weekend.
>
> Can someone fix or revert?
>

Sure, reverted in 361059.


>
> Thanks,
>
> Stephen.
>
> On Fri 17 May 2019, 17:11 Yitzhak Mandelbaum,  wrote:
>
>> Looks like this caused a breakage:
>> http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio
>>
>> On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Author: steveire
>>> Date: Fri May 17 06:55:28 2019
>>> New Revision: 361033
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=361033&view=rev
>>> Log:
>>> Add a Visit overload for DynTypedNode to ASTNodeTraverser
>>>
>>> Reviewers: aaron.ballman
>>>
>>> Subscribers: cfe-commits
>>>
>>> Tags: #clang
>>>
>>> Differential Revision: https://reviews.llvm.org/D61834
>>>
>>> Added:
>>> cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>>> Modified:
>>> cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>>> cfe/trunk/unittests/AST/CMakeLists.txt
>>>
>>> Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff
>>>
>>> ==
>>> --- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
>>> +++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28
>>> 2019
>>> @@ -205,6 +205,24 @@ public:
>>>  });
>>>}
>>>
>>> +  void Visit(const ast_type_traits::DynTypedNode &N) {
>>> +// FIXME: Improve this with a switch or a visitor pattern.
>>> +if (const auto *D = N.get())
>>> +  Visit(D);
>>> +else if (const auto *S = N.get())
>>> +  Visit(S);
>>> +else if (const auto *QT = N.get())
>>> +  Visit(*QT);
>>> +else if (const auto *T = N.get())
>>> +  Visit(T);
>>> +else if (const auto *C = N.get())
>>> +  Visit(C);
>>> +else if (const auto *C = N.get())
>>> +  Visit(C);
>>> +else if (const auto *T = N.get())
>>> +  Visit(*T);
>>> +  }
>>> +
>>>void dumpDeclContext(const DeclContext *DC) {
>>>  if (!DC)
>>>return;
>>>
>>> Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto
>>>
>>> ==
>>> --- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)
>>> +++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019
>>> @@ -0,0 +1,220 @@
>>> +//===-
>>> unittests/AST/ASTTraverserTest.h===//
>>> +//
>>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>>> Exceptions.
>>> +// See https://llvm.org/LICENSE.txt for license information.
>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>>> +//
>>>
>>> +//===--===//
>>> +
>>> +#include "clang/AST/ASTContext.h"
>>> +#include "clang/AST/ASTNodeTraverser.h"
>>> +#include "clang/AST/TextNodeDumper.h"
>>> +#include "clang/ASTMatchers/ASTMatchFinder.h"
>>> +#include "clang/ASTMatchers/ASTMatchers.h"
>>> +#include "clang/Tooling/Tooling.h"
>>> +#include "gmock/gmock.h"
>>> +#include "gtest/gtest.h"
>>> +
>>> +using namespace clang::tooling;
>>> +using namespace clang::ast_matchers;
>>> +
>>> +namespace clang {
>>> +
>>> +class NodeTreePrinter : public TextTreeStructure {
>>> +  llvm::raw_ostream &OS;
>>> +
>>> +public:
>>> +  NodeTreePrinter(llvm::raw_ostream &OS)
>>> +  : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
>>> +
>>> +  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }
>>> +
>>> +  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }
>>> +
>>> +  void Visit(QualType QT) {
>>> +OS << "QualType " << QT.split().Quals.getAsString();
>>> +  }
>>> +
>>> +  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }
>>> +
>>> +  void Visit(const comments::Comment *C, const comments::FullComment
>>> *FC) {
>>> +OS << C->getCommentKindName();
>>> +  }
>>> +
>>> +  void Visit(const CXXCtorInitializer *Init) { OS <<
>>> "CXXCtorInitializer"; }
>>> +
>>> +  void Visit(const Attr *A) {
>>> +switch (A->getKind()) {
>>> +#define ATTR(X)
>>> \
>>> +  case attr::X:
>>> \
>>> +OS << #X;
>>> \
>>> +break;
>>> +#include "clang/Basic/AttrList.inc"
>>> +}
>>> +OS << "Attr";
>>> +  }
>>> +
>>> +  void Visit(const OMPClause *C) { OS << "OMPClause"; }
>>> +  void Visit(const TemplateArgument &A, SourceRange R = {},
>>> + const Decl *From = nullptr, const char *Label = nullptr) {
>>> +OS << "TemplateArgument";
>>> +  }
>>> +
>>> +  

Re: r361033 - Add a Visit overload for DynTypedNode to ASTNodeTraverser

2019-05-17 Thread Yitzhak Mandelbaum via cfe-commits
i'll see if i can repro on my build and fix if so.

On Fri, May 17, 2019 at 1:56 PM Stephen Kelly  wrote:

> Hmm, thanks for letting me know!
>
> Is that an old compiler?
>
> I'm not near a computer for the weekend.
>
> Can someone fix or revert?
>
> Thanks,
>
> Stephen.
>
> On Fri 17 May 2019, 17:11 Yitzhak Mandelbaum,  wrote:
>
>> Looks like this caused a breakage:
>> http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio
>>
>> On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Author: steveire
>>> Date: Fri May 17 06:55:28 2019
>>> New Revision: 361033
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=361033&view=rev
>>> Log:
>>> Add a Visit overload for DynTypedNode to ASTNodeTraverser
>>>
>>> Reviewers: aaron.ballman
>>>
>>> Subscribers: cfe-commits
>>>
>>> Tags: #clang
>>>
>>> Differential Revision: https://reviews.llvm.org/D61834
>>>
>>> Added:
>>> cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>>> Modified:
>>> cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>>> cfe/trunk/unittests/AST/CMakeLists.txt
>>>
>>> Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff
>>>
>>> ==
>>> --- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
>>> +++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28
>>> 2019
>>> @@ -205,6 +205,24 @@ public:
>>>  });
>>>}
>>>
>>> +  void Visit(const ast_type_traits::DynTypedNode &N) {
>>> +// FIXME: Improve this with a switch or a visitor pattern.
>>> +if (const auto *D = N.get())
>>> +  Visit(D);
>>> +else if (const auto *S = N.get())
>>> +  Visit(S);
>>> +else if (const auto *QT = N.get())
>>> +  Visit(*QT);
>>> +else if (const auto *T = N.get())
>>> +  Visit(T);
>>> +else if (const auto *C = N.get())
>>> +  Visit(C);
>>> +else if (const auto *C = N.get())
>>> +  Visit(C);
>>> +else if (const auto *T = N.get())
>>> +  Visit(*T);
>>> +  }
>>> +
>>>void dumpDeclContext(const DeclContext *DC) {
>>>  if (!DC)
>>>return;
>>>
>>> Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto
>>>
>>> ==
>>> --- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)
>>> +++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019
>>> @@ -0,0 +1,220 @@
>>> +//===-
>>> unittests/AST/ASTTraverserTest.h===//
>>> +//
>>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>>> Exceptions.
>>> +// See https://llvm.org/LICENSE.txt for license information.
>>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>>> +//
>>>
>>> +//===--===//
>>> +
>>> +#include "clang/AST/ASTContext.h"
>>> +#include "clang/AST/ASTNodeTraverser.h"
>>> +#include "clang/AST/TextNodeDumper.h"
>>> +#include "clang/ASTMatchers/ASTMatchFinder.h"
>>> +#include "clang/ASTMatchers/ASTMatchers.h"
>>> +#include "clang/Tooling/Tooling.h"
>>> +#include "gmock/gmock.h"
>>> +#include "gtest/gtest.h"
>>> +
>>> +using namespace clang::tooling;
>>> +using namespace clang::ast_matchers;
>>> +
>>> +namespace clang {
>>> +
>>> +class NodeTreePrinter : public TextTreeStructure {
>>> +  llvm::raw_ostream &OS;
>>> +
>>> +public:
>>> +  NodeTreePrinter(llvm::raw_ostream &OS)
>>> +  : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
>>> +
>>> +  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }
>>> +
>>> +  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }
>>> +
>>> +  void Visit(QualType QT) {
>>> +OS << "QualType " << QT.split().Quals.getAsString();
>>> +  }
>>> +
>>> +  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }
>>> +
>>> +  void Visit(const comments::Comment *C, const comments::FullComment
>>> *FC) {
>>> +OS << C->getCommentKindName();
>>> +  }
>>> +
>>> +  void Visit(const CXXCtorInitializer *Init) { OS <<
>>> "CXXCtorInitializer"; }
>>> +
>>> +  void Visit(const Attr *A) {
>>> +switch (A->getKind()) {
>>> +#define ATTR(X)
>>> \
>>> +  case attr::X:
>>> \
>>> +OS << #X;
>>> \
>>> +break;
>>> +#include "clang/Basic/AttrList.inc"
>>> +}
>>> +OS << "Attr";
>>> +  }
>>> +
>>> +  void Visit(const OMPClause *C) { OS << "OMPClause"; }
>>> +  void Visit(const TemplateArgument &A, SourceRange R = {},
>>> + const Decl *From = nullptr, const char *Label = nullptr) {
>>> +OS << "TemplateArgument";
>>> +  }
>>> +
>>> +  template  void Visit(T...) {}
>>> +};
>>> 

Re: r361033 - Add a Visit overload for DynTypedNode to ASTNodeTraverser

2019-05-17 Thread Stephen Kelly via cfe-commits
Hmm, thanks for letting me know!

Is that an old compiler?

I'm not near a computer for the weekend.

Can someone fix or revert?

Thanks,

Stephen.

On Fri 17 May 2019, 17:11 Yitzhak Mandelbaum,  wrote:

> Looks like this caused a breakage:
> http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio
>
> On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Author: steveire
>> Date: Fri May 17 06:55:28 2019
>> New Revision: 361033
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=361033&view=rev
>> Log:
>> Add a Visit overload for DynTypedNode to ASTNodeTraverser
>>
>> Reviewers: aaron.ballman
>>
>> Subscribers: cfe-commits
>>
>> Tags: #clang
>>
>> Differential Revision: https://reviews.llvm.org/D61834
>>
>> Added:
>> cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>> Modified:
>> cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>> cfe/trunk/unittests/AST/CMakeLists.txt
>>
>> Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff
>>
>> ==
>> --- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
>> +++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28
>> 2019
>> @@ -205,6 +205,24 @@ public:
>>  });
>>}
>>
>> +  void Visit(const ast_type_traits::DynTypedNode &N) {
>> +// FIXME: Improve this with a switch or a visitor pattern.
>> +if (const auto *D = N.get())
>> +  Visit(D);
>> +else if (const auto *S = N.get())
>> +  Visit(S);
>> +else if (const auto *QT = N.get())
>> +  Visit(*QT);
>> +else if (const auto *T = N.get())
>> +  Visit(T);
>> +else if (const auto *C = N.get())
>> +  Visit(C);
>> +else if (const auto *C = N.get())
>> +  Visit(C);
>> +else if (const auto *T = N.get())
>> +  Visit(*T);
>> +  }
>> +
>>void dumpDeclContext(const DeclContext *DC) {
>>  if (!DC)
>>return;
>>
>> Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto
>>
>> ==
>> --- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)
>> +++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019
>> @@ -0,0 +1,220 @@
>> +//===-
>> unittests/AST/ASTTraverserTest.h===//
>> +//
>> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
>> Exceptions.
>> +// See https://llvm.org/LICENSE.txt for license information.
>> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
>> +//
>>
>> +//===--===//
>> +
>> +#include "clang/AST/ASTContext.h"
>> +#include "clang/AST/ASTNodeTraverser.h"
>> +#include "clang/AST/TextNodeDumper.h"
>> +#include "clang/ASTMatchers/ASTMatchFinder.h"
>> +#include "clang/ASTMatchers/ASTMatchers.h"
>> +#include "clang/Tooling/Tooling.h"
>> +#include "gmock/gmock.h"
>> +#include "gtest/gtest.h"
>> +
>> +using namespace clang::tooling;
>> +using namespace clang::ast_matchers;
>> +
>> +namespace clang {
>> +
>> +class NodeTreePrinter : public TextTreeStructure {
>> +  llvm::raw_ostream &OS;
>> +
>> +public:
>> +  NodeTreePrinter(llvm::raw_ostream &OS)
>> +  : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
>> +
>> +  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }
>> +
>> +  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }
>> +
>> +  void Visit(QualType QT) {
>> +OS << "QualType " << QT.split().Quals.getAsString();
>> +  }
>> +
>> +  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }
>> +
>> +  void Visit(const comments::Comment *C, const comments::FullComment
>> *FC) {
>> +OS << C->getCommentKindName();
>> +  }
>> +
>> +  void Visit(const CXXCtorInitializer *Init) { OS <<
>> "CXXCtorInitializer"; }
>> +
>> +  void Visit(const Attr *A) {
>> +switch (A->getKind()) {
>> +#define ATTR(X)
>>   \
>> +  case attr::X:
>>   \
>> +OS << #X;
>>   \
>> +break;
>> +#include "clang/Basic/AttrList.inc"
>> +}
>> +OS << "Attr";
>> +  }
>> +
>> +  void Visit(const OMPClause *C) { OS << "OMPClause"; }
>> +  void Visit(const TemplateArgument &A, SourceRange R = {},
>> + const Decl *From = nullptr, const char *Label = nullptr) {
>> +OS << "TemplateArgument";
>> +  }
>> +
>> +  template  void Visit(T...) {}
>> +};
>> +
>> +class TestASTDumper : public ASTNodeTraverser> NodeTreePrinter> {
>> +
>> +  NodeTreePrinter MyNodeRecorder;
>> +
>> +public:
>> +  TestASTDumper(llvm::raw_ostream &OS) : MyNodeRecorder(OS) {}
>> +  NodeTreePrinter &doGetNodeDelegate() { return MyNodeRecorder; }
>> +};
>

Re: r361033 - Add a Visit overload for DynTypedNode to ASTNodeTraverser

2019-05-17 Thread Yitzhak Mandelbaum via cfe-commits
Looks like this caused a breakage:
http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio

On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: steveire
> Date: Fri May 17 06:55:28 2019
> New Revision: 361033
>
> URL: http://llvm.org/viewvc/llvm-project?rev=361033&view=rev
> Log:
> Add a Visit overload for DynTypedNode to ASTNodeTraverser
>
> Reviewers: aaron.ballman
>
> Subscribers: cfe-commits
>
> Tags: #clang
>
> Differential Revision: https://reviews.llvm.org/D61834
>
> Added:
> cfe/trunk/unittests/AST/ASTTraverserTest.cpp
> Modified:
> cfe/trunk/include/clang/AST/ASTNodeTraverser.h
> cfe/trunk/unittests/AST/CMakeLists.txt
>
> Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff
>
> ==
> --- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)
> +++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28 2019
> @@ -205,6 +205,24 @@ public:
>  });
>}
>
> +  void Visit(const ast_type_traits::DynTypedNode &N) {
> +// FIXME: Improve this with a switch or a visitor pattern.
> +if (const auto *D = N.get())
> +  Visit(D);
> +else if (const auto *S = N.get())
> +  Visit(S);
> +else if (const auto *QT = N.get())
> +  Visit(*QT);
> +else if (const auto *T = N.get())
> +  Visit(T);
> +else if (const auto *C = N.get())
> +  Visit(C);
> +else if (const auto *C = N.get())
> +  Visit(C);
> +else if (const auto *T = N.get())
> +  Visit(*T);
> +  }
> +
>void dumpDeclContext(const DeclContext *DC) {
>  if (!DC)
>return;
>
> Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto
>
> ==
> --- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)
> +++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019
> @@ -0,0 +1,220 @@
> +//===-
> unittests/AST/ASTTraverserTest.h===//
> +//
> +// Part of the LLVM Project, under the Apache License v2.0 with LLVM
> Exceptions.
> +// See https://llvm.org/LICENSE.txt for license information.
> +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
> +//
>
> +//===--===//
> +
> +#include "clang/AST/ASTContext.h"
> +#include "clang/AST/ASTNodeTraverser.h"
> +#include "clang/AST/TextNodeDumper.h"
> +#include "clang/ASTMatchers/ASTMatchFinder.h"
> +#include "clang/ASTMatchers/ASTMatchers.h"
> +#include "clang/Tooling/Tooling.h"
> +#include "gmock/gmock.h"
> +#include "gtest/gtest.h"
> +
> +using namespace clang::tooling;
> +using namespace clang::ast_matchers;
> +
> +namespace clang {
> +
> +class NodeTreePrinter : public TextTreeStructure {
> +  llvm::raw_ostream &OS;
> +
> +public:
> +  NodeTreePrinter(llvm::raw_ostream &OS)
> +  : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}
> +
> +  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }
> +
> +  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }
> +
> +  void Visit(QualType QT) {
> +OS << "QualType " << QT.split().Quals.getAsString();
> +  }
> +
> +  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }
> +
> +  void Visit(const comments::Comment *C, const comments::FullComment *FC)
> {
> +OS << C->getCommentKindName();
> +  }
> +
> +  void Visit(const CXXCtorInitializer *Init) { OS <<
> "CXXCtorInitializer"; }
> +
> +  void Visit(const Attr *A) {
> +switch (A->getKind()) {
> +#define ATTR(X)
>   \
> +  case attr::X:
>   \
> +OS << #X;
>   \
> +break;
> +#include "clang/Basic/AttrList.inc"
> +}
> +OS << "Attr";
> +  }
> +
> +  void Visit(const OMPClause *C) { OS << "OMPClause"; }
> +  void Visit(const TemplateArgument &A, SourceRange R = {},
> + const Decl *From = nullptr, const char *Label = nullptr) {
> +OS << "TemplateArgument";
> +  }
> +
> +  template  void Visit(T...) {}
> +};
> +
> +class TestASTDumper : public ASTNodeTraverser NodeTreePrinter> {
> +
> +  NodeTreePrinter MyNodeRecorder;
> +
> +public:
> +  TestASTDumper(llvm::raw_ostream &OS) : MyNodeRecorder(OS) {}
> +  NodeTreePrinter &doGetNodeDelegate() { return MyNodeRecorder; }
> +};
> +
> +template  std::string dumpASTString(NodeType &&...
> N) {
> +  std::string Buffer;
> +  llvm::raw_string_ostream OS(Buffer);
> +
> +  TestASTDumper Dumper(OS);
> +
> +  OS << "\n";
> +
> +  Dumper.Visit(std::forward(N)...);
> +
> +  return OS.str();
> +}
> +
> +const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
> +