Coverage Report

Created: 2022-07-16 07:03

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/ASTDumper.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
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 the AST dump methods, which dump out the
10
// AST in a form that exposes type details and other fields.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/ASTDumper.h"
15
#include "clang/AST/ASTContext.h"
16
#include "clang/AST/DeclLookups.h"
17
#include "clang/AST/JSONNodeDumper.h"
18
#include "clang/Basic/Builtins.h"
19
#include "clang/Basic/Module.h"
20
#include "clang/Basic/SourceManager.h"
21
#include "llvm/Support/raw_ostream.h"
22
using namespace clang;
23
using namespace clang::comments;
24
25
7
void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
26
7
  NodeDumper.AddChild([=] {
27
7
    OS << "StoredDeclsMap ";
28
7
    NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
29
30
7
    const DeclContext *Primary = DC->getPrimaryContext();
31
7
    if (Primary != DC) {
32
0
      OS << " primary";
33
0
      NodeDumper.dumpPointer(cast<Decl>(Primary));
34
0
    }
35
36
7
    bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
37
38
7
    auto Range = getDeserialize()
39
7
                     ? 
Primary->lookups()0
40
7
                     : Primary->noload_lookups(/*PreserveInternalState=*/true);
41
139
    for (auto I = Range.begin(), E = Range.end(); I != E; 
++I132
) {
42
132
      DeclarationName Name = I.getLookupName();
43
132
      DeclContextLookupResult R = *I;
44
45
132
      NodeDumper.AddChild([=] {
46
132
        OS << "DeclarationName ";
47
132
        {
48
132
          ColorScope Color(OS, ShowColors, DeclNameColor);
49
132
          OS << '\'' << Name << '\'';
50
132
        }
51
52
132
        for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
53
266
             RI != RE; 
++RI134
) {
54
134
          NodeDumper.AddChild([=] {
55
134
            NodeDumper.dumpBareDeclRef(*RI);
56
57
134
            if (!(*RI)->isUnconditionallyVisible())
58
2
              OS << " hidden";
59
60
            // If requested, dump the redecl chain for this lookup.
61
134
            if (DumpDecls) {
62
              // Dump earliest decl first.
63
3
              std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
64
3
                if (Decl *Prev = D->getPreviousDecl())
65
1
                  DumpWithPrev(Prev);
66
3
                Visit(D);
67
3
              };
68
2
              DumpWithPrev(*RI);
69
2
            }
70
134
          });
71
134
        }
72
132
      });
73
132
    }
74
75
7
    if (HasUndeserializedLookups) {
76
5
      NodeDumper.AddChild([=] {
77
5
        ColorScope Color(OS, ShowColors, UndeserializedColor);
78
5
        OS << "<undeserialized lookups>";
79
5
      });
80
5
    }
81
7
  });
82
7
}
83
84
template <typename SpecializationDecl>
85
void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
86
                                               bool DumpExplicitInst,
