Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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
7
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
7
36
7
    bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
37
7
38
7
    auto Range = getDeserialize()
39
7
                     ? 
Primary->lookups()0
40
7
                     : Primary->noload_lookups(/*PreserveInternalState=*/true);
41
140
    for (auto I = Range.begin(), E = Range.end(); I != E; 
++I133
) {
42
133
      DeclarationName Name = I.getLookupName();
43
133
      DeclContextLookupResult R = *I;
44
133
45
133
      NodeDumper.AddChild([=] {
46
133
        OS << "DeclarationName ";
47
133
        {
48
133
          ColorScope Color(OS, ShowColors, DeclNameColor);
49
133
          OS << '\'' << Name << '\'';
50
133
        }
51
133
52
133
        for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
53
303
             RI != RE; 
++RI170
) {
54
170
          NodeDumper.AddChild([=] {
55
170
            NodeDumper.dumpBareDeclRef(*RI);
56
170
57
170
            if ((*RI)->isHidden())
58
7
              OS << " hidden";
59
170
60
170
            // If requested, dump the redecl chain for this lookup.
61
170
            if (DumpDecls) {
62
2
              // 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
170
          });
71
170
        }
72
133
      });
73
133
    }
74
7
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
116
                                               bool DumpRefOnly) {
88
116
  bool DumpedAny = false;
89
191
  for (const auto *RedeclWithBadType : D->redecls()) {
90
191
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
191
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
191
    // us TagDecls, and should give CXXRecordDecls).
93
191
    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
94
191
    if (!Redecl) {
95
69
      // Found the injected-class-name for a class template. This will be dumped
96
69
      // as part of its surrounding class so we don't need to dump it here.
97
69
      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
98
69
             "expected an injected-class-name");
99
69
      continue;
100
69
    }
101
122
102
122
    switch (Redecl->getTemplateSpecializationKind()) {
103
122
    case TSK_ExplicitInstantiationDeclaration:
104
15
    case TSK_ExplicitInstantiationDefinition:
105
15
      if (!DumpExplicitInst)
106
10
        break;
107
5
      LLVM_FALLTHROUGH;
108
101
    case TSK_Undeclared:
109
101
    case TSK_ImplicitInstantiation:
110
101
      if (DumpRefOnly)
111
6
        NodeDumper.dumpDeclRef(Redecl);
112
95
      else
113
95
        Visit(Redecl);
114
101
      DumpedAny = true;
115
101
      break;
116
101
    case TSK_ExplicitSpecialization:
117
11
      break;
118
122
    }
119
122
  }
120
116
121
116
  // Ensure we dump at least one decl for each specialization.
122
116
  if (!DumpedAny)
123
19
    NodeDumper.dumpDeclRef(D);
124
116
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::FunctionDecl>(clang::FunctionDecl const*, bool, bool)
Line
Count
Source
87
37
                                               bool DumpRefOnly) {
88
37
  bool DumpedAny = false;
89
39
  for (const auto *RedeclWithBadType : D->redecls()) {
90
39
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
39
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
39
    // us TagDecls, and should give CXXRecordDecls).
93
39
    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
94
39
    if (!Redecl) {
95
0
      // Found the injected-class-name for a class template. This will be dumped
96
0
      // as part of its surrounding class so we don't need to dump it here.
97
0
      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
98
0
             "expected an injected-class-name");
99
0
      continue;
100
0
    }
101
39
102
39
    switch (Redecl->getTemplateSpecializationKind()) {
103
39
    case TSK_ExplicitInstantiationDeclaration:
104
5
    case TSK_ExplicitInstantiationDefinition:
105
5
      if (!DumpExplicitInst)
106
0
        break;
107
5
      LLVM_FALLTHROUGH;
108
35
    case TSK_Undeclared:
109
35
    case TSK_ImplicitInstantiation:
110
35
      if (DumpRefOnly)
111
1
        NodeDumper.dumpDeclRef(Redecl);
112
34
      else
113
34
        Visit(Redecl);
114
35
      DumpedAny = true;
115
35
      break;
116
35
    case TSK_ExplicitSpecialization:
117
4
      break;
118
39
    }
119
39
  }
120
37
121
37
  // Ensure we dump at least one decl for each specialization.
122
37
  if (!DumpedAny)
123
2
    NodeDumper.dumpDeclRef(D);
