Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/AST/JSONNodeDumper.h
Line
Count
Source (jump to first uncovered line)
1
//===--- JSONNodeDumper.h - Printing of AST nodes to JSON -----------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file implements AST dumping of components of individual AST nodes to
11
// a JSON.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#ifndef LLVM_CLANG_AST_JSONNODEDUMPER_H
16
#define LLVM_CLANG_AST_JSONNODEDUMPER_H
17
18
#include "clang/AST/ASTContext.h"
19
#include "clang/AST/ASTDumperUtils.h"
20
#include "clang/AST/ASTNodeTraverser.h"
21
#include "clang/AST/AttrVisitor.h"
22
#include "clang/AST/CommentCommandTraits.h"
23
#include "clang/AST/CommentVisitor.h"
24
#include "clang/AST/ExprCXX.h"
25
#include "clang/AST/Mangle.h"
26
#include "llvm/Support/JSON.h"
27
28
namespace clang {
29
30
class NodeStreamer {
31
  bool FirstChild = true;
32
  bool TopLevel = true;
33
  llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
34
35
protected:
36
  llvm::json::OStream JOS;
37
38
public:
39
  /// Add a child of the current node.  Calls DoAddChild without arguments
40
1.33k
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
1.33k
    return AddChild("", DoAddChild);
42
1.33k
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Decl const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Decl const*)::'lambda'())
Line
Count
Source
40
1.03k
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
1.03k
    return AddChild("", DoAddChild);
42
1.03k
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::BlockDecl::Capture const&)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::BlockDecl::Capture const&)::'lambda'())
Line
Count
Source
40
3
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
3
    return AddChild("", DoAddChild);
42
3
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::OMPClause const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::OMPClause const*)::'lambda'())
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Type const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Type const*)::'lambda'())
Line
Count
Source
40
194
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
194
    return AddChild("", DoAddChild);
42
194
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::TemplateArgument const&, clang::SourceRange, clang::Decl const*, char const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::TemplateArgument const&, clang::SourceRange, clang::Decl const*, char const*)::'lambda'())
Line
Count
Source
40
7
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
7
    return AddChild("", DoAddChild);
42
7
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::QualType)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::QualType)::'lambda'())
Line
Count
Source
40
1
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
1
    return AddChild("", DoAddChild);
42
1
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::GenericSelectionExpr::AssociationTy<true> const&)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::GenericSelectionExpr::AssociationTy<true> const&)::'lambda'())
Line
Count
Source
40
12
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
12
    return AddChild("", DoAddChild);
42
12
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::CXXCtorInitializer const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::CXXCtorInitializer const*)::'lambda'())
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda'()>(clang::ClassTemplateSpecializationDecl)
void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda0'()>(clang::ClassTemplateSpecializationDecl)
Line
Count
Source
40
1
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
1
    return AddChild("", DoAddChild);
42
1
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda'()>(clang::FunctionDecl)
void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda0'()>(clang::FunctionDecl)
Line
Count
Source
40
1
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
1
    return AddChild("", DoAddChild);
42
1
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda'()>(clang::VarTemplateSpecializationDecl)
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda0'()>(clang::VarTemplateSpecializationDecl)
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Attr const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Attr const*)::'lambda'())
Line
Count
Source
40
13
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
13
    return AddChild("", DoAddChild);
42
13
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::comments::Comment const*, clang::comments::FullComment const*)::'lambda'()>(clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::comments::Comment const*, clang::comments::FullComment const*)::'lambda'())
Line
Count
Source
40
64
  template <typename Fn> void AddChild(Fn DoAddChild) {
41
64
    return AddChild("", DoAddChild);
42
64
  }
43
44
  /// Add a child of the current node with an optional label.
45
  /// Calls DoAddChild without arguments.
46
2.81k
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
2.81k
    // If we're at the top level, there's nothing interesting to do; just
48
2.81k
    // run the dumper.
49
2.81k
    if (TopLevel) {
50
122
      TopLevel = false;
51
122
      JOS.objectBegin();
52
122
53
122
      DoAddChild();
54
122
55
210
      while (!Pending.empty()) {
56
88
        Pending.back()(true);
57
88
        Pending.pop_back();
58
88
      }
59
122
60
122
      JOS.objectEnd();
61
122
      TopLevel = true;
62
122
      return;
63
122
    }
64
2.69k
65
2.69k
    // We need to capture an owning-string in the lambda because the lambda
66
2.69k
    // is invoked in a deferred manner.
67
2.69k
    std::string LabelStr(!Label.empty() ? 
Label1
:
"inner"2.69k
);
68
2.69k
    bool WasFirstChild = FirstChild;
69
2.69k
    auto DumpWithIndent = [=](bool IsLastChild) {
70
2.69k
      if (WasFirstChild) {
71
1.58k
        JOS.attributeBegin(LabelStr);
72
1.58k
        JOS.arrayBegin();
73
1.58k
      }
74
2.69k
75
2.69k
      FirstChild = true;
76
2.69k
      unsigned Depth = Pending.size();
77
2.69k
      JOS.objectBegin();
78
2.69k
79
2.69k
      DoAddChild();
80
2.69k
81
2.69k
      // If any children are left, they're the last at their nesting level.
82
2.69k
      // Dump those ones out now.
83
4.18k
      while (Depth < Pending.size()) {
84
1.49k
        Pending.back()(true);
85
1.49k
        this->Pending.pop_back();
86
1.49k
      }
87
2.69k
88
2.69k
      JOS.objectEnd();
89
2.69k
90
2.69k
      if (IsLastChild) {
91
1.58k
        JOS.arrayEnd();
92
1.58k
        JOS.attributeEnd();
93
1.58k
      }
94
2.69k
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::BlockDecl::Capture const&)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::BlockDecl::Capture const&)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
3
    auto DumpWithIndent = [=](bool IsLastChild) {
70
3
      if (WasFirstChild) {
71
2
        JOS.attributeBegin(LabelStr);
72
2
        JOS.arrayBegin();
73
2
      }
74
3
75
3
      FirstChild = true;
76
3
      unsigned Depth = Pending.size();
77
3
      JOS.objectBegin();
78
3
79
3
      DoAddChild();
80
3
81
3
      // If any children are left, they're the last at their nesting level.
82
3
      // Dump those ones out now.
83
3
      while (Depth < Pending.size()) {
84
0
        Pending.back()(true);
85
0
        this->Pending.pop_back();
86
0
      }
87
3
88
3
      JOS.objectEnd();
89
3
90
3
      if (IsLastChild) {
91
0
        JOS.arrayEnd();
92
0
        JOS.attributeEnd();
93
0
      }
94
3
    };
Unexecuted instantiation: void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::OMPClause const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::OMPClause const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::TemplateArgument const&, clang::SourceRange, clang::Decl const*, char const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::TemplateArgument const&, clang::SourceRange, clang::Decl const*, char const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
7
    auto DumpWithIndent = [=](bool IsLastChild) {
70
7
      if (WasFirstChild) {
71
5
        JOS.attributeBegin(LabelStr);
72
5
        JOS.arrayBegin();
73
5
      }
74
7
75
7
      FirstChild = true;
76
7
      unsigned Depth = Pending.size();
77
7
      JOS.objectBegin();
78
7
79
7
      DoAddChild();
80
7
81
7
      // If any children are left, they're the last at their nesting level.
82
7
      // Dump those ones out now.
83
7
      while (Depth < Pending.size()) {
84
0
        Pending.back()(true);
85
0
        this->Pending.pop_back();
86
0
      }
87
7
88
7
      JOS.objectEnd();
89
7
90
7
      if (IsLastChild) {
91
2
        JOS.arrayEnd();
92
2
        JOS.attributeEnd();
93
2
      }
94
7
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Type const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Type const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
194
    auto DumpWithIndent = [=](bool IsLastChild) {
70
194
      if (WasFirstChild) {
71
183
        JOS.attributeBegin(LabelStr);
72
183
        JOS.arrayBegin();
73
183
      }
74
194
75
194
      FirstChild = true;
76
194
      unsigned Depth = Pending.size();
77
194
      JOS.objectBegin();
78
194
79
194
      DoAddChild();
80
194
81
194
      // If any children are left, they're the last at their nesting level.
82
194
      // Dump those ones out now.
83
251
      while (Depth < Pending.size()) {
84
57
        Pending.back()(true);
85
57
        this->Pending.pop_back();
86
57
      }
87
194
88
194
      JOS.objectEnd();
89
194
90
194
      if (IsLastChild) {
91
176
        JOS.arrayEnd();
92
176
        JOS.attributeEnd();
93
176
      }
94
194
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::QualType)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::QualType)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
1
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1
      if (WasFirstChild) {
71
1
        JOS.attributeBegin(LabelStr);
72
1
        JOS.arrayBegin();
73
1
      }