87
397
                                               bool DumpRefOnly) {
88
397
  bool DumpedAny = false;
89
405
  for (const auto *RedeclWithBadType : D->redecls()) {
90
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
    // us TagDecls, and should give CXXRecordDecls).
93
405
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
405
    switch (Redecl->getTemplateSpecializationKind()) {
95
2
    case TSK_ExplicitInstantiationDeclaration:
96
21
    case TSK_ExplicitInstantiationDefinition:
97
21
      if (!DumpExplicitInst)
98
16
        break;
99
21
      
LLVM_FALLTHROUGH5
;5
100
22
    case TSK_Undeclared:
101
357
    case TSK_ImplicitInstantiation:
102
357
      if (DumpRefOnly)
103
36
        NodeDumper.dumpDeclRef(Redecl);
104
321
      else
105
321
        Visit(Redecl);
106
357
      DumpedAny = true;
107
357
      break;
108
32
    case TSK_ExplicitSpecialization:
109
32
      break;
110
405
    }
111
405
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
397
  if (!DumpedAny)
115
44
    NodeDumper.dumpDeclRef(D);
116
397
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)
Line
Count
Source
87
189
                                               bool DumpRefOnly) {
88
189
  bool DumpedAny = false;
89
193
  for (const auto *RedeclWithBadType : D->redecls()) {
90
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
    // us TagDecls, and should give CXXRecordDecls).
93
193
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
193
    switch (Redecl->getTemplateSpecializationKind()) {
95
1
    case TSK_ExplicitInstantiationDeclaration:
96
5
    case TSK_ExplicitInstantiationDefinition:
97
5
      if (!DumpExplicitInst)
98
0
        break;
99
5
      LLVM_FALLTHROUGH;
100
5
    case TSK_Undeclared:
101
185
    case TSK_ImplicitInstantiation:
102
185
      if (DumpRefOnly)
103
5
        NodeDumper.dumpDeclRef(Redecl);
104
180
      else
105
180
        Visit(Redecl);
106
185
      DumpedAny = true;
107
185
      break;
108
8
    case TSK_ExplicitSpecialization:
109
8
      break;
110
193
    }
111
193
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
189
  if (!DumpedAny)
115
4
    NodeDumper.dumpDeclRef(D);
116
189
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)
Line
Count
Source
87
205
                                               bool DumpRefOnly) {
88
205
  bool DumpedAny = false;
89
207
  for (const auto *RedeclWithBadType : D->redecls()) {
90
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
    // us TagDecls, and should give CXXRecordDecls).
93
207
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
207
    switch (Redecl->getTemplateSpecializationKind()) {
95
1
    case TSK_ExplicitInstantiationDeclaration:
96
16
    case TSK_ExplicitInstantiationDefinition:
97
16
      if (!DumpExplicitInst)
98
16
        break;
99
16
      
LLVM_FALLTHROUGH0
;0
100
17
    case TSK_Undeclared:
101
167
    case TSK_ImplicitInstantiation:
102
167
      if (DumpRefOnly)
103
29
        NodeDumper.dumpDeclRef(Redecl);
104
138
      else
105
138
        Visit(Redecl);
106
167
      DumpedAny = true;
107
167
      break;
108
24
    case TSK_ExplicitSpecialization:
109
24
      break;
110
207
    }
111
207
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
205
  if (!DumpedAny)
115
40
    NodeDumper.dumpDeclRef(D);
116
205
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)
Line
Count
Source
87
3
                                               bool DumpRefOnly) {
88
3
  bool DumpedAny = false;
89
5
  for (const auto *RedeclWithBadType : D->redecls()) {
90
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
    // us TagDecls, and should give CXXRecordDecls).
93
5
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
5
    switch (Redecl->getTemplateSpecializationKind()) {
95
0
    case TSK_ExplicitInstantiationDeclaration:
96
0
    case TSK_ExplicitInstantiationDefinition:
97
0
      if (!DumpExplicitInst)
98
0
        break;
99
0
      LLVM_FALLTHROUGH;
100
0
    case TSK_Undeclared:
101
5
    case TSK_ImplicitInstantiation:
102
5
      if (DumpRefOnly)
103
2
        NodeDumper.dumpDeclRef(Redecl);
104
3
      else
105
3
        Visit(Redecl);
106
5
      DumpedAny = true;
107
5
      break;
108
0
    case TSK_ExplicitSpecialization:
109
0
      break;
110
5
    }
111
5
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
3
  if (!DumpedAny)
115
0
    NodeDumper.dumpDeclRef(D);
116
3
}
117
118
template <typename TemplateDecl>
119
577
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
577
  dumpTemplateParameters(D->getTemplateParameters());
121
122
577
  Visit(D->getTemplatedDecl());
123
124
577
  if (GetTraversalKind() == TK_AsIs) {
125
577
    for (const auto *Child : D->specializations())
126
397
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
397
                                     !D->isCanonicalDecl());
128
577
  }
129
577
}
void clang::ASTDumper::dumpTemplateDecl<clang::FunctionTemplateDecl>(clang::FunctionTemplateDecl const*, bool)
Line
Count
Source
119
350
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
350
  dumpTemplateParameters(D->getTemplateParameters());
121
122
350
  Visit(D->getTemplatedDecl());
123
124
350
  if (GetTraversalKind() == TK_AsIs) {
125
350
    for (const auto *Child : D->specializations())
126
189
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
189
                                     !D->isCanonicalDecl());
128
350
  }
129
350
}
void clang::ASTDumper::dumpTemplateDecl<clang::ClassTemplateDecl>(clang::ClassTemplateDecl const*, bool)
Line
Count
Source
119
222
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
222
  dumpTemplateParameters(D->getTemplateParameters());
121
122
222
  Visit(D->getTemplatedDecl());
123
124
222
  if (GetTraversalKind() == TK_AsIs) {
125
222
    for (const auto *Child : D->specializations())
126
205
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
205
                                     !D->isCanonicalDecl());
128
222
  }
129
222
}
void clang::ASTDumper::dumpTemplateDecl<clang::VarTemplateDecl>(clang::VarTemplateDecl const*, bool)
Line
Count
Source
119
5
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
5
  dumpTemplateParameters(D->getTemplateParameters());
121
122
5
  Visit(D->getTemplatedDecl());
123
124
5
  if (GetTraversalKind() == TK_AsIs) {
125
5
    for (const auto *Child : D->specializations())
126
3
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
3
                                     !D->isCanonicalDecl());
128
5
  }
129
5
}
130
131
350
void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
132
  // FIXME: We don't add a declaration of a function template specialization
133
  // to its context when it's explicitly instantiated, so dump explicit
134
  // instantiations when we dump the template itself.
