/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 |