Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp
35234 views
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
DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
43
44
void HandleTranslationUnit(ASTContext &Context) override {
45
TranslationUnitDecl *D = Context.getTranslationUnitDecl();
46
47
if (FilterString.empty())
48
return print(D);
49
50
TraverseDecl(D);
51
}
52
53
bool shouldWalkTypesOfTypeLocs() const { return false; }
54
55
bool TraverseDecl(Decl *D) {
56
if (D && filterMatches(D)) {
57
bool ShowColors = Out.has_colors();
58
if (ShowColors)
59
Out.changeColor(raw_ostream::BLUE);
60
61
if (OutputFormat == ADOF_Default)
62
Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
63
<< ":\n";
64
65
if (ShowColors)
66
Out.resetColor();
67
print(D);
68
Out << "\n";
69
// Don't traverse child nodes to avoid output duplication.
70
return true;
71
}
72
return base::TraverseDecl(D);
73
}
74
75
private:
76
std::string getName(Decl *D) {
77
if (isa<NamedDecl>(D))
78
return cast<NamedDecl>(D)->getQualifiedNameAsString();
79
return "";
80
}
81
bool filterMatches(Decl *D) {
82
return getName(D).find(FilterString) != std::string::npos;
83
}
84
void print(Decl *D) {
85
if (DumpLookups) {
86
if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
87
if (DC == DC->getPrimaryContext())
88
DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
89
else
90
Out << "Lookup map is in primary DeclContext "
91
<< DC->getPrimaryContext() << "\n";
92
} else
93
Out << "Not a DeclContext\n";
94
} else if (OutputKind == Print) {
95
PrintingPolicy Policy(D->getASTContext().getLangOpts());
96
D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
97
} else if (OutputKind != None) {
98
D->dump(Out, OutputKind == DumpFull, OutputFormat);
99
}
100
101
if (DumpDeclTypes) {
102
Decl *InnerD = D;
103
if (auto *TD = dyn_cast<TemplateDecl>(D))
104
InnerD = TD->getTemplatedDecl();
105
106
// FIXME: Support OutputFormat in type dumping.
107
// FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
108
if (auto *VD = dyn_cast<ValueDecl>(InnerD))
109
VD->getType().dump(Out, VD->getASTContext());
110
if (auto *TD = dyn_cast<TypeDecl>(InnerD))
111
TD->getTypeForDecl()->dump(Out, TD->getASTContext());
112
}
113
}
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
: Out(Out ? *Out : llvm::outs()) {}
141
142
void HandleTranslationUnit(ASTContext &Context) override {
143
TraverseDecl(Context.getTranslationUnitDecl());
144
}
145
146
bool shouldWalkTypesOfTypeLocs() const { return false; }
147
148
bool VisitNamedDecl(NamedDecl *D) {
149
D->printQualifiedName(Out);
150
Out << '\n';
151
return true;
152
}
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
StringRef FilterString) {
162
return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
163
ADOF_Default, FilterString);
164
}
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
bool DumpDeclTypes, ASTDumpOutputFormat Format) {
170
assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
171
return std::make_unique<ASTPrinter>(
172
std::move(Out),
173
Deserialize ? ASTPrinter::DumpFull
174
: DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,
175
Format, FilterString, DumpLookups, DumpDeclTypes);
176
}
177
178
std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
179
return std::make_unique<ASTDeclNodeLister>(nullptr);
180
}
181
182
//===----------------------------------------------------------------------===//
183
/// ASTViewer - AST Visualization
184
185
namespace {
186
class ASTViewer : public ASTConsumer {
187
ASTContext *Context = nullptr;
188
189
public:
190
void Initialize(ASTContext &Context) override { this->Context = &Context; }
191
192
bool HandleTopLevelDecl(DeclGroupRef D) override {
193
for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
194
HandleTopLevelSingleDecl(*I);
195
return true;
196
}
197
198
void HandleTopLevelSingleDecl(Decl *D);
199
};
200
}
201
202
void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
203
if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
204
D->print(llvm::errs());
205
206
if (Stmt *Body = D->getBody()) {
207
llvm::errs() << '\n';
208
Body->viewAST();
209
llvm::errs() << '\n';
210
}
211
}
212
}
213
214
std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
215
return std::make_unique<ASTViewer>();
216
}
217
218