124
37
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::ClassTemplateSpecializationDecl>(clang::ClassTemplateSpecializationDecl const*, bool, bool)
Line
Count
Source
87
77
                                               bool DumpRefOnly) {
88
77
  bool DumpedAny = false;
89
148
  for (const auto *RedeclWithBadType : D->redecls()) {
90
148
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
148
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
148
    // us TagDecls, and should give CXXRecordDecls).
93
148
    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
94
148
    if (!Redecl) {
95
69
      // Found the injected-class-name for a class template. This will be dumped
96
69
      // as part of its surrounding class so we don't need to dump it here.
97
69
      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
98
69
             "expected an injected-class-name");
99
69
      continue;
100
69
    }
101
79
102
79
    switch (Redecl->getTemplateSpecializationKind()) {
103
79
    case TSK_ExplicitInstantiationDeclaration:
104
10
    case TSK_ExplicitInstantiationDefinition:
105
10
      if (!DumpExplicitInst)
106
10
        break;
107
0
      LLVM_FALLTHROUGH;
108
62
    case TSK_Undeclared:
109
62
    case TSK_ImplicitInstantiation:
110
62
      if (DumpRefOnly)
111
3
        NodeDumper.dumpDeclRef(Redecl);
112
59
      else
113
59
        Visit(Redecl);
114
62
      DumpedAny = true;
115
62
      break;
116
62
    case TSK_ExplicitSpecialization:
117
7
      break;
118
79
    }
119
79
  }
120
77
121
77
  // Ensure we dump at least one decl for each specialization.
122
77
  if (!DumpedAny)
123
17
    NodeDumper.dumpDeclRef(D);
124
77
}
void clang::ASTDumper::dumpTemplateDeclSpecialization<clang::VarTemplateSpecializationDecl>(clang::VarTemplateSpecializationDecl const*, bool, bool)
Line
Count
Source
87
2
                                               bool DumpRefOnly) {
88
2
  bool DumpedAny = false;
89
4
  for (const auto *RedeclWithBadType : D->redecls()) {
90
4
    // FIXME: The redecls() range sometimes has elements of a less-specific
91
4
    // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
92
4
    // us TagDecls, and should give CXXRecordDecls).
93
4
    auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
94
4
    if (!Redecl) {
95
0
      // Found the injected-class-name for a class template. This will be dumped
96
0
      // as part of its surrounding class so we don't need to dump it here.
97
0
      assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
98
0
             "expected an injected-class-name");
99
0
      continue;
100
0
    }
101
4
102
4
    switch (Redecl->getTemplateSpecializationKind()) {
103
4
    case TSK_ExplicitInstantiationDeclaration:
104
0
    case TSK_ExplicitInstantiationDefinition:
105
0
      if (!DumpExplicitInst)
106
0
        break;
107
0
      LLVM_FALLTHROUGH;
108
4
    case TSK_Undeclared:
109
4
    case TSK_ImplicitInstantiation:
110
4
      if (DumpRefOnly)
111
2
        NodeDumper.dumpDeclRef(Redecl);
112
2
      else
113
2
        Visit(Redecl);
114
4
      DumpedAny = true;
115
4
      break;
116
4
    case TSK_ExplicitSpecialization:
117
0
      break;
118
4
    }
119
4
  }
120
2
121
2
  // Ensure we dump at least one decl for each specialization.
122
2
  if (!DumpedAny)
123
0
    NodeDumper.dumpDeclRef(D);
124
2
}
125
126
template <typename TemplateDecl>
127
223
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
128
223
  dumpTemplateParameters(D->getTemplateParameters());
129
223
130
223
  Visit(D->getTemplatedDecl());
131
223
132
223
  for (const auto *Child : D->specializations())
133
116
    dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
134
116
                                   !D->isCanonicalDecl());
135
223
}
void clang::ASTDumper::dumpTemplateDecl<clang::FunctionTemplateDecl>(clang::FunctionTemplateDecl const*, bool)
Line
Count
Source
127
105
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
128
105
  dumpTemplateParameters(D->getTemplateParameters());
129
105
130
105
  Visit(D->getTemplatedDecl());
131
105
132
105
  for (const auto *Child : D->specializations())
133
37
    dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
134
37
                                   !D->isCanonicalDecl());
135
105
}
void clang::ASTDumper::dumpTemplateDecl<clang::ClassTemplateDecl>(clang::ClassTemplateDecl const*, bool)
Line
Count
Source
127
114
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
128
114
  dumpTemplateParameters(D->getTemplateParameters());
129
114
130
114
  Visit(D->getTemplatedDecl());
131
114
132
114
  for (const auto *Child : D->specializations())
133
77
    dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
134
77
                                   !D->isCanonicalDecl());
135
114
}
void clang::ASTDumper::dumpTemplateDecl<clang::VarTemplateDecl>(clang::VarTemplateDecl const*, bool)
Line
Count
Source
127
4
void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
128
4
  dumpTemplateParameters(D->getTemplateParameters());
129
4
130
4
  Visit(D->getTemplatedDecl());
131
4
132
4
  for (const auto *Child : D->specializations())
133
2
    dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
134
2
                                   !D->isCanonicalDecl());