74
1
75
1
      FirstChild = true;
76
1
      unsigned Depth = Pending.size();
77
1
      JOS.objectBegin();
78
1
79
1
      DoAddChild();
80
1
81
1
      // If any children are left, they're the last at their nesting level.
82
1
      // Dump those ones out now.
83
2
      while (Depth < Pending.size()) {
84
1
        Pending.back()(true);
85
1
        this->Pending.pop_back();
86
1
      }
87
1
88
1
      JOS.objectEnd();
89
1
90
1
      if (IsLastChild) {
91
1
        JOS.arrayEnd();
92
1
        JOS.attributeEnd();
93
1
      }
94
1
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::GenericSelectionExpr::AssociationTy<true> const&)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::GenericSelectionExpr::AssociationTy<true> const&)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
12
    auto DumpWithIndent = [=](bool IsLastChild) {
70
12
      if (WasFirstChild) {
71
0
        JOS.attributeBegin(LabelStr);
72
0
        JOS.arrayBegin();
73
0
      }
74
12
75
12
      FirstChild = true;
76
12
      unsigned Depth = Pending.size();
77
12
      JOS.objectBegin();
78
12
79
12
      DoAddChild();
80
12
81
12
      // If any children are left, they're the last at their nesting level.
82
12
      // Dump those ones out now.
83
24
      while (Depth < Pending.size()) {
84
12
        Pending.back()(true);
85
12
        this->Pending.pop_back();
86
12
      }
87
12
88
12
      JOS.objectEnd();
89
12
90
12
      if (IsLastChild) {
91
7
        JOS.arrayEnd();
92
7
        JOS.attributeEnd();
93
7
      }
94
12
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Stmt const*, llvm::StringRef)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Stmt const*, llvm::StringRef)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
1.48k
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1.48k
      if (WasFirstChild) {
71
971
        JOS.attributeBegin(LabelStr);
72
971
        JOS.arrayBegin();
73
971
      }
74
1.48k
75
1.48k
      FirstChild = true;
76
1.48k
      unsigned Depth = Pending.size();
77
1.48k
      JOS.objectBegin();
78
1.48k
79
1.48k
      DoAddChild();
80
1.48k
81
1.48k
      // If any children are left, they're the last at their nesting level.
82
1.48k
      // Dump those ones out now.
83
2.40k
      while (Depth < Pending.size()) {
84
920
        Pending.back()(true);
85
920
        this->Pending.pop_back();
86
920
      }
87
1.48k
88
1.48k
      JOS.objectEnd();
89
1.48k
90
1.48k
      if (IsLastChild) {
91
1.05k
        JOS.arrayEnd();
92
1.05k
        JOS.attributeEnd();
93
1.05k
      }
94
1.48k
    };
Unexecuted instantiation: void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::CXXCtorInitializer const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::CXXCtorInitializer const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda'()>(llvm::StringRef, clang::ClassTemplateSpecializationDecl)::'lambda'(bool)::operator()(bool) const
void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda0'()>(llvm::StringRef, clang::ClassTemplateSpecializationDecl)::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
1
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1
      if (WasFirstChild) {
71
0
        JOS.attributeBegin(LabelStr);
72
0
        JOS.arrayBegin();
73
0
      }
74
1
75
1
      FirstChild = true;
76
1
      unsigned Depth = Pending.size();
77
1
      JOS.objectBegin();
78
1
79
1
      DoAddChild();
80
1
81
1
      // If any children are left, they're the last at their nesting level.
82
1
      // Dump those ones out now.
83
1
      while (Depth < Pending.size()) {
84
0
        Pending.back()(true);
85
0
        this->Pending.pop_back();
86
0
      }
87
1
88
1
      JOS.objectEnd();
89
1
90
1
      if (IsLastChild) {
91
1
        JOS.arrayEnd();
92
1
        JOS.attributeEnd();
93
1
      }
94
1
    };
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda'()>(llvm::StringRef, clang::FunctionDecl)::'lambda'(bool)::operator()(bool) const
void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda0'()>(llvm::StringRef, clang::FunctionDecl)::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
1
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1
      if (WasFirstChild) {
71
0
        JOS.attributeBegin(LabelStr);
72
0
        JOS.arrayBegin();
73
0
      }
74
1
75
1
      FirstChild = true;
76
1
      unsigned Depth = Pending.size();
77
1
      JOS.objectBegin();
78
1
79
1
      DoAddChild();
80
1
81
1
      // If any children are left, they're the last at their nesting level.
82
1
      // Dump those ones out now.
83
1
      while (Depth < Pending.size()) {
84
0
        Pending.back()(true);
85
0
        this->Pending.pop_back();
86
0
      }
87
1
88
1
      JOS.objectEnd();
89
1
90
1
      if (IsLastChild) {
91
1
        JOS.arrayEnd();
92
1
        JOS.attributeEnd();
93
1
      }
94
1
    };
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda'()>(llvm::StringRef, clang::VarTemplateSpecializationDecl)::'lambda'(bool)::operator()(bool) const
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda0'()>(llvm::StringRef, clang::VarTemplateSpecializationDecl)::'lambda'(bool)::operator()(bool) const
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Attr const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Attr const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
13
    auto DumpWithIndent = [=](bool IsLastChild) {
70
13
      if (WasFirstChild) {
71
0
        JOS.attributeBegin(LabelStr);
72
0
        JOS.arrayBegin();
73
0
      }
74
13
75
13
      FirstChild = true;
76
13
      unsigned Depth = Pending.size();
77
13
      JOS.objectBegin();
78
13
79
13
      DoAddChild();
80
13
81
13
      // If any children are left, they're the last at their nesting level.
82
13
      // Dump those ones out now.
83
13
      while (Depth < Pending.size()) {
84
0
        Pending.back()(true);
85
0
        this->Pending.pop_back();
86
0
      }
87
13
88
13
      JOS.objectEnd();
89
13
90
13
      if (IsLastChild) {
91
13
        JOS.arrayEnd();
92
13
        JOS.attributeEnd();
93
13
      }
94
13
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::comments::Comment const*, clang::comments::FullComment const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::comments::Comment const*, clang::comments::FullComment const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
64
    auto DumpWithIndent = [=](bool IsLastChild) {
70
64
      if (WasFirstChild) {
71
45
        JOS.attributeBegin(LabelStr);
72
45
        JOS.arrayBegin();
73
45
      }
74
64
75
64
      FirstChild = true;
76
64
      unsigned Depth = Pending.size();
77
64
      JOS.objectBegin();
78
64
79
64
      DoAddChild();
80
64
81
64
      // If any children are left, they're the last at their nesting level.
82
64
      // Dump those ones out now.
83
101
      while (Depth < Pending.size()) {
84
37
        Pending.back()(true);
85
37
        this->Pending.pop_back();
86
37
      }
87
64
88
64
      JOS.objectEnd();
89
64
90
64
      if (IsLastChild) {
91
49
        JOS.arrayEnd();
92
49
        JOS.attributeEnd();
93
49
      }
94
64
    };
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Decl const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Decl const*)::'lambda'())::'lambda'(bool)::operator()(bool) const
Line
Count
Source
69
917
    auto DumpWithIndent = [=](bool IsLastChild) {
70
917
      if (WasFirstChild) {
71
374
        JOS.attributeBegin(LabelStr);
72
374
        JOS.arrayBegin();
73
374
      }
74
917
75
917
      FirstChild = true;
76
917
      unsigned Depth = Pending.size();
77
917
      JOS.objectBegin();
78
917
79
917
      DoAddChild();
80
917
81
917
      // If any children are left, they're the last at their nesting level.
82
917
      // Dump those ones out now.
83
1.38k
      while (Depth < Pending.size()) {
84
466
        Pending.back()(true);
85
466
        this->Pending.pop_back();
86
466
      }
87
917
88
917
      JOS.objectEnd();
89
917
90
917
      if (IsLastChild) {
91
274
        JOS.arrayEnd();
92
274
        JOS.attributeEnd();
93
274
      }
94
917
    };
