<div dir="auto">Hmm, thanks for letting me know!<div dir="auto"><br></div><div dir="auto">Is that an old compiler?</div><div dir="auto"><br></div><div dir="auto">I'm not near a computer for the weekend. </div><div dir="auto"><br></div><div dir="auto">Can someone fix or revert?</div><div dir="auto"><br></div><div dir="auto">Thanks,</div><div dir="auto"><br></div><div dir="auto">Stephen. </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri 17 May 2019, 17:11 Yitzhak Mandelbaum, <<a href="mailto:yitzhakm@google.com">yitzhakm@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">Looks like this caused a breakage: <a href="http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio" style="font-family:Arial,Helvetica,sans-serif" target="_blank" rel="noreferrer">http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/18641/steps/ninja%20check%201/logs/stdio</a></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, May 17, 2019 at 9:52 AM Stephen Kelly via cfe-commits <<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" rel="noreferrer">cfe-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: steveire<br>
Date: Fri May 17 06:55:28 2019<br>
New Revision: 361033<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=361033&view=rev" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=361033&view=rev</a><br>
Log:<br>
Add a Visit overload for DynTypedNode to ASTNodeTraverser<br>
<br>
Reviewers: aaron.ballman<br>
<br>
Subscribers: cfe-commits<br>
<br>
Tags: #clang<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D61834" rel="noreferrer noreferrer" target="_blank">https://reviews.llvm.org/D61834</a><br>
<br>
Added:<br>
    cfe/trunk/unittests/AST/ASTTraverserTest.cpp<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTNodeTraverser.h<br>
    cfe/trunk/unittests/AST/CMakeLists.txt<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTNodeTraverser.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTNodeTraverser.h?rev=361033&r1=361032&r2=361033&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTNodeTraverser.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTNodeTraverser.h Fri May 17 06:55:28 2019<br>
@@ -205,6 +205,24 @@ public:<br>
     });<br>
   }<br>