135
4
}
136
137
105
void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
138
105
  // FIXME: We don't add a declaration of a function template specialization
139
105
  // to its context when it's explicitly instantiated, so dump explicit
140
105
  // instantiations when we dump the template itself.
141
105
  dumpTemplateDecl(D, true);
142
105
}
143
144
114
void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
145
114
  dumpTemplateDecl(D, false);
146
114
}
147
148
4
void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
149
4
  dumpTemplateDecl(D, false);
150
4
}
151
152
//===----------------------------------------------------------------------===//
153
// Type method implementations
154
//===----------------------------------------------------------------------===//
155
156
0
void QualType::dump(const char *msg) const {
157
0
  if (msg)
158
0
    llvm::errs() << msg << ": ";
159
0
  dump();
160
0
}
161
162
0
LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); }
163
164
0
LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const {
165
0
  ASTDumper Dumper(OS, nullptr, nullptr);
166
0
  Dumper.Visit(*this);
167
0
}
168
169
0
LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); }
170
171
0
LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const {
172
0
  QualType(this, 0).dump(OS);
173
0
}
174
175
//===----------------------------------------------------------------------===//
176
// Decl method implementations
177
//===----------------------------------------------------------------------===//
178
179
18
LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
180
181
LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
182
966
                                 ASTDumpOutputFormat Format) const {
183
966
  ASTContext &Ctx = getASTContext();
184
966
  const SourceManager &SM = Ctx.getSourceManager();
185
966
186
966
  if (ADOF_JSON == Format) {
187
110
    JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
188
110
                 &Ctx.getCommentCommandTraits());
189
110
    (void)Deserialize; // FIXME?
190
110
    P.Visit(this);
191
856
  } else {
192
856
    ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM,
193
856
                SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
194
856
    P.setDeserialize(Deserialize);
195
856
    P.Visit(this);
196
856
  }
197
966
}
198
199
0
LLVM_DUMP_METHOD void Decl::dumpColor() const {
200
0
  const ASTContext &Ctx = getASTContext();
201
0
  ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(),
202
0
              &Ctx.getSourceManager(), /*ShowColors*/ true,
203
0
              Ctx.getPrintingPolicy());
204
0
  P.Visit(this);
205
0
}
206
207
0
LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
208
0
  dumpLookups(llvm::errs());
209
0
}
210
211
LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
212
                                               bool DumpDecls,
213
7
                                               bool Deserialize) const {
214
7
  const DeclContext *DC = this;
215
13
  while (!DC->isTranslationUnit())
216
6
    DC = DC->getParent();
217
7
  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
218
7
  const SourceManager &SM = Ctx.getSourceManager();
219
7
  ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(),
220
7
              SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy());
221
7
  P.setDeserialize(Deserialize);
222
7
  P.dumpLookups(this, DumpDecls);
223
7
}
224
225
//===----------------------------------------------------------------------===//
226
// Stmt method implementations
227
//===----------------------------------------------------------------------===//
228
229
0
LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const {
230
0
  dump(llvm::errs(), SM);
231
0
}
232
233
1
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const {
234
1
  ASTDumper P(OS, nullptr, &SM);
235
1
  P.Visit(this);
236
1
}
237
238
0
LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const {
239
0
  ASTDumper P(OS, nullptr, nullptr);
240
0
  P.Visit(this);
241
0
}
242
243
11
LLVM_DUMP_METHOD void Stmt::dump() const {
244
11
  ASTDumper P(llvm::errs(), nullptr, nullptr);
245
11
  P.Visit(this);
246
11
}
247
248
0
LLVM_DUMP_METHOD void Stmt::dumpColor() const {
249
0
  ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
250
0
  P.Visit(this);
251
0
}
252
253
//===----------------------------------------------------------------------===//
254
// Comment method implementations
255
//===----------------------------------------------------------------------===//
256
257
0
LLVM_DUMP_METHOD void Comment::dump() const {
258
0
  dump(llvm::errs(), nullptr, nullptr);
259
0
}
260
261
0
LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const {
262
0
  dump(llvm::errs(), &Context.getCommentCommandTraits(),
263
0
       &Context.getSourceManager());
264
0
}
265
266
void Comment::dump(raw_ostream &OS, const CommandTraits *Traits,
267
79
                   const SourceManager *SM) const {
268
79
  const FullComment *FC = dyn_cast<FullComment>(this);
269
79
  if (!FC)
270
0
    return;
271
79
  ASTDumper D(OS, Traits, SM);
272
79
  D.Visit(FC, FC);
273
79
}
274
275
0
LLVM_DUMP_METHOD void Comment::dumpColor() const {
276
0
  const FullComment *FC = dyn_cast<FullComment>(this);
277
0
  if (!FC)
278
0
    return;
279
0
  ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true);
280
0
  D.Visit(FC, FC);
281
0
}