95
2.69k
96
2.69k
    if (FirstChild) {
97
1.58k
      Pending.push_back(std::move(DumpWithIndent));
98
1.58k
    } else {
99
1.11k
      Pending.back()(false);
100
1.11k
      Pending.back() = std::move(DumpWithIndent);
101
1.11k
    }
102
2.69k
    FirstChild = false;
103
2.69k
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Decl const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Decl const*)::'lambda'())
Line
Count
Source
46
1.03k
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
1.03k
    // If we're at the top level, there's nothing interesting to do; just
48
1.03k
    // run the dumper.
49
1.03k
    if (TopLevel) {
50
122
      TopLevel = false;
51
122
      JOS.objectBegin();
52
122
53
122
      DoAddChild();
54
122
55
210
      while (!Pending.empty()) {
56
88
        Pending.back()(true);
57
88
        Pending.pop_back();
58
88
      }
59
122
60
122
      JOS.objectEnd();
61
122
      TopLevel = true;
62
122
      return;
63
122
    }
64
917
65
917
    // We need to capture an owning-string in the lambda because the lambda
66
917
    // is invoked in a deferred manner.
67
917
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
917
    bool WasFirstChild = FirstChild;
69
917
    auto DumpWithIndent = [=](bool IsLastChild) {
70
917
      if (WasFirstChild) {
71
917
        JOS.attributeBegin(LabelStr);
72
917
        JOS.arrayBegin();
73
917
      }
74
917
75
917
      FirstChild = true;
76
917
      unsigned Depth = Pending.size();
77
917
      JOS.objectBegin();
78
917
79
917
      DoAddChild();
80
917
81
917
      // If any children are left, they're the last at their nesting level.
82
917
      // Dump those ones out now.
83
917
      while (Depth < Pending.size()) {
84
917
        Pending.back()(true);
85
917
        this->Pending.pop_back();
86
917
      }
87
917
88
917
      JOS.objectEnd();
89
917
90
917
      if (IsLastChild) {
91
917
        JOS.arrayEnd();
92
917
        JOS.attributeEnd();
93
917
      }
94
917
    };
95
917
96
917
    if (FirstChild) {
97
374
      Pending.push_back(std::move(DumpWithIndent));
98
543
    } else {
99
543
      Pending.back()(false);
100
543
      Pending.back() = std::move(DumpWithIndent);
101
543
    }
102
917
    FirstChild = false;
103
917
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::BlockDecl::Capture const&)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::BlockDecl::Capture const&)::'lambda'())
Line
Count
Source
46
3
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
3
    // If we're at the top level, there's nothing interesting to do; just
48
3
    // run the dumper.
49
3
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
3
65
3
    // We need to capture an owning-string in the lambda because the lambda
66
3
    // is invoked in a deferred manner.
67
3
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
3
    bool WasFirstChild = FirstChild;
69
3
    auto DumpWithIndent = [=](bool IsLastChild) {
70
3
      if (WasFirstChild) {
71
3
        JOS.attributeBegin(LabelStr);
72
3
        JOS.arrayBegin();
73
3
      }
74
3
75
3
      FirstChild = true;
76
3
      unsigned Depth = Pending.size();
77
3
      JOS.objectBegin();
78
3
79
3
      DoAddChild();
80
3
81
3
      // If any children are left, they're the last at their nesting level.
82
3
      // Dump those ones out now.
83
3
      while (Depth < Pending.size()) {
84
3
        Pending.back()(true);
85
3
        this->Pending.pop_back();
86
3
      }
87
3
88
3
      JOS.objectEnd();
89
3
90
3
      if (IsLastChild) {
91
3
        JOS.arrayEnd();
92
3
        JOS.attributeEnd();
93
3
      }
94
3
    };
95
3
96
3
    if (FirstChild) {
97
2
      Pending.push_back(std::move(DumpWithIndent));
98
2
    } else {
99
1
      Pending.back()(false);
100
1
      Pending.back() = std::move(DumpWithIndent);
101
1
    }
102
3
    FirstChild = false;
103
3
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Stmt const*, llvm::StringRef)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Stmt const*, llvm::StringRef)::'lambda'())
Line
Count
Source
46
1.48k
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
1.48k
    // If we're at the top level, there's nothing interesting to do; just
48
1.48k
    // run the dumper.
49
1.48k
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
1.48k
65
1.48k
    // We need to capture an owning-string in the lambda because the lambda
66
1.48k
    // is invoked in a deferred manner.
67
1.48k
    std::string LabelStr(!Label.empty() ? 
Label1
:
"inner"1.48k
);
68
1.48k
    bool WasFirstChild = FirstChild;
69
1.48k
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1.48k
      if (WasFirstChild) {
71
1.48k
        JOS.attributeBegin(LabelStr);
72
1.48k
        JOS.arrayBegin();
73
1.48k
      }
74
1.48k
75
1.48k
      FirstChild = true;
76
1.48k
      unsigned Depth = Pending.size();
77
1.48k
      JOS.objectBegin();
78
1.48k
79
1.48k
      DoAddChild();
80
1.48k
81
1.48k
      // If any children are left, they're the last at their nesting level.
82
1.48k
      // Dump those ones out now.
83
1.48k
      while (Depth < Pending.size()) {
84
1.48k
        Pending.back()(true);
85
1.48k
        this->Pending.pop_back();
86
1.48k
      }
87
1.48k
88
1.48k
      JOS.objectEnd();
89
1.48k
90
1.48k
      if (IsLastChild) {
91
1.48k
        JOS.arrayEnd();
92
1.48k
        JOS.attributeEnd();
93
1.48k
      }
94
1.48k
    };
95
1.48k
96
1.48k
    if (FirstChild) {
97
971
      Pending.push_back(std::move(DumpWithIndent));
98
971
    } else {
99
511
      Pending.back()(false);
100
511
      Pending.back() = std::move(DumpWithIndent);
101
511
    }
102
1.48k
    FirstChild = false;
103
1.48k
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::OMPClause const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::OMPClause const*)::'lambda'())
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Type const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Type const*)::'lambda'())
Line
Count
Source
46
194
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
194
    // If we're at the top level, there's nothing interesting to do; just
48
194
    // run the dumper.
49
194
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
194
65
194
    // We need to capture an owning-string in the lambda because the lambda
66
194
    // is invoked in a deferred manner.
67
194
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
194
    bool WasFirstChild = FirstChild;