<br>
+  void Visit(const ast_type_traits::DynTypedNode &N) {<br>
+    // FIXME: Improve this with a switch or a visitor pattern.<br>
+    if (const auto *D = N.get<Decl>())<br>
+      Visit(D);<br>
+    else if (const auto *S = N.get<Stmt>())<br>
+      Visit(S);<br>
+    else if (const auto *QT = N.get<QualType>())<br>
+      Visit(*QT);<br>
+    else if (const auto *T = N.get<Type>())<br>
+      Visit(T);<br>
+    else if (const auto *C = N.get<CXXCtorInitializer>())<br>
+      Visit(C);<br>
+    else if (const auto *C = N.get<OMPClause>())<br>
+      Visit(C);<br>
+    else if (const auto *T = N.get<TemplateArgument>())<br>
+      Visit(*T);<br>
+  }<br>
+<br>
   void dumpDeclContext(const DeclContext *DC) {<br>
     if (!DC)<br>
       return;<br>
<br>
Added: cfe/trunk/unittests/AST/ASTTraverserTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTTraverserTest.cpp?rev=361033&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/AST/ASTTraverserTest.cpp (added)<br>
+++ cfe/trunk/unittests/AST/ASTTraverserTest.cpp Fri May 17 06:55:28 2019<br>
@@ -0,0 +1,220 @@<br>
+//===- unittests/AST/ASTTraverserTest.h------------------------------------===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "clang/AST/ASTContext.h"<br>
+#include "clang/AST/ASTNodeTraverser.h"<br>
+#include "clang/AST/TextNodeDumper.h"<br>
+#include "clang/ASTMatchers/ASTMatchFinder.h"<br>
+#include "clang/ASTMatchers/ASTMatchers.h"<br>
+#include "clang/Tooling/Tooling.h"<br>
+#include "gmock/gmock.h"<br>
+#include "gtest/gtest.h"<br>
+<br>
+using namespace clang::tooling;<br>
+using namespace clang::ast_matchers;<br>
+<br>
+namespace clang {<br>
+<br>
+class NodeTreePrinter : public TextTreeStructure {<br>
+  llvm::raw_ostream &OS;<br>
+<br>
+public:<br>
+  NodeTreePrinter(llvm::raw_ostream &OS)<br>
+      : TextTreeStructure(OS, /* showColors */ false), OS(OS) {}<br>
+<br>
+  void Visit(const Decl *D) { OS << D->getDeclKindName() << "Decl"; }<br>
+<br>
+  void Visit(const Stmt *S) { OS << S->getStmtClassName(); }<br>
+<br>
+  void Visit(QualType QT) {<br>
+    OS << "QualType " << QT.split().Quals.getAsString();<br>
+  }<br>
+<br>
+  void Visit(const Type *T) { OS << T->getTypeClassName() << "Type"; }<br>
+<br>
+  void Visit(const comments::Comment *C, const comments::FullComment *FC) {<br>
+    OS << C->getCommentKindName();<br>
+  }<br>
+<br>
+  void Visit(const CXXCtorInitializer *Init) { OS << "CXXCtorInitializer"; }<br>
+<br>
+  void Visit(const Attr *A) {<br>
+    switch (A->getKind()) {<br>
+#define ATTR(X)                                                                \<br>
+  case attr::X:                                                                \<br>
+    OS << #X;                                                                  \<br>
+    break;<br>
+#include "clang/Basic/AttrList.inc"<br>
+    }<br>
+    OS << "Attr";<br>
+  }<br>
+<br>
+  void Visit(const OMPClause *C) { OS << "OMPClause"; }<br>
+  void Visit(const TemplateArgument &A, SourceRange R = {},<br>
+             const Decl *From = nullptr, const char *Label = nullptr) {<br>
+    OS << "TemplateArgument";<br>
+  }<br>
+<br>
+  template <typename... T> void Visit(T...) {}<br>
+};<br>
+<br>
+class TestASTDumper : public ASTNodeTraverser<TestASTDumper, NodeTreePrinter> {<br>
+<br>
+  NodeTreePrinter MyNodeRecorder;<br>
+<br>
+public:<br>
+  TestASTDumper(llvm::raw_ostream &OS) : MyNodeRecorder(OS) {}<br>
+  NodeTreePrinter &doGetNodeDelegate() { return MyNodeRecorder; }<br>
+};<br>
+<br>
+template <typename... NodeType> std::string dumpASTString(NodeType &&... N) {<br>
+  std::string Buffer;<br>
+  llvm::raw_string_ostream OS(Buffer);<br>
+<br>
+  TestASTDumper Dumper(OS);<br>
+<br>
+  OS << "\n";<br>
+<br>
+  Dumper.Visit(std::forward<NodeType &&>(N)...);<br>
+<br>
+  return OS.str();<br>
+}<br>
+<br>
+const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,<br>
+                                    const std::string &Name) {<br>
+  auto Result = ast_matchers::match(functionDecl(hasName(Name)).bind("fn"),<br>
+                                    AST->getASTContext());<br>
+  EXPECT_EQ(Result.size(), 1u);<br>
+  return Result[0].getNodeAs<FunctionDecl>("fn");<br>
+}<br>
+<br>
+template <typename T> struct Verifier {<br>
+  static void withDynNode(T Node, const std::string &DumpString) {<br>
+    EXPECT_EQ(dumpASTString(ast_type_traits::DynTypedNode::create(Node)),<br>
+              DumpString);<br>
+  }<br>
+};<br>
+<br>
+template <typename T> struct Verifier<T *> {<br>
+  static void withDynNode(T *Node, const std::string &DumpString) {<br>
+    EXPECT_EQ(dumpASTString(ast_type_traits::DynTypedNode::create(*Node)),<br>
+              DumpString);<br>
+  }<br>
+};<br>
+<br>
+template <typename T><br>
+void verifyWithDynNode(T Node, const std::string &DumpString) {<br>
+  EXPECT_EQ(dumpASTString(Node), DumpString);<br>
+<br>
+  Verifier<T>::withDynNode(Node, DumpString);<br>
+}<br>
+<br>
+TEST(Traverse, Dump) {<br>
+<br>
+  auto AST = buildASTFromCode(R"cpp(<br>
+struct A {<br>
+  int m_number;<br>
+<br>
+  /// CTor<br>
+  A() : m_number(42) {}<br>
+<br>
+  [[nodiscard]] const int func() {<br>
+    return 42;<br>
+  }<br>
+<br>
+};<br>
+<br>
+template<typename T><br>
+struct templ<br>
+{ <br>
+};<br>
+<br>
+template<><br>
+struct templ<int><br>
+{ <br>
+};<br>
+<br>
+)cpp");<br>
+<br>
+  const FunctionDecl *Func = getFunctionNode(AST.get(), "func");<br>
+<br>
+  verifyWithDynNode(Func,<br>
+                    R"cpp(<br>
+CXXMethodDecl<br>
+|-CompoundStmt<br>
+| `-ReturnStmt<br>
+|   `-IntegerLiteral<br>
+`-WarnUnusedResultAttr<br>
+)cpp");<br>
+<br>
+  Stmt *Body = Func->getBody();<br>
+<br>
+  verifyWithDynNode(Body,<br>
+                    R"cpp(<br>
+CompoundStmt<br>
+`-ReturnStmt<br>
+  `-IntegerLiteral<br>
+)cpp");<br>
+<br>
+  QualType QT = Func->getType();<br>
+<br>
+  verifyWithDynNode(QT,<br>
+                    R"cpp(<br>
+FunctionProtoType<br>
+`-QualType const<br>
+  `-BuiltinType<br>
+)cpp");<br>
+<br>
+  const FunctionDecl *CTorFunc = getFunctionNode(AST.get(), "A");<br>
+<br>
+  verifyWithDynNode(CTorFunc->getType(),<br>
+                    R"cpp(<br>
+FunctionProtoType<br>
+`-BuiltinType<br>
+)cpp");<br>
+<br>
+  Attr *A = *Func->attr_begin();<br>
+<br>
+  EXPECT_EQ(dumpASTString(A),<br>
+            R"cpp(<br>
+WarnUnusedResultAttr<br>
+)cpp");<br>
+<br>
+  auto *CTor = dyn_cast<CXXConstructorDecl>(CTorFunc);<br>
+  const CXXCtorInitializer *Init = *CTor->init_begin();<br>
+<br>
+  verifyWithDynNode(Init,<br>
+                    R"cpp(<br>
+CXXCtorInitializer<br>
+`-IntegerLiteral<br>
+)cpp");<br>
+<br>
+  const comments::FullComment *Comment =<br>
+      AST->getASTContext().getLocalCommentForDeclUncached(CTorFunc);<br>
+<br>
+  EXPECT_EQ(dumpASTString(Comment, Comment),<br>
+            R"cpp(<br>
+FullComment<br>
+`-ParagraphComment<br>
+  `-TextComment<br>
+)cpp");<br>
+<br>
+  auto Result = ast_matchers::match(<br>
+      classTemplateSpecializationDecl(hasName("templ")).bind("fn"),<br>
+      AST->getASTContext());<br>
+  EXPECT_EQ(Result.size(), 1u);<br>
+  auto Templ = Result[0].getNodeAs<ClassTemplateSpecializationDecl>("fn");<br>
+<br>
+  TemplateArgument TA = Templ->getTemplateArgs()[0];<br>
+<br>
+  verifyWithDynNode(TA,<br>
+                    R"cpp(<br>
+TemplateArgument<br>
+)cpp");<br>
+}<br>
+} // namespace clang<br>
<br>
Modified: cfe/trunk/unittests/AST/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CMakeLists.txt?rev=361033&r1=361032&r2=361033&view=diff" rel="noreferrer noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CMakeLists.txt?rev=361033&r1=361032&r2=361033&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/unittests/AST/CMakeLists.txt (original)<br>
+++ cfe/trunk/unittests/AST/CMakeLists.txt Fri May 17 06:55:28 2019<br>
@@ -12,6 +12,7 @@ add_clang_unittest(ASTTests<br>
   ASTImporterTest.cpp<br>
   ASTImporterGenericRedeclTest.cpp<br>
   ASTImporterVisibilityTest.cpp<br>
+  ASTTraverserTest.cpp<br>
   ASTTypeTraitsTest.cpp<br>
   ASTVectorTest.cpp<br>
   CommentLexer.cpp<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org" target="_blank" rel="noreferrer">cfe-commits@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>
</blockquote></div>