Coverage Report

Created: 2022-05-14 11:35

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Frontend/ASTConsumers.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
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
// AST Consumer Implementations.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Frontend/ASTConsumers.h"
14
#include "clang/AST/AST.h"
15
#include "clang/AST/ASTConsumer.h"
16
#include "clang/AST/ASTContext.h"
17
#include "clang/AST/PrettyPrinter.h"
18
#include "clang/AST/RecordLayout.h"
19
#include "clang/AST/RecursiveASTVisitor.h"
20
#include "clang/Basic/Diagnostic.h"
21
#include "clang/Basic/SourceManager.h"
22
#include "llvm/Support/Path.h"
23
#include "llvm/Support/Timer.h"
24
#include "llvm/Support/raw_ostream.h"
25
using namespace clang;
26
27
//===----------------------------------------------------------------------===//
28
/// ASTPrinter - Pretty-printer and dumper of ASTs
29
30
namespace {
31
  class ASTPrinter : public ASTConsumer,
32
                     public RecursiveASTVisitor<ASTPrinter> {
33
    typedef RecursiveASTVisitor<ASTPrinter> base;
34
35
  public:
36
    enum Kind { DumpFull, Dump, Print, None };
37
    ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
38
               ASTDumpOutputFormat Format, StringRef FilterString,
39
               bool DumpLookups = false, bool DumpDeclTypes = false)
40
        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
41
          OutputKind(K), OutputFormat(Format), FilterString(FilterString),
42
1.16k
          DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
43
44
1.17k
    void HandleTranslationUnit(ASTContext &Context) override {
45
1.17k
      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
46
47
1.17k
      if (FilterString.empty())
48
1.05k
        return print(D);
49
50
124
      TraverseDecl(D);
51
124
    }
52
53
2.17k
    bool shouldWalkTypesOfTypeLocs() const { return false; }
54
55
3.96k
    bool TraverseDecl(Decl *D) {
56
3.96k
      if (D && 
filterMatches(D)3.95k
) {
57
746
        bool ShowColors = Out.has_colors();
58
746
        if (ShowColors)
59
0
          Out.changeColor(raw_ostream::BLUE);
60
61
746
        if (OutputFormat == ADOF_Default)
62
643
          Out << (OutputKind != Print ? "Dumping " : 
"Printing "0
) << getName(D)
63
643
              << ":\n";
64
65
746
        if (ShowColors)
66
0
          Out.resetColor();
67
746
        print(D);
68
746
        Out << "\n";
69
        // Don't traverse child nodes to avoid output duplication.
70
746
        return true;
71
746
      }
72
3.21k
      return base::TraverseDecl(D);
73
3.96k
    }
74
75
  private:
76
4.59k
    std::string getName(Decl *D) {
77
4.59k
      if (isa<NamedDecl>(D))
78
4.37k
        return cast<NamedDecl>(D)->getQualifiedNameAsString();
79
218
      return "";
80
4.59k
    }
81
3.95k
    bool filterMatches(Decl *D) {
82
3.95k
      return getName(D).find(FilterString) != std::string::npos;
83
3.95k
    }
84
1.79k
    void print(Decl *D) {
85
1.79k
      if (DumpLookups) {
86
17
        if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
87
13
          if (DC == DC->getPrimaryContext())
88
7
            DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
89
6
          else
90
6
            Out << "Lookup map is in primary DeclContext "
91
6
                << DC->getPrimaryContext() << "\n";
92
13
        } else
93
4
          Out << "Not a DeclContext\n";
94
1.78k
      } else if (OutputKind == Print) {
95
613
        PrintingPolicy Policy(D->getASTContext().getLangOpts());
96
613
        D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
97
1.16k
      } else if (OutputKind != None) {
98
1.16k
        D->dump(Out, OutputKind == DumpFull, OutputFormat);
99
1.16k
      }
100
101
1.79k
      if (DumpDeclTypes) {
102
13
        Decl *InnerD = D;
103
13
        if (auto *TD = dyn_cast<TemplateDecl>(D))
104
13
          InnerD = TD->getTemplatedDecl();
105
106
        // FIXME: Support OutputFormat in type dumping.
107
        // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
108
13
        if (auto *VD = dyn_cast<ValueDecl>(InnerD))
109
13
          VD->getType().dump(Out, VD->getASTContext());
110
13
        if (auto *TD = dyn_cast<TypeDecl>(InnerD))
111
0
          TD->getTypeForDecl()->dump(Out, TD->getASTContext());
112
13
      }
113
1.79k
    }