69
194
    auto DumpWithIndent = [=](bool IsLastChild) {
70
194
      if (WasFirstChild) {
71
194
        JOS.attributeBegin(LabelStr);
72
194
        JOS.arrayBegin();
73
194
      }
74
194
75
194
      FirstChild = true;
76
194
      unsigned Depth = Pending.size();
77
194
      JOS.objectBegin();
78
194
79
194
      DoAddChild();
80
194
81
194
      // If any children are left, they're the last at their nesting level.
82
194
      // Dump those ones out now.
83
194
      while (Depth < Pending.size()) {
84
194
        Pending.back()(true);
85
194
        this->Pending.pop_back();
86
194
      }
87
194
88
194
      JOS.objectEnd();
89
194
90
194
      if (IsLastChild) {
91
194
        JOS.arrayEnd();
92
194
        JOS.attributeEnd();
93
194
      }
94
194
    };
95
194
96
194
    if (FirstChild) {
97
183
      Pending.push_back(std::move(DumpWithIndent));
98
183
    } else {
99
11
      Pending.back()(false);
100
11
      Pending.back() = std::move(DumpWithIndent);
101
11
    }
102
194
    FirstChild = false;
103
194
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::TemplateArgument const&, clang::SourceRange, clang::Decl const*, char const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::TemplateArgument const&, clang::SourceRange, clang::Decl const*, char const*)::'lambda'())
Line
Count
Source
46
7
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
7
    // If we're at the top level, there's nothing interesting to do; just
48
7
    // run the dumper.
49
7
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
7
65
7
    // We need to capture an owning-string in the lambda because the lambda
66
7
    // is invoked in a deferred manner.
67
7
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
7
    bool WasFirstChild = FirstChild;
69
7
    auto DumpWithIndent = [=](bool IsLastChild) {
70
7
      if (WasFirstChild) {
71
7
        JOS.attributeBegin(LabelStr);
72
7
        JOS.arrayBegin();
73
7
      }
74
7
75
7
      FirstChild = true;
76
7
      unsigned Depth = Pending.size();
77
7
      JOS.objectBegin();
78
7
79
7
      DoAddChild();
80
7
81
7
      // If any children are left, they're the last at their nesting level.
82
7
      // Dump those ones out now.
83
7
      while (Depth < Pending.size()) {
84
7
        Pending.back()(true);
85
7
        this->Pending.pop_back();
86
7
      }
87
7
88
7
      JOS.objectEnd();
89
7
90
7
      if (IsLastChild) {
91
7
        JOS.arrayEnd();
92
7
        JOS.attributeEnd();
93
7
      }
94
7
    };
95
7
96
7
    if (FirstChild) {
97
5
      Pending.push_back(std::move(DumpWithIndent));
98
5
    } else {
99
2
      Pending.back()(false);
100
2
      Pending.back() = std::move(DumpWithIndent);
101
2
    }
102
7
    FirstChild = false;
103
7
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::QualType)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::QualType)::'lambda'())
Line
Count
Source
46
1
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
1
    // If we're at the top level, there's nothing interesting to do; just
48
1
    // run the dumper.
49
1
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
1
65
1
    // We need to capture an owning-string in the lambda because the lambda
66
1
    // is invoked in a deferred manner.
67
1
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
1
    bool WasFirstChild = FirstChild;
69
1
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1
      if (WasFirstChild) {
71
1
        JOS.attributeBegin(LabelStr);
72
1
        JOS.arrayBegin();
73
1
      }
74
1
75
1
      FirstChild = true;
76
1
      unsigned Depth = Pending.size();
77
1
      JOS.objectBegin();
78
1
79
1
      DoAddChild();
80
1
81
1
      // If any children are left, they're the last at their nesting level.
82
1
      // Dump those ones out now.
83
1
      while (Depth < Pending.size()) {
84
1
        Pending.back()(true);
85
1
        this->Pending.pop_back();
86
1
      }
87
1
88
1
      JOS.objectEnd();
89
1
90
1
      if (IsLastChild) {
91
1
        JOS.arrayEnd();
92
1
        JOS.attributeEnd();
93
1
      }
94
1
    };
95
1
96
1
    if (FirstChild) {
97
1
      Pending.push_back(std::move(DumpWithIndent));
98
1
    } else {
99
0
      Pending.back()(false);
100
0
      Pending.back() = std::move(DumpWithIndent);
101
0
    }
102
1
    FirstChild = false;
103
1
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::GenericSelectionExpr::AssociationTy<true> const&)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::GenericSelectionExpr::AssociationTy<true> const&)::'lambda'())
Line
Count
Source
46
12
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
12
    // If we're at the top level, there's nothing interesting to do; just
48
12
    // run the dumper.
49
12
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
12
65
12
    // We need to capture an owning-string in the lambda because the lambda
66
12
    // is invoked in a deferred manner.
67
12
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
12
    bool WasFirstChild = FirstChild;
69
12
    auto DumpWithIndent = [=](bool IsLastChild) {
70
12
      if (WasFirstChild) {
71
12
        JOS.attributeBegin(LabelStr);
72
12
        JOS.arrayBegin();
73
12
      }
74
12
75
12
      FirstChild = true;
76
12
      unsigned Depth = Pending.size();
77
12
      JOS.objectBegin();
78
12
79
12
      DoAddChild();
80
12
81
12
      // If any children are left, they're the last at their nesting level.
82
12
      // Dump those ones out now.
83
12
      while (Depth < Pending.size()) {
84
12
        Pending.back()(true);
85
12
        this->Pending.pop_back();
86
12
      }
87
12
88
12
      JOS.objectEnd();
89
12
90
12
      if (IsLastChild) {
91
12
        JOS.arrayEnd();
92
12
        JOS.attributeEnd();
93
12
      }
94
12
    };
95
12
96
12
    if (FirstChild) {
97
0
      Pending.push_back(std::move(DumpWithIndent));
98
12
    } else {
99
12
      Pending.back()(false);
100
12
      Pending.back() = std::move(DumpWithIndent);
101
12
    }
102
12
    FirstChild = false;
103
12
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::CXXCtorInitializer const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::CXXCtorInitializer const*)::'lambda'())
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda'()>(llvm::StringRef, clang::ClassTemplateSpecializationDecl)
void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda0'()>(llvm::StringRef, clang::ClassTemplateSpecializationDecl)
Line
Count
Source
46
1
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
1
    // If we're at the top level, there's nothing interesting to do; just
48
1
    // run the dumper.
49
1
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
1
65
1
    // We need to capture an owning-string in the lambda because the lambda
66
1
    // is invoked in a deferred manner.
67
1
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
1
    bool WasFirstChild = FirstChild;
69
1
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1
      if (WasFirstChild) {
71
1
        JOS.attributeBegin(LabelStr);
72
1
        JOS.arrayBegin();
73
1
      }
74
1
75
1
      FirstChild = true;
76
1
      unsigned Depth = Pending.size();
77
1
      JOS.objectBegin();
78
1
79
1
      DoAddChild();
80
1
81
1
      // If any children are left, they're the last at their nesting level.
82
1
      // Dump those ones out now.
83
1
      while (Depth < Pending.size()) {
84
1
        Pending.back()(true);
85
1
        this->Pending.pop_back();
86
1
      }
87
1
88
1
      JOS.objectEnd();
89
1
90
1
      if (IsLastChild) {
91
1
        JOS.arrayEnd();
92
1
        JOS.attributeEnd();
93
1
      }
94
1
    };
95
1
96
1
    if (FirstChild) {
97
0
      Pending.push_back(std::move(DumpWithIndent));
98
1
    } else {
99
1
      Pending.back()(false);
100
1
      Pending.back() = std::move(DumpWithIndent);
101
1
    }
102
1
    FirstChild = false;
103
1
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda'()>(llvm::StringRef, clang::FunctionDecl)
void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda0'()>(llvm::StringRef, clang::FunctionDecl)
Line
Count
Source
46
1
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
1
    // If we're at the top level, there's nothing interesting to do; just
