Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/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)
40
        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
41
          OutputKind(K), OutputFormat(Format), FilterString(FilterString),
42
623
          DumpLookups(DumpLookups) {}
43
44
623
    void HandleTranslationUnit(ASTContext &Context) override {
45
623
      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
46
623
47
623
      if (FilterString.empty())
48
564
        return print(D);
49
59
50
59
      TraverseDecl(D);
51
59
    }
52
53
1.84k
    bool shouldWalkTypesOfTypeLocs() const { return false; }
54
55
2.77k
    bool TraverseDecl(Decl *D) {
56
2.77k
      if (D && 
filterMatches(D)2.76k
) {
57
514
        bool ShowColors = Out.has_colors();
58
514
        if (ShowColors)
59
0
          Out.changeColor(raw_ostream::BLUE);
60
514
        Out << (OutputKind != Print ? "Dumping " : 
"Printing "0
) << getName(D)
61
514
            << ":\n";
62
514
        if (ShowColors)
63
0
          Out.resetColor();
64
514
        print(D);
65
514
        Out << "\n";
66
514
        // Don't traverse child nodes to avoid output duplication.
67
514
        return true;
68
514
      }
69
2.26k
      return base::TraverseDecl(D);
70
2.26k
    }
71
72
  private:
73
3.28k
    std::string getName(Decl *D) {
74
3.28k
      if (isa<NamedDecl>(D))
75
3.13k
        return cast<NamedDecl>(D)->getQualifiedNameAsString();
76
148
      return "";
77
148
    }
78
2.76k
    bool filterMatches(Decl *D) {
79
2.76k
      return getName(D).find(FilterString) != std::string::npos;
80
2.76k
    }
81
1.07k
    void print(Decl *D) {
82
1.07k
      if (DumpLookups) {
83
17
        if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
84
13
          if (DC == DC->getPrimaryContext())
85
7
            DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
86
6
          else
87
6
            Out << "Lookup map is in primary DeclContext "
88
6
                << DC->getPrimaryContext() << "\n";
89
13
        } else
90
4
          Out << "Not a DeclContext\n";
91
1.06k
      } else if (OutputKind == Print) {
92
388
        PrintingPolicy Policy(D->getASTContext().getLangOpts());
93
388
        D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
94
673
      } else if (OutputKind != None)
95
673
        D->dump(Out, OutputKind == DumpFull, OutputFormat);
96
1.07k
    }
97
98
    raw_ostream &Out;
99
    std::unique_ptr<raw_ostream> OwnedOut;
100
101
    /// How to output individual declarations.
102
    Kind OutputKind;
103
104
    /// What format should the output take?
105
    ASTDumpOutputFormat OutputFormat;
106
107
    /// Which declarations or DeclContexts to display.
108
    std::string FilterString;
109
110
    /// Whether the primary output is lookup results or declarations. Individual
111
    /// results will be output with a format determined by OutputKind. This is
112
    /// incompatible with OutputKind == Print.
113
    bool DumpLookups;
114
  };
115
116
  class ASTDeclNodeLister : public ASTConsumer,
117
                     public RecursiveASTVisitor<ASTDeclNodeLister> {
118
  public:
119
    ASTDeclNodeLister(raw_ostream *Out = nullptr)
120
1
        : Out(Out ? *Out : llvm::outs()) {}
121
122
1
    void HandleTranslationUnit(ASTContext &Context) override {
123
1
      TraverseDecl(Context.getTranslationUnitDecl());
124
1
    }
125
126
4
    bool shouldWalkTypesOfTypeLocs() const { return false; }
127
128
10
    bool VisitNamedDecl(NamedDecl *D) {
129
10
      D->printQualifiedName(Out);
130
10
      Out << '\n';
131
10
      return true;
132
10
    }
133
134
  private:
135
    raw_ostream &Out;
136
  };
137
} // end anonymous namespace
138
139
std::unique_ptr<ASTConsumer>
140
clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
141
388
                        StringRef FilterString) {
142
388
  return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
143
388
                                       ADOF_Default, FilterString);
144
388
}
145
146
std::unique_ptr<ASTConsumer>
147
clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
148
                       bool DumpDecls, bool Deserialize, bool DumpLookups,
149
235
                       ASTDumpOutputFormat Format) {
150
235
  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
151
235
  return llvm::make_unique<ASTPrinter>(std::move(Out),
152
235
                                       Deserialize ? 
ASTPrinter::DumpFull5
:
153
235
                                       
DumpDecls 230
?
ASTPrinter::Dump225
:
154
230
                                       
ASTPrinter::None5
, Format,
155
235
                                       FilterString, DumpLookups);
156
235
}
157
158
1
std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
159
1
  return llvm::make_unique<ASTDeclNodeLister>(nullptr);
160
1
}
161
162
//===----------------------------------------------------------------------===//
163
/// ASTViewer - AST Visualization
164
165
namespace {
166
  class ASTViewer : public ASTConsumer {
167
    ASTContext *Context;
168
  public:
169
0
    void Initialize(ASTContext &Context) override {
170
0
      this->Context = &Context;
171
0
    }
172
173
0
    bool HandleTopLevelDecl(DeclGroupRef D) override {
174
0
      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
175
0
        HandleTopLevelSingleDecl(*I);
176
0
      return true;
177
0
    }
178
179
    void HandleTopLevelSingleDecl(Decl *D);
180
  };
181
}
182
183
0
void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
184
0
  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
185
0
    D->print(llvm::errs());
186
0
187
0
    if (Stmt *Body = D->getBody()) {
188
0
      llvm::errs() << '\n';
189
0
      Body->viewAST();
190
0
      llvm::errs() << '\n';
191
0
    }
192
0
  }
193
0
}
194
195
0
std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
196
0
  return llvm::make_unique<ASTViewer>();
197
0
}