114
115
    raw_ostream &Out;
116
    std::unique_ptr<raw_ostream> OwnedOut;
117
118
    /// How to output individual declarations.
119
    Kind OutputKind;
120
121
    /// What format should the output take?
122
    ASTDumpOutputFormat OutputFormat;
123
124
    /// Which declarations or DeclContexts to display.
125
    std::string FilterString;
126
127
    /// Whether the primary output is lookup results or declarations. Individual
128
    /// results will be output with a format determined by OutputKind. This is
129
    /// incompatible with OutputKind == Print.
130
    bool DumpLookups;
131
132
    /// Whether to dump the type for each declaration dumped.
133
    bool DumpDeclTypes;
134
  };
135
136
  class ASTDeclNodeLister : public ASTConsumer,
137
                     public RecursiveASTVisitor<ASTDeclNodeLister> {
138
  public:
139
    ASTDeclNodeLister(raw_ostream *Out = nullptr)
140
1
        : Out(Out ? *Out : llvm::outs()) {}
141
142
1
    void HandleTranslationUnit(ASTContext &Context) override {
143
1
      TraverseDecl(Context.getTranslationUnitDecl());
144
1
    }
145
146
4
    bool shouldWalkTypesOfTypeLocs() const { return false; }
147
148
10
    bool VisitNamedDecl(NamedDecl *D) {
149
10
      D->printQualifiedName(Out);
150
10
      Out << '\n';
151
10
      return true;
152
10
    }
153
154
  private:
155
    raw_ostream &Out;
156
  };
157
} // end anonymous namespace
158
159
std::unique_ptr<ASTConsumer>
160
clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
161
613
                        StringRef FilterString) {
162
613
  return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
163
613
                                       ADOF_Default, FilterString);
164
613
}
165
166
std::unique_ptr<ASTConsumer>
167
clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
168
                       bool DumpDecls, bool Deserialize, bool DumpLookups,
169
547
                       bool DumpDeclTypes, ASTDumpOutputFormat Format) {
170
547
  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
171
0
  return std::make_unique<ASTPrinter>(
172
547
      std::move(Out),
173
547
      Deserialize ? 
ASTPrinter::DumpFull81
174
547
                  : 
DumpDecls466
?
ASTPrinter::Dump461
:
ASTPrinter::None5
,
175
547
      Format, FilterString, DumpLookups, DumpDeclTypes);
176
547
}
177
178
1
std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
179
1
  return std::make_unique<ASTDeclNodeLister>(nullptr);
180
1
}
181
182
//===----------------------------------------------------------------------===//
183
/// ASTViewer - AST Visualization
184
185
namespace {
186
  class ASTViewer : public ASTConsumer {
187
    ASTContext *Context;
188
  public:
189
0
    void Initialize(ASTContext &Context) override {
190
0
      this->Context = &Context;
191
0
    }
192
193
0
    bool HandleTopLevelDecl(DeclGroupRef D) override {
194
0
      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
195
0
        HandleTopLevelSingleDecl(*I);
196
0
      return true;
197
0
    }
198
199
    void HandleTopLevelSingleDecl(Decl *D);
200
  };
201
}
202
203
0
void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
204
0
  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
205
0
    D->print(llvm::errs());
206
207
0
    if (Stmt *Body = D->getBody()) {
208
0
      llvm::errs() << '\n';
209
0
      Body->viewAST();
210
0
      llvm::errs() << '\n';
211
0
    }
212
0
  }
213
0
}
214
215
0
std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
216
0
  return std::make_unique<ASTViewer>();
217
0
}