48
1
    // run the dumper.
49
1
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
1
65
1
    // We need to capture an owning-string in the lambda because the lambda
66
1
    // is invoked in a deferred manner.
67
1
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
1
    bool WasFirstChild = FirstChild;
69
1
    auto DumpWithIndent = [=](bool IsLastChild) {
70
1
      if (WasFirstChild) {
71
1
        JOS.attributeBegin(LabelStr);
72
1
        JOS.arrayBegin();
73
1
      }
74
1
75
1
      FirstChild = true;
76
1
      unsigned Depth = Pending.size();
77
1
      JOS.objectBegin();
78
1
79
1
      DoAddChild();
80
1
81
1
      // If any children are left, they're the last at their nesting level.
82
1
      // Dump those ones out now.
83
1
      while (Depth < Pending.size()) {
84
1
        Pending.back()(true);
85
1
        this->Pending.pop_back();
86
1
      }
87
1
88
1
      JOS.objectEnd();
89
1
90
1
      if (IsLastChild) {
91
1
        JOS.arrayEnd();
92
1
        JOS.attributeEnd();
93
1
      }
94
1
    };
95
1
96
1
    if (FirstChild) {
97
0
      Pending.push_back(std::move(DumpWithIndent));
98
1
    } else {
99
1
      Pending.back()(false);
100
1
      Pending.back() = std::move(DumpWithIndent);
101
1
    }
102
1
    FirstChild = false;
103
1
  }
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda'()>(llvm::StringRef, clang::VarTemplateSpecializationDecl)
Unexecuted instantiation: void clang::NodeStreamer::AddChild<void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda0'()>(llvm::StringRef, clang::VarTemplateSpecializationDecl)
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Attr const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::Attr const*)::'lambda'())
Line
Count
Source
46
13
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
13
    // If we're at the top level, there's nothing interesting to do; just
48
13
    // run the dumper.
49
13
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
13
65
13
    // We need to capture an owning-string in the lambda because the lambda
66
13
    // is invoked in a deferred manner.
67
13
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
13
    bool WasFirstChild = FirstChild;
69
13
    auto DumpWithIndent = [=](bool IsLastChild) {
70
13
      if (WasFirstChild) {
71
13
        JOS.attributeBegin(LabelStr);
72
13
        JOS.arrayBegin();
73
13
      }
74
13
75
13
      FirstChild = true;
76
13
      unsigned Depth = Pending.size();
77
13
      JOS.objectBegin();
78
13
79
13
      DoAddChild();
80
13
81
13
      // If any children are left, they're the last at their nesting level.
82
13
      // Dump those ones out now.
83
13
      while (Depth < Pending.size()) {
84
13
        Pending.back()(true);
85
13
        this->Pending.pop_back();
86
13
      }
87
13
88
13
      JOS.objectEnd();
89
13
90
13
      if (IsLastChild) {
91
13
        JOS.arrayEnd();
92
13
        JOS.attributeEnd();
93
13
      }
94
13
    };
95
13
96
13
    if (FirstChild) {
97
0
      Pending.push_back(std::move(DumpWithIndent));
98
13
    } else {
99
13
      Pending.back()(false);
100
13
      Pending.back() = std::move(DumpWithIndent);
101
13
    }
102
13
    FirstChild = false;
103
13
  }
void clang::NodeStreamer::AddChild<clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::comments::Comment const*, clang::comments::FullComment const*)::'lambda'()>(llvm::StringRef, clang::ASTNodeTraverser<clang::JSONDumper, clang::JSONNodeDumper>::Visit(clang::comments::Comment const*, clang::comments::FullComment const*)::'lambda'())
Line
Count
Source
46
64
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
47
64
    // If we're at the top level, there's nothing interesting to do; just
48
64
    // run the dumper.
49
64
    if (TopLevel) {
50
0
      TopLevel = false;
51
0
      JOS.objectBegin();
52
0
53
0
      DoAddChild();
54
0
55
0
      while (!Pending.empty()) {
56
0
        Pending.back()(true);
57
0
        Pending.pop_back();
58
0
      }
59
0
60
0
      JOS.objectEnd();
61
0
      TopLevel = true;
62
0
      return;
63
0
    }
64
64
65
64
    // We need to capture an owning-string in the lambda because the lambda
66
64
    // is invoked in a deferred manner.
67
64
    std::string LabelStr(!Label.empty() ? 
Label0
: "inner");
68
64
    bool WasFirstChild = FirstChild;
69
64
    auto DumpWithIndent = [=](bool IsLastChild) {
70
64
      if (WasFirstChild) {
71
64
        JOS.attributeBegin(LabelStr);
72
64
        JOS.arrayBegin();
73
64
      }
74
64
75
64
      FirstChild = true;
76
64
      unsigned Depth = Pending.size();
77
64
      JOS.objectBegin();
78
64
79
64
      DoAddChild();
80
64
81
64
      // If any children are left, they're the last at their nesting level.
82
64
      // Dump those ones out now.
83
64
      while (Depth < Pending.size()) {
84
64
        Pending.back()(true);
85
64
        this->Pending.pop_back();
86
64
      }
87
64
88
64
      JOS.objectEnd();
89
64
90
64
      if (IsLastChild) {
91
64
        JOS.arrayEnd();
92
64
        JOS.attributeEnd();
93
64
      }
94
64
    };
95
64
96
64
    if (FirstChild) {
97
45
      Pending.push_back(std::move(DumpWithIndent));
98
45
    } else {
99
19
      Pending.back()(false);
100
19
      Pending.back() = std::move(DumpWithIndent);
101
19
    }
102
64
    FirstChild = false;
103
64
  }
104
105
122
  NodeStreamer(raw_ostream &OS) : JOS(OS, 2) {}
106
};
107
108
// Dumps AST nodes in JSON format. There is no implied stability for the
109
// content or format of the dump between major releases of Clang, other than it
110
// being valid JSON output. Further, there is no requirement that the
111
// information dumped is a complete representation of the AST, only that the
112
// information presented is correct.
113
class JSONNodeDumper
114
    : public ConstAttrVisitor<JSONNodeDumper>,
115
      public comments::ConstCommentVisitor<JSONNodeDumper, void,
116
                                           const comments::FullComment *>,
117
      public ConstTemplateArgumentVisitor<JSONNodeDumper>,
118
      public ConstStmtVisitor<JSONNodeDumper>,
119
      public TypeVisitor<JSONNodeDumper>,
120
      public ConstDeclVisitor<JSONNodeDumper>,
121
      public NodeStreamer {
122
  friend class JSONDumper;
123
124
  const SourceManager &SM;
125
  ASTContext& Ctx;
126
  ASTNameGenerator ASTNameGen;
127
  PrintingPolicy PrintPolicy;
128
  const comments::CommandTraits *Traits;
129
  StringRef LastLocFilename, LastLocPresumedFilename;
130
  unsigned LastLocLine, LastLocPresumedLine;
131
132
  using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>;
133
  using InnerCommentVisitor =
134
      comments::ConstCommentVisitor<JSONNodeDumper, void,
135
                                    const comments::FullComment *>;
136
  using InnerTemplateArgVisitor = ConstTemplateArgumentVisitor<JSONNodeDumper>;
137
  using InnerStmtVisitor = ConstStmtVisitor<JSONNodeDumper>;
138
  using InnerTypeVisitor = TypeVisitor<JSONNodeDumper>;
139
  using InnerDeclVisitor = ConstDeclVisitor<JSONNodeDumper>;
140
141
8.01k
  void attributeOnlyIfTrue(StringRef Key, bool Value) {
142
8.01k
    if (Value)
143
682
      JOS.attribute(Key, Value);
144
8.01k
  }
145
146
  void writeIncludeStack(PresumedLoc Loc, bool JustFirst = false);
147
148
  // Writes the attributes of a SourceLocation object without.
149
  void writeBareSourceLocation(SourceLocation Loc, bool IsSpelling);
150
151
  // Writes the attributes of a SourceLocation to JSON based on its presumed
152
  // spelling location. If the given location represents a macro invocation,
153
  // this outputs two sub-objects: one for the spelling and one for the
154
  // expansion location.
155
  void writeSourceLocation(SourceLocation Loc);
156
  void writeSourceRange(SourceRange R);
157
  std::string createPointerRepresentation(const void *Ptr);
158
  llvm::json::Object createQualType(QualType QT, bool Desugar = true);
159
  llvm::json::Object createBareDeclRef(const Decl *D);
160
  void writeBareDeclRef(const Decl *D);
161
  llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
162
  llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
163
  std::string createAccessSpecifier(AccessSpecifier AS);
164
  llvm::json::Array createCastPath(const CastExpr *C);
165
166
89
  void writePreviousDeclImpl(...) {}
167
168
105
  template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
169
105
    const T *First = D->getFirstDecl();
170
105
    if (First != D)
171
0
      JOS.attribute("firstRedecl", createPointerRepresentation(First));
172
105
  }
