Coverage Report

Created: 2023-09-30 09:22

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