135
350
  dumpTemplateDecl(D, true);
136
350
}
137
138
222
void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
139
222
  dumpTemplateDecl(D, false);
140
222
}
141
142
5
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
143
5
  dumpTemplateDecl(D, false);
144
5
}
145
146
//===----------------------------------------------------------------------===//
147
// Type method implementations
148
//===----------------------------------------------------------------------===//
149
150
0
void QualType::dump(const char *msg) const {
151
0
  if (msg)
152
0
    llvm::errs() << msg << ": ";
153
0
  dump();
154
0
}
155
156
0
LLVM_DUMP_METHOD void QualType::dump() const {
157
0
  ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
158
0
  Dumper.Visit(*this);
159
0
}
160
161
LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS,
162
29
                                     const ASTContext &Context) const {
163
29
  ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
164
29
  Dumper.Visit(*this);
165
29
}
166
167
0
LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
168
169
LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS,
170
0
                                 const ASTContext &Context) const {
171
0
  QualType(this, 0).dump(OS, Context);
172
0
}
173
174
//===----------------------------------------------------------------------===//
175
// Decl method implementations
176
//===----------------------------------------------------------------------===//
177
178
23
LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
179
180
LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
181
1.84k
                                 ASTDumpOutputFormat Format) const {
182
1.84k
  ASTContext &Ctx = getASTContext();
183
1.84k
  const SourceManager &SM = Ctx.getSourceManager();
184
185
1.84k
  if (ADOF_JSON == Format) {
186
167
    JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
187
167
                 &Ctx.getCommentCommandTraits());
188
167
    (void)Deserialize; // FIXME?
189
167
    P.Visit(this);
190
1.68k
  } else {
191
1.68k
    ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
192
1.68k
    P.setDeserialize(Deserialize);
193
1.68k
    P.Visit(this);
194
1.68k
  }
195
1.84k
}
196
197
0
LLVM_DUMP_METHOD void Decl::dumpColor() const {
198
0
  const ASTContext &Ctx = getASTContext();
199
0
  ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
200
0
  P.Visit(this);
201
0
}
202
203
0
LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
204
0
  dumpLookups(llvm::errs());
205
0
}
206
207
LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
208
                                               bool DumpDecls,
209
7
                                               bool Deserialize) const {
210
7
  const DeclContext *DC = this;
211
13
  while (!DC->isTranslationUnit())
212
6
    DC = DC->getParent();
213
7
  const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
214
7
  ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
215
7
  P.setDeserialize(Deserialize);
216
7
  P.dumpLookups(this, DumpDecls);
217
7
}
218
219
//===----------------------------------------------------------------------===//
220
// Stmt method implementations
221
//===----------------------------------------------------------------------===//
222
223
14
LLVM_DUMP_METHOD void Stmt::dump() const {
224
14
  ASTDumper P(llvm::errs(), /*ShowColors=*/false);
225
14
  P.Visit(this);
226
14
}
227
228
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
229
1
                                 const ASTContext &Context) const {
230
1
  ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors());
231
1
  P.Visit(this);
232
1
}
233
234
0
LLVM_DUMP_METHOD void Stmt::dumpColor() const {
235
0
  ASTDumper P(llvm::errs(), /*ShowColors=*/true);
236
0
  P.Visit(this);
237
0
}
238
239
//===----------------------------------------------------------------------===//
240
// Comment method implementations
241
//===----------------------------------------------------------------------===//
242
243
79
LLVM_DUMP_METHOD void Comment::dump() const {
244
79
  const auto *FC = dyn_cast<FullComment>(this);
245
79
  if (!FC)
246
0
    return;
247
79
  ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
248
79
  Dumper.Visit(FC, FC);
249
79
}
250
251
LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
252
0
                                    const ASTContext &Context) const {
253
0
  const auto *FC = dyn_cast<FullComment>(this);
254
0
  if (!FC)
255
0
    return;
256
0
  ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
257
0
  Dumper.Visit(FC, FC);
258
0
}
259
260
0
LLVM_DUMP_METHOD void Comment::dumpColor() const {
261
0
  const auto *FC = dyn_cast<FullComment>(this);
262
0
  if (!FC)
263
0
    return;
264
0
  ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
265
0
  Dumper.Visit(FC, FC);
266
0
}
267
268
//===----------------------------------------------------------------------===//
269
// APValue method implementations
270
//===----------------------------------------------------------------------===//
271
272
0
LLVM_DUMP_METHOD void APValue::dump() const {
273
0
  ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
274
0
  Dumper.Visit(*this, /*Ty=*/QualType());
275
0
}
276
277
LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
278
0
                                    const ASTContext &Context) const {
279
0
  ASTDumper Dumper(llvm::errs(), Context,
280
0
                   Context.getDiagnostics().getShowColors());
281
0
  Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
282
0
}