Unexecuted instantiation: void clang::JSONNodeDumper::writePreviousDeclImpl<clang::LifetimeExtendedTemporaryDecl>(clang::Mergeable<clang::LifetimeExtendedTemporaryDecl> const*)
Unexecuted instantiation: void clang::JSONNodeDumper::writePreviousDeclImpl<clang::ConceptDecl>(clang::Mergeable<clang::ConceptDecl> const*)
Unexecuted instantiation: void clang::JSONNodeDumper::writePreviousDeclImpl<clang::UnresolvedUsingTypenameDecl>(clang::Mergeable<clang::UnresolvedUsingTypenameDecl> const*)
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::UsingDecl>(clang::Mergeable<clang::UsingDecl> const*)
Line
Count
Source
168
4
  template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
169
4
    const T *First = D->getFirstDecl();
170
4
    if (First != D)
171
0
      JOS.attribute("firstRedecl", createPointerRepresentation(First));
172
4
  }
Unexecuted instantiation: void clang::JSONNodeDumper::writePreviousDeclImpl<clang::UsingPackDecl>(clang::Mergeable<clang::UsingPackDecl> const*)
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::FieldDecl>(clang::Mergeable<clang::FieldDecl> const*)
Line
Count
Source
168
74
  template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
169
74
    const T *First = D->getFirstDecl();
170
74
    if (First != D)
171
0
      JOS.attribute("firstRedecl", createPointerRepresentation(First));
172
74
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::EnumConstantDecl>(clang::Mergeable<clang::EnumConstantDecl> const*)
Line
Count
Source
168
17
  template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
169
17
    const T *First = D->getFirstDecl();
170
17
    if (First != D)
171
0
      JOS.attribute("firstRedecl", createPointerRepresentation(First));
172
17
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::IndirectFieldDecl>(clang::Mergeable<clang::IndirectFieldDecl> const*)
Line
Count
Source
168
10
  template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
169
10
    const T *First = D->getFirstDecl();
170
10
    if (First != D)
171
0
      JOS.attribute("firstRedecl", createPointerRepresentation(First));
172
10
  }
Unexecuted instantiation: void clang::JSONNodeDumper::writePreviousDeclImpl<clang::UnresolvedUsingValueDecl>(clang::Mergeable<clang::UnresolvedUsingValueDecl> const*)
173
174
844
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
844
    const T *Prev = D->getPreviousDecl();
176
844
    if (Prev)
177
13
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
844
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::NamespaceDecl>(clang::Redeclarable<clang::NamespaceDecl> const*)
Line
Count
Source
174
12
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
12
    const T *Prev = D->getPreviousDecl();
176
12
    if (Prev)
177
0
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
12
  }
Unexecuted instantiation: void clang::JSONNodeDumper::writePreviousDeclImpl<clang::NamespaceAliasDecl>(clang::Redeclarable<clang::NamespaceAliasDecl> const*)
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::ObjCInterfaceDecl>(clang::Redeclarable<clang::ObjCInterfaceDecl> const*)
Line
Count
Source
174
4
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
4
    const T *Prev = D->getPreviousDecl();
176
4
    if (Prev)
177
0
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
4
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::ObjCProtocolDecl>(clang::Redeclarable<clang::ObjCProtocolDecl> const*)
Line
Count
Source
174
1
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
1
    const T *Prev = D->getPreviousDecl();
176
1
    if (Prev)
177
0
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
1
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::RedeclarableTemplateDecl>(clang::Redeclarable<clang::RedeclarableTemplateDecl> const*)
Line
Count
Source
174
31
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
31
    const T *Prev = D->getPreviousDecl();
176
31
    if (Prev)
177
1
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
31
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::TagDecl>(clang::Redeclarable<clang::TagDecl> const*)
Line
Count
Source
174
169
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
169
    const T *Prev = D->getPreviousDecl();
176
169
    if (Prev)
177
2
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
169
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::TypedefNameDecl>(clang::Redeclarable<clang::TypedefNameDecl> const*)
Line
Count
Source
174
119
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
119
    const T *Prev = D->getPreviousDecl();
176
119
    if (Prev)
177
0
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
119
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::UsingShadowDecl>(clang::Redeclarable<clang::UsingShadowDecl> const*)
Line
Count
Source
174
3
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
3
    const T *Prev = D->getPreviousDecl();
176
3
    if (Prev)
177
0
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
3
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::FunctionDecl>(clang::Redeclarable<clang::FunctionDecl> const*)
Line
Count
Source
174
256
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
256
    const T *Prev = D->getPreviousDecl();
176
256
    if (Prev)
177
10
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
256
  }
void clang::JSONNodeDumper::writePreviousDeclImpl<clang::VarDecl>(clang::Redeclarable<clang::VarDecl> const*)
Line
Count
Source
174
249
  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
175
249
    const T *Prev = D->getPreviousDecl();
176
249
    if (Prev)
177
0
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
178
249
  }
179
  void addPreviousDeclaration(const Decl *D);
180
181
  StringRef getCommentCommandName(unsigned CommandID) const;
182
183
public:
184
  JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
185
                 const PrintingPolicy &PrintPolicy,
186
                 const comments::CommandTraits *Traits)
187
      : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), ASTNameGen(Ctx),
188
        PrintPolicy(PrintPolicy), Traits(Traits), LastLocLine(0),
189
122
        LastLocPresumedLine(0) {}
190
191
  void Visit(const Attr *A);
192
  void Visit(const Stmt *Node);
193
  void Visit(const Type *T);
194
  void Visit(QualType T);
195
  void Visit(const Decl *D);
196
197
  void Visit(const comments::Comment *C, const comments::FullComment *FC);
198
  void Visit(const TemplateArgument &TA, SourceRange R = {},
199
             const Decl *From = nullptr, StringRef Label = {});
200
  void Visit(const CXXCtorInitializer *Init);
201
  void Visit(const OMPClause *C);
202
  void Visit(const BlockDecl::Capture &C);
203
  void Visit(const GenericSelectionExpr::ConstAssociation &A);
204
205
  void VisitTypedefType(const TypedefType *TT);
206
  void VisitFunctionType(const FunctionType *T);
207
  void VisitFunctionProtoType(const FunctionProtoType *T);
208
  void VisitRValueReferenceType(const ReferenceType *RT);
209
  void VisitArrayType(const ArrayType *AT);
210
  void VisitConstantArrayType(const ConstantArrayType *CAT);
211
  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *VT);
212
  void VisitVectorType(const VectorType *VT);
213
  void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT);
214
  void VisitUnaryTransformType(const UnaryTransformType *UTT);
