Coverage Report

Created: 2019-07-24 05:18

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