Coverage Report

Created: 2022-01-18 06:27

/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
358
                                               bool DumpRefOnly) {
88
358
  bool DumpedAny = false;
89
366
  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
366
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
366
    switch (Redecl->getTemplateSpecializationKind()) {
95
2
    case TSK_ExplicitInstantiationDeclaration:
96
18
    case TSK_ExplicitInstantiationDefinition:
97
18
      if (!DumpExplicitInst)
98
13
        break;
99
18
      
LLVM_FALLTHROUGH5
;5
100
19
    case TSK_Undeclared:
101
322
    case TSK_ImplicitInstantiation:
102
322
      if (DumpRefOnly)
103
33
        NodeDumper.dumpDeclRef(Redecl);
104
289
      else
105
289
        Visit(Redecl);
106
322
      DumpedAny = true;
107
322
      break;
108
31
    case TSK_ExplicitSpecialization:
109
31
      break;
110
366
    }
111
366
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
358
  if (!DumpedAny)
115
40
    NodeDumper.dumpDeclRef(D);
116
358
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)
Line
Count
Source
87
173
                                               bool DumpRefOnly) {
88
173
  bool DumpedAny = false;
89
177
  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
177
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
177
    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
169
    case TSK_ImplicitInstantiation:
102
169
      if (DumpRefOnly)
103
2
        NodeDumper.dumpDeclRef(Redecl);
104
167
      else
105
167
        Visit(Redecl);
106
169
      DumpedAny = true;
107
169
      break;
108
8
    case TSK_ExplicitSpecialization:
109
8
      break;
110
177
    }
111
177
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
173
  if (!DumpedAny)
115
4
    NodeDumper.dumpDeclRef(D);
116
173
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)
Line
Count
Source
87
182
                                               bool DumpRefOnly) {
88
182
  bool DumpedAny = false;
89
184
  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
184
    auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
94
184
    switch (Redecl->getTemplateSpecializationKind()) {
95
1
    case TSK_ExplicitInstantiationDeclaration:
96
13
    case TSK_ExplicitInstantiationDefinition:
97
13
      if (!DumpExplicitInst)
98
13
        break;
99
13
      
LLVM_FALLTHROUGH0
;0
100
14
    case TSK_Undeclared:
101
148
    case TSK_ImplicitInstantiation:
102
148
      if (DumpRefOnly)
103
29
        NodeDumper.dumpDeclRef(Redecl);
104
119
      else
105
119
        Visit(Redecl);
106
148
      DumpedAny = true;
107
148
      break;
108
23
    case TSK_ExplicitSpecialization:
109
23
      break;
110
184
    }
111
184
  }
112
113
  // Ensure we dump at least one decl for each specialization.
114
182
  if (!DumpedAny)
115
36
    NodeDumper.dumpDeclRef(D);
116
182
}
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
547
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
547
  dumpTemplateParameters(D->getTemplateParameters());
121
122
547
  Visit(D->getTemplatedDecl());
123
124
547
  if (GetTraversalKind() == TK_AsIs) {
125
547
    for (const auto *Child : D->specializations())
126
358
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
358
                                     !D->isCanonicalDecl());
128
547
  }
129
547
}
void clang::ASTDumper::dumpTemplateDecl<clang::FunctionTemplateDecl>(clang::FunctionTemplateDecl const*, bool)
Line
Count
Source
119
333
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
333
  dumpTemplateParameters(D->getTemplateParameters());
121
122
333
  Visit(D->getTemplatedDecl());
123
124
333
  if (GetTraversalKind() == TK_AsIs) {
125
333
    for (const auto *Child : D->specializations())
126
173
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
173
                                     !D->isCanonicalDecl());
128
333
  }
129
333
}
void clang::ASTDumper::dumpTemplateDecl<clang::ClassTemplateDecl>(clang::ClassTemplateDecl const*, bool)
Line
Count
Source
119
209
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
120
209
  dumpTemplateParameters(D->getTemplateParameters());
121
122
209
  Visit(D->getTemplatedDecl());
123
124
209
  if (GetTraversalKind() == TK_AsIs) {
125
209
    for (const auto *Child : D->specializations())
126
182
      dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
127
182
                                     !D->isCanonicalDecl());
128
209
  }
129
209
}
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
333
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
333
  dumpTemplateDecl(D, true);
136
333
}
137
138
209
void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
139
209
  dumpTemplateDecl(D, false);
140
209
}
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
26
                                     const ASTContext &Context) const {
163
26
  ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
164
26
  Dumper.Visit(*this);
165
26
}
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.76k
                                 ASTDumpOutputFormat Format) const {
182
1.76k
  ASTContext &Ctx = getASTContext();
183
1.76k
  const SourceManager &SM = Ctx.getSourceManager();
184
185
1.76k
  if (ADOF_JSON == Format) {
186
164
    JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
187
164
                 &Ctx.getCommentCommandTraits());
188
164
    (void)Deserialize; // FIXME?
189
164
    P.Visit(this);
190
1.60k
  } else {
191
1.60k
    ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
192
1.60k
    P.setDeserialize(Deserialize);
193
1.60k
    P.Visit(this);
194
1.60k
  }
195
1.76k
}
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
}