215
  void VisitTagType(const TagType *TT);
216
  void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
217
  void VisitAutoType(const AutoType *AT);
218
  void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
219
  void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
220
  void VisitObjCInterfaceType(const ObjCInterfaceType *OIT);
221
  void VisitPackExpansionType(const PackExpansionType *PET);
222
  void VisitElaboratedType(const ElaboratedType *ET);
223
  void VisitMacroQualifiedType(const MacroQualifiedType *MQT);
224
  void VisitMemberPointerType(const MemberPointerType *MPT);
225
226
  void VisitNamedDecl(const NamedDecl *ND);
227
  void VisitTypedefDecl(const TypedefDecl *TD);
228
  void VisitTypeAliasDecl(const TypeAliasDecl *TAD);
229
  void VisitNamespaceDecl(const NamespaceDecl *ND);
230
  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD);
231
  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD);
232
  void VisitUsingDecl(const UsingDecl *UD);
233
  void VisitUsingShadowDecl(const UsingShadowDecl *USD);
234
  void VisitVarDecl(const VarDecl *VD);
235
  void VisitFieldDecl(const FieldDecl *FD);
236
  void VisitFunctionDecl(const FunctionDecl *FD);
237
  void VisitEnumDecl(const EnumDecl *ED);
238
  void VisitEnumConstantDecl(const EnumConstantDecl *ECD);
239
  void VisitRecordDecl(const RecordDecl *RD);
240
  void VisitCXXRecordDecl(const CXXRecordDecl *RD);
241
  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
242
  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
243
  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
244
  void VisitLinkageSpecDecl(const LinkageSpecDecl *LSD);
245
  void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
246
  void VisitFriendDecl(const FriendDecl *FD);
247
248
  void VisitObjCIvarDecl(const ObjCIvarDecl *D);
249
  void VisitObjCMethodDecl(const ObjCMethodDecl *D);
250
  void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
251
  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
252
  void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
253
  void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
254
  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
255
  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
256
  void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
257
  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
258
  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
259
  void VisitBlockDecl(const BlockDecl *D);
260
261
  void VisitDeclRefExpr(const DeclRefExpr *DRE);
262
  void VisitPredefinedExpr(const PredefinedExpr *PE);
263
  void VisitUnaryOperator(const UnaryOperator *UO);
264
  void VisitBinaryOperator(const BinaryOperator *BO);
265
  void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
266
  void VisitMemberExpr(const MemberExpr *ME);
267
  void VisitCXXNewExpr(const CXXNewExpr *NE);
268
  void VisitCXXDeleteExpr(const CXXDeleteExpr *DE);
269
  void VisitCXXThisExpr(const CXXThisExpr *TE);
270
  void VisitCastExpr(const CastExpr *CE);
271
  void VisitImplicitCastExpr(const ImplicitCastExpr *ICE);
272
  void VisitCallExpr(const CallExpr *CE);
273
  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *TTE);
274
  void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE);
275
  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *ULE);
276
  void VisitAddrLabelExpr(const AddrLabelExpr *ALE);
277
  void VisitCXXTypeidExpr(const CXXTypeidExpr *CTE);
278
  void VisitConstantExpr(const ConstantExpr *CE);
279
  void VisitInitListExpr(const InitListExpr *ILE);
280
  void VisitGenericSelectionExpr(const GenericSelectionExpr *GSE);
281
  void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *UCE);
282
  void VisitCXXConstructExpr(const CXXConstructExpr *CE);
283
  void VisitExprWithCleanups(const ExprWithCleanups *EWC);
284
  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE);
285
  void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE);
286
  void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME);
287
288
  void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE);
289
  void VisitObjCMessageExpr(const ObjCMessageExpr *OME);
290
  void VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE);
291
  void VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE);
292
  void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE);
293
  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE);
294
  void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *OSRE);
295
  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE);
296
  void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE);
297
298
  void VisitIntegerLiteral(const IntegerLiteral *IL);
299
  void VisitCharacterLiteral(const CharacterLiteral *CL);
300
  void VisitFixedPointLiteral(const FixedPointLiteral *FPL);
301
  void VisitFloatingLiteral(const FloatingLiteral *FL);
302
  void VisitStringLiteral(const StringLiteral *SL);
303
  void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE);
304
305
  void VisitIfStmt(const IfStmt *IS);
306
  void VisitSwitchStmt(const SwitchStmt *SS);
307
  void VisitCaseStmt(const CaseStmt *CS);
308
  void VisitLabelStmt(const LabelStmt *LS);
309
  void VisitGotoStmt(const GotoStmt *GS);
310
  void VisitWhileStmt(const WhileStmt *WS);
311
  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);
312
313
  void VisitNullTemplateArgument(const TemplateArgument &TA);
314
  void VisitTypeTemplateArgument(const TemplateArgument &TA);
315
  void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
316
  void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
317
  void VisitIntegralTemplateArgument(const TemplateArgument &TA);
318
  void VisitTemplateTemplateArgument(const TemplateArgument &TA);
319
  void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
320
  void VisitExpressionTemplateArgument(const TemplateArgument &TA);
321
  void VisitPackTemplateArgument(const TemplateArgument &TA);
322
323
  void visitTextComment(const comments::TextComment *C,
324
                        const comments::FullComment *);
325
  void visitInlineCommandComment(const comments::InlineCommandComment *C,
326
                                 const comments::FullComment *);
327
  void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
328
                                const comments::FullComment *);
329
  void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
330
                              const comments::FullComment *);
331
  void visitBlockCommandComment(const comments::BlockCommandComment *C,
332
                                const comments::FullComment *);
333
  void visitParamCommandComment(const comments::ParamCommandComment *C,
334
                                const comments::FullComment *FC);
335
  void visitTParamCommandComment(const comments::TParamCommandComment *C,
336
                                 const comments::FullComment *FC);
337
  void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
338
                                 const comments::FullComment *);
339
  void
340
  visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
341
                                const comments::FullComment *);
342
  void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
343
                                const comments::FullComment *);
344
};
345
346
class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
347
  JSONNodeDumper NodeDumper;
348
349
  template <typename SpecializationDecl>
350
  void writeTemplateDeclSpecialization(const SpecializationDecl *SD,
351
                                       bool DumpExplicitInst,
352
2
                                       bool DumpRefOnly) {
353
2
    bool DumpedAny = false;
354
3
    for (const auto *RedeclWithBadType : SD->redecls()) {
355
3
      // FIXME: The redecls() range sometimes has elements of a less-specific
356
3
      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
357
3
      // us TagDecls, and should give CXXRecordDecls).
358
3
      const auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
359
3
      if (!Redecl) {
360
0
        // Found the injected-class-name for a class template. This will be
361
0
        // dumped as part of its surrounding class so we don't need to dump it
362
0
        // here.
363
0
        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
364
0
               "expected an injected-class-name");
365
0
        continue;
366
0
      }
367
3
368
3
      switch (Redecl->getTemplateSpecializationKind()) {
369
0
      case TSK_ExplicitInstantiationDeclaration:
370
0
      case TSK_ExplicitInstantiationDefinition:
371
0
        if (!DumpExplicitInst)
372
0
          break;
373
0
        LLVM_FALLTHROUGH;
374
0
      case TSK_Undeclared:
375
0
      case TSK_ImplicitInstantiation:
376
0
        if (DumpRefOnly)
377
0
          NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); });
Unexecuted instantiation: void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda'()::operator()() const
Unexecuted instantiation: void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda'()::operator()() const
Unexecuted instantiation: void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda'()::operator()() const
378
0
        else
379
0
          Visit(Redecl);
380
0
        DumpedAny = true;
381
0
        break;
382
3
      case TSK_ExplicitSpecialization:
383
3
        break;
384
3
      }
385
3
    }
386
2
387
2
    // Ensure we dump at least one decl for each specialization.
