clang 23.0.0git
ASTConsumers.cpp
Go to the documentation of this file.
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
21#include "llvm/Support/Timer.h"
22#include "llvm/Support/raw_ostream.h"
23using namespace clang;
24
25//===----------------------------------------------------------------------===//
26/// ASTPrinter - Pretty-printer and dumper of ASTs
27
28namespace {
29 class ASTPrinter : public ASTConsumer,
30 public RecursiveASTVisitor<ASTPrinter> {
31 typedef RecursiveASTVisitor<ASTPrinter> base;
32
33 public:
34 enum Kind { DumpFull, Dump, Print, None };
35 ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
36 ASTDumpOutputFormat Format, StringRef FilterString,
37 bool DumpLookups = false, bool DumpDeclTypes = false)
38 : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
39 OutputKind(K), OutputFormat(Format), FilterString(FilterString),
40 DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}
41
42 ASTPrinter(raw_ostream &Out, Kind K, ASTDumpOutputFormat Format,
43 StringRef FilterString, bool DumpLookups = false,
44 bool DumpDeclTypes = false)
45 : Out(Out), OwnedOut(nullptr), OutputKind(K), OutputFormat(Format),
46 FilterString(FilterString), DumpLookups(DumpLookups),
47 DumpDeclTypes(DumpDeclTypes) {}
48
49 void HandleTranslationUnit(ASTContext &Context) override {
50 TranslationUnitDecl *D = Context.getTranslationUnitDecl();
51
52 if (FilterString.empty())
53 return print(D);
54
55 TraverseDecl(D);
56 }
57
58 bool shouldWalkTypesOfTypeLocs() const { return false; }
59
60 bool TraverseDecl(Decl *D) {
61 if (D && filterMatches(D)) {
62 bool ShowColors = Out.has_colors();
63 if (ShowColors)
64 Out.changeColor(raw_ostream::BLUE);
65
66 if (OutputFormat == ADOF_Default)
67 Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
68 << ":\n";
69
70 if (ShowColors)
71 Out.resetColor();
72 print(D);
73 Out << "\n";
74 // Don't traverse child nodes to avoid output duplication.
75 return true;
76 }
77 return base::TraverseDecl(D);
78 }
79
80 private:
81 std::string getName(Decl *D) {
82 if (isa<NamedDecl>(D))
83 return cast<NamedDecl>(D)->getQualifiedNameAsString();
84 return "";
85 }
86 bool filterMatches(Decl *D) {
87 return getName(D).find(FilterString) != std::string::npos;
88 }
89 void print(Decl *D) {
90 if (DumpLookups) {
91 if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
92 if (DC == DC->getPrimaryContext())
93 DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
94 else
95 Out << "Lookup map is in primary DeclContext "
96 << DC->getPrimaryContext() << "\n";
97 } else
98 Out << "Not a DeclContext\n";
99 } else if (OutputKind == Print) {
100 PrintingPolicy Policy(D->getASTContext().getLangOpts());
101 Policy.IncludeTagDefinition = true;
102 D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
103 } else if (OutputKind != None) {
104 D->dump(Out, OutputKind == DumpFull, OutputFormat);
105 }
106
107 if (DumpDeclTypes) {
108 Decl *InnerD = D;
109 if (auto *TD = dyn_cast<TemplateDecl>(D))
110 if (Decl *TempD = TD->getTemplatedDecl())
111 InnerD = TempD;
112
113 // FIXME: Support OutputFormat in type dumping.
114 // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
115 if (auto *VD = dyn_cast<ValueDecl>(InnerD))
116 VD->getType().dump(Out, VD->getASTContext());
117 if (auto *TD = dyn_cast<TypeDecl>(InnerD)) {
118 const ASTContext &Ctx = TD->getASTContext();
119 Ctx.getTypeDeclType(TD)->dump(Out, Ctx);
120 }
121 }
122 }
123
124 raw_ostream &Out;
125 std::unique_ptr<raw_ostream> OwnedOut;
126
127 /// How to output individual declarations.
128 Kind OutputKind;
129
130 /// What format should the output take?
131 ASTDumpOutputFormat OutputFormat;
132
133 /// Which declarations or DeclContexts to display.
134 std::string FilterString;
135
136 /// Whether the primary output is lookup results or declarations. Individual
137 /// results will be output with a format determined by OutputKind. This is
138 /// incompatible with OutputKind == Print.
139 bool DumpLookups;
140
141 /// Whether to dump the type for each declaration dumped.
142 bool DumpDeclTypes;
143 };
144
145 class ASTDeclNodeLister : public ASTConsumer,
147 public:
148 ASTDeclNodeLister(raw_ostream *Out = nullptr)
149 : Out(Out ? *Out : llvm::outs()) {
150 ShouldWalkTypesOfTypeLocs = false;
151 }
152
153 void HandleTranslationUnit(ASTContext &Context) override {
154 TraverseDecl(Context.getTranslationUnitDecl());
155 }
156
157 bool VisitNamedDecl(NamedDecl *D) override {
158 D->printQualifiedName(Out);
159 Out << '\n';
160 return true;
161 }
162
163 private:
164 raw_ostream &Out;
165 };
166} // end anonymous namespace
167
168std::unique_ptr<ASTConsumer>
169clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
170 StringRef FilterString) {
171 return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
172 ADOF_Default, FilterString);
173}
174
175std::unique_ptr<ASTConsumer>
176clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
177 bool DumpDecls, bool Deserialize, bool DumpLookups,
178 bool DumpDeclTypes, ASTDumpOutputFormat Format) {
179 assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
180 return std::make_unique<ASTPrinter>(
181 std::move(Out),
182 Deserialize ? ASTPrinter::DumpFull
183 : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,
184 Format, FilterString, DumpLookups, DumpDeclTypes);
185}
186
187std::unique_ptr<ASTConsumer>
188clang::CreateASTDumper(raw_ostream &Out, StringRef FilterString, bool DumpDecls,
189 bool Deserialize, bool DumpLookups, bool DumpDeclTypes,
190 ASTDumpOutputFormat Format) {
191 assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
192 return std::make_unique<ASTPrinter>(Out,
193 Deserialize ? ASTPrinter::DumpFull
194 : DumpDecls ? ASTPrinter::Dump
195 : ASTPrinter::None,
196 Format, FilterString, DumpLookups,
197 DumpDeclTypes);
198}
199
200std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
201 return std::make_unique<ASTDeclNodeLister>(nullptr);
202}
203
204//===----------------------------------------------------------------------===//
205/// ASTViewer - AST Visualization
206
207namespace {
208class ASTViewer : public ASTConsumer {
209 ASTContext *Context = nullptr;
210
211public:
212 void Initialize(ASTContext &Context) override { this->Context = &Context; }
213
214 bool HandleTopLevelDecl(DeclGroupRef D) override {
215 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
216 HandleTopLevelSingleDecl(*I);
217 return true;
218 }
219
220 void HandleTopLevelSingleDecl(Decl *D);
221};
222}
223
224void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
226 D->print(llvm::errs());
227
228 if (Stmt *Body = D->getBody()) {
229 llvm::errs() << '\n';
230 Body->viewAST();
231 llvm::errs() << '\n';
232 }
233 }
234}
235
236std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
237 return std::make_unique<ASTViewer>();
238}
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
static void print(llvm::raw_ostream &OS, const T &V, const Context &Ctx, QualType Ty)
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
Definition ASTConsumer.h:35
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
TranslationUnitDecl * getTranslationUnitDecl() const
const LangOptions & getLangOpts() const
Definition ASTContext.h:965
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
iterator begin()
Definition DeclGroup.h:95
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition DeclBase.h:1104
void dump() const
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition Decl.cpp:1688
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
void dump() const
StringRef getName(const HeaderType T)
Definition HeaderFile.h:38
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
ASTDumpOutputFormat
Used to specify the format for printing AST dump information.
bool isa(CodeGen::Address addr)
Definition Address.h:330
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
std::unique_ptr< ASTConsumer > CreateASTDumper(std::unique_ptr< raw_ostream > OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, bool DumpDeclTypes, ASTDumpOutputFormat Format)
std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)
std::unique_ptr< ASTConsumer > CreateASTViewer()
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
U cast(CodeGen::Address addr)
Definition Address.h:327