388
2
    if (!DumpedAny)
389
2
      NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)::'lambda0'()::operator()() const
Line
Count
Source
389
1
      NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)::'lambda0'()::operator()() const
Line
Count
Source
389
1
      NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
Unexecuted instantiation: void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)::'lambda0'()::operator()() const
390
2
  }
void clang::JSONDumper::writeTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)
Line
Count
Source
352
1
                                       bool DumpRefOnly) {
353
1
    bool DumpedAny = false;
354
1
    for (const auto *RedeclWithBadType : SD->redecls()) {
355
1
      // FIXME: The redecls() range sometimes has elements of a less-specific
356
1
      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
357
1
      // us TagDecls, and should give CXXRecordDecls).
358
1
      const auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
359
1
      if (!Redecl) {
360
0
        // Found the injected-class-name for a class template. This will be
361
0
        // dumped as part of its surrounding class so we don't need to dump it
362
0
        // here.
363
0
        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
364
0
               "expected an injected-class-name");
365
0
        continue;
366
0
      }
367
1
368
1
      switch (Redecl->getTemplateSpecializationKind()) {
369
0
      case TSK_ExplicitInstantiationDeclaration:
370
0
      case TSK_ExplicitInstantiationDefinition:
371
0
        if (!DumpExplicitInst)
372
0
          break;
373
0
        LLVM_FALLTHROUGH;
374
0
      case TSK_Undeclared:
375
0
      case TSK_ImplicitInstantiation:
376
0
        if (DumpRefOnly)
377
0
          NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); });
378
0
        else
379
0
          Visit(Redecl);
380
0
        DumpedAny = true;
381
0
        break;
382
1
      case TSK_ExplicitSpecialization:
383
1
        break;
384
1
      }
385
1
    }
386
1
387
1
    // Ensure we dump at least one decl for each specialization.
388
1
    if (!DumpedAny)
389
1
      NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
390
1
  }
void clang::JSONDumper::writeTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)
Line
Count
Source
352
1
                                       bool DumpRefOnly) {
353
1
    bool DumpedAny = false;
354
2
    for (const auto *RedeclWithBadType : SD->redecls()) {
355
2
      // FIXME: The redecls() range sometimes has elements of a less-specific
356
2
      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
357
2
      // us TagDecls, and should give CXXRecordDecls).
358
2
      const auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
359
2
      if (!Redecl) {
360
0
        // Found the injected-class-name for a class template. This will be
361
0
        // dumped as part of its surrounding class so we don't need to dump it
362
0
        // here.
363
0
        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
364
0
               "expected an injected-class-name");
365
0
        continue;
366
0
      }
367
2
368
2
      switch (Redecl->getTemplateSpecializationKind()) {
369
0
      case TSK_ExplicitInstantiationDeclaration:
370
0
      case TSK_ExplicitInstantiationDefinition:
371
0
        if (!DumpExplicitInst)
372
0
          break;
373
0
        LLVM_FALLTHROUGH;
374
0
      case TSK_Undeclared:
375
0
      case TSK_ImplicitInstantiation:
376
0
        if (DumpRefOnly)
377
0
          NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); });
378
0
        else
379
0
          Visit(Redecl);
380
0
        DumpedAny = true;
381
0
        break;
382
2
      case TSK_ExplicitSpecialization:
383
2
        break;
384
2
      }
385
2
    }
386
1
387
1
    // Ensure we dump at least one decl for each specialization.
388
1
    if (!DumpedAny)
389
1
      NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
390
1
  }
Unexecuted instantiation: void clang::JSONDumper::writeTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)
391
392
  template <typename TemplateDecl>
393
31
  void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) {
394
31
    // FIXME: it would be nice to dump template parameters and specializations
395
31
    // to their own named arrays rather than shoving them into the "inner"
396
31
    // array. However, template declarations are currently being handled at the
397
31
    // wrong "level" of the traversal hierarchy and so it is difficult to
398
31
    // achieve without losing information elsewhere.
399
31
400
31
    dumpTemplateParameters(TD->getTemplateParameters());
401
31
402
31
    Visit(TD->getTemplatedDecl());
403
31
404
31
    for (const auto *Child : TD->specializations())
405
2
      writeTemplateDeclSpecialization(Child, DumpExplicitInst,
406
2
                                      !TD->isCanonicalDecl());
407
31
  }
void clang::JSONDumper::writeTemplateDecl<clang::ClassTemplateDecl>(clang::ClassTemplateDecl const*, bool)
Line
Count
Source
393
9
  void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) {
394
9
    // FIXME: it would be nice to dump template parameters and specializations
395
9
    // to their own named arrays rather than shoving them into the "inner"
396
9
    // array. However, template declarations are currently being handled at the
397
9
    // wrong "level" of the traversal hierarchy and so it is difficult to
398
9
    // achieve without losing information elsewhere.
399
9
400
9
    dumpTemplateParameters(TD->getTemplateParameters());
401
9
402
9
    Visit(TD->getTemplatedDecl());
403
9
404
9
    for (const auto *Child : TD->specializations())
405
1
      writeTemplateDeclSpecialization(Child, DumpExplicitInst,
406
1
                                      !TD->isCanonicalDecl());
407
9
  }
void clang::JSONDumper::writeTemplateDecl<clang::FunctionTemplateDecl>(clang::FunctionTemplateDecl const*, bool)
Line
Count
Source
393
21
  void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) {
394
21
    // FIXME: it would be nice to dump template parameters and specializations
395
21
    // to their own named arrays rather than shoving them into the "inner"
396
21
    // array. However, template declarations are currently being handled at the
397
21
    // wrong "level" of the traversal hierarchy and so it is difficult to
398
21
    // achieve without losing information elsewhere.
399
21
400
21
    dumpTemplateParameters(TD->getTemplateParameters());
401
21
402
21
    Visit(TD->getTemplatedDecl());
403
21
404
21
    for (const auto *Child : TD->specializations())
405
1
      writeTemplateDeclSpecialization(Child, DumpExplicitInst,
406
1
                                      !TD->isCanonicalDecl());
407
21
  }
void clang::JSONDumper::writeTemplateDecl<clang::VarTemplateDecl>(clang::VarTemplateDecl const*, bool)
Line
Count
Source
393
1
  void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) {
394
1
    // FIXME: it would be nice to dump template parameters and specializations
395
1
    // to their own named arrays rather than shoving them into the "inner"
396
1
    // array. However, template declarations are currently being handled at the
397
1
    // wrong "level" of the traversal hierarchy and so it is difficult to
398
1
    // achieve without losing information elsewhere.
399
1
400
1
    dumpTemplateParameters(TD->getTemplateParameters());
401
1
402
1
    Visit(TD->getTemplatedDecl());
403
1
404
1
    for (const auto *Child : TD->specializations())
405
0
      writeTemplateDeclSpecialization(Child, DumpExplicitInst,
406
0
                                      !TD->isCanonicalDecl());
407
1
  }
408
409
public:
410
  JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
411
             const PrintingPolicy &PrintPolicy,
412
             const comments::CommandTraits *Traits)
413
122
      : NodeDumper(OS, SrcMgr, Ctx, PrintPolicy, Traits) {}
414
415
5.63k
  JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; }
416
417
21
  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *FTD) {
418
21
    writeTemplateDecl(FTD, true);
419
21
  }
420
9
  void VisitClassTemplateDecl(const ClassTemplateDecl *CTD) {
421
9
    writeTemplateDecl(CTD, false);
422
9
  }
423
1
  void VisitVarTemplateDecl(const VarTemplateDecl *VTD) {
424
1
    writeTemplateDecl(VTD, false);
425
1
  }
426
};
427
428
} // namespace clang
429
430
#endif // LLVM_CLANG_AST_JSONNODEDUMPER_H