1*67e74705SXin Li //===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // AST Consumer Implementations.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li
14*67e74705SXin Li #include "clang/Frontend/ASTConsumers.h"
15*67e74705SXin Li #include "clang/AST/AST.h"
16*67e74705SXin Li #include "clang/AST/ASTConsumer.h"
17*67e74705SXin Li #include "clang/AST/ASTContext.h"
18*67e74705SXin Li #include "clang/AST/PrettyPrinter.h"
19*67e74705SXin Li #include "clang/AST/RecordLayout.h"
20*67e74705SXin Li #include "clang/AST/RecursiveASTVisitor.h"
21*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
22*67e74705SXin Li #include "clang/Basic/FileManager.h"
23*67e74705SXin Li #include "clang/Basic/SourceManager.h"
24*67e74705SXin Li #include "llvm/Support/Path.h"
25*67e74705SXin Li #include "llvm/Support/Timer.h"
26*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
27*67e74705SXin Li using namespace clang;
28*67e74705SXin Li
29*67e74705SXin Li //===----------------------------------------------------------------------===//
30*67e74705SXin Li /// ASTPrinter - Pretty-printer and dumper of ASTs
31*67e74705SXin Li
32*67e74705SXin Li namespace {
33*67e74705SXin Li class ASTPrinter : public ASTConsumer,
34*67e74705SXin Li public RecursiveASTVisitor<ASTPrinter> {
35*67e74705SXin Li typedef RecursiveASTVisitor<ASTPrinter> base;
36*67e74705SXin Li
37*67e74705SXin Li public:
ASTPrinter(raw_ostream * Out=nullptr,bool Dump=false,StringRef FilterString="",bool DumpLookups=false)38*67e74705SXin Li ASTPrinter(raw_ostream *Out = nullptr, bool Dump = false,
39*67e74705SXin Li StringRef FilterString = "", bool DumpLookups = false)
40*67e74705SXin Li : Out(Out ? *Out : llvm::outs()), Dump(Dump),
41*67e74705SXin Li FilterString(FilterString), DumpLookups(DumpLookups) {}
42*67e74705SXin Li
HandleTranslationUnit(ASTContext & Context)43*67e74705SXin Li void HandleTranslationUnit(ASTContext &Context) override {
44*67e74705SXin Li TranslationUnitDecl *D = Context.getTranslationUnitDecl();
45*67e74705SXin Li
46*67e74705SXin Li if (FilterString.empty())
47*67e74705SXin Li return print(D);
48*67e74705SXin Li
49*67e74705SXin Li TraverseDecl(D);
50*67e74705SXin Li }
51*67e74705SXin Li
shouldWalkTypesOfTypeLocs() const52*67e74705SXin Li bool shouldWalkTypesOfTypeLocs() const { return false; }
53*67e74705SXin Li
TraverseDecl(Decl * D)54*67e74705SXin Li bool TraverseDecl(Decl *D) {
55*67e74705SXin Li if (D && filterMatches(D)) {
56*67e74705SXin Li bool ShowColors = Out.has_colors();
57*67e74705SXin Li if (ShowColors)
58*67e74705SXin Li Out.changeColor(raw_ostream::BLUE);
59*67e74705SXin Li Out << ((Dump || DumpLookups) ? "Dumping " : "Printing ") << getName(D)
60*67e74705SXin Li << ":\n";
61*67e74705SXin Li if (ShowColors)
62*67e74705SXin Li Out.resetColor();
63*67e74705SXin Li print(D);
64*67e74705SXin Li Out << "\n";
65*67e74705SXin Li // Don't traverse child nodes to avoid output duplication.
66*67e74705SXin Li return true;
67*67e74705SXin Li }
68*67e74705SXin Li return base::TraverseDecl(D);
69*67e74705SXin Li }
70*67e74705SXin Li
71*67e74705SXin Li private:
getName(Decl * D)72*67e74705SXin Li std::string getName(Decl *D) {
73*67e74705SXin Li if (isa<NamedDecl>(D))
74*67e74705SXin Li return cast<NamedDecl>(D)->getQualifiedNameAsString();
75*67e74705SXin Li return "";
76*67e74705SXin Li }
filterMatches(Decl * D)77*67e74705SXin Li bool filterMatches(Decl *D) {
78*67e74705SXin Li return getName(D).find(FilterString) != std::string::npos;
79*67e74705SXin Li }
print(Decl * D)80*67e74705SXin Li void print(Decl *D) {
81*67e74705SXin Li if (DumpLookups) {
82*67e74705SXin Li if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
83*67e74705SXin Li if (DC == DC->getPrimaryContext())
84*67e74705SXin Li DC->dumpLookups(Out, Dump);
85*67e74705SXin Li else
86*67e74705SXin Li Out << "Lookup map is in primary DeclContext "
87*67e74705SXin Li << DC->getPrimaryContext() << "\n";
88*67e74705SXin Li } else
89*67e74705SXin Li Out << "Not a DeclContext\n";
90*67e74705SXin Li } else if (Dump)
91*67e74705SXin Li D->dump(Out);
92*67e74705SXin Li else
93*67e74705SXin Li D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
94*67e74705SXin Li }
95*67e74705SXin Li
96*67e74705SXin Li raw_ostream &Out;
97*67e74705SXin Li bool Dump;
98*67e74705SXin Li std::string FilterString;
99*67e74705SXin Li bool DumpLookups;
100*67e74705SXin Li };
101*67e74705SXin Li
102*67e74705SXin Li class ASTDeclNodeLister : public ASTConsumer,
103*67e74705SXin Li public RecursiveASTVisitor<ASTDeclNodeLister> {
104*67e74705SXin Li public:
ASTDeclNodeLister(raw_ostream * Out=nullptr)105*67e74705SXin Li ASTDeclNodeLister(raw_ostream *Out = nullptr)
106*67e74705SXin Li : Out(Out ? *Out : llvm::outs()) {}
107*67e74705SXin Li
HandleTranslationUnit(ASTContext & Context)108*67e74705SXin Li void HandleTranslationUnit(ASTContext &Context) override {
109*67e74705SXin Li TraverseDecl(Context.getTranslationUnitDecl());
110*67e74705SXin Li }
111*67e74705SXin Li
shouldWalkTypesOfTypeLocs() const112*67e74705SXin Li bool shouldWalkTypesOfTypeLocs() const { return false; }
113*67e74705SXin Li
VisitNamedDecl(NamedDecl * D)114*67e74705SXin Li bool VisitNamedDecl(NamedDecl *D) {
115*67e74705SXin Li D->printQualifiedName(Out);
116*67e74705SXin Li Out << '\n';
117*67e74705SXin Li return true;
118*67e74705SXin Li }
119*67e74705SXin Li
120*67e74705SXin Li private:
121*67e74705SXin Li raw_ostream &Out;
122*67e74705SXin Li };
123*67e74705SXin Li } // end anonymous namespace
124*67e74705SXin Li
CreateASTPrinter(raw_ostream * Out,StringRef FilterString)125*67e74705SXin Li std::unique_ptr<ASTConsumer> clang::CreateASTPrinter(raw_ostream *Out,
126*67e74705SXin Li StringRef FilterString) {
127*67e74705SXin Li return llvm::make_unique<ASTPrinter>(Out, /*Dump=*/false, FilterString);
128*67e74705SXin Li }
129*67e74705SXin Li
CreateASTDumper(StringRef FilterString,bool DumpDecls,bool DumpLookups)130*67e74705SXin Li std::unique_ptr<ASTConsumer> clang::CreateASTDumper(StringRef FilterString,
131*67e74705SXin Li bool DumpDecls,
132*67e74705SXin Li bool DumpLookups) {
133*67e74705SXin Li assert((DumpDecls || DumpLookups) && "nothing to dump");
134*67e74705SXin Li return llvm::make_unique<ASTPrinter>(nullptr, DumpDecls, FilterString,
135*67e74705SXin Li DumpLookups);
136*67e74705SXin Li }
137*67e74705SXin Li
CreateASTDeclNodeLister()138*67e74705SXin Li std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
139*67e74705SXin Li return llvm::make_unique<ASTDeclNodeLister>(nullptr);
140*67e74705SXin Li }
141*67e74705SXin Li
142*67e74705SXin Li //===----------------------------------------------------------------------===//
143*67e74705SXin Li /// ASTViewer - AST Visualization
144*67e74705SXin Li
145*67e74705SXin Li namespace {
146*67e74705SXin Li class ASTViewer : public ASTConsumer {
147*67e74705SXin Li ASTContext *Context;
148*67e74705SXin Li public:
Initialize(ASTContext & Context)149*67e74705SXin Li void Initialize(ASTContext &Context) override {
150*67e74705SXin Li this->Context = &Context;
151*67e74705SXin Li }
152*67e74705SXin Li
HandleTopLevelDecl(DeclGroupRef D)153*67e74705SXin Li bool HandleTopLevelDecl(DeclGroupRef D) override {
154*67e74705SXin Li for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
155*67e74705SXin Li HandleTopLevelSingleDecl(*I);
156*67e74705SXin Li return true;
157*67e74705SXin Li }
158*67e74705SXin Li
159*67e74705SXin Li void HandleTopLevelSingleDecl(Decl *D);
160*67e74705SXin Li };
161*67e74705SXin Li }
162*67e74705SXin Li
HandleTopLevelSingleDecl(Decl * D)163*67e74705SXin Li void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
164*67e74705SXin Li if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
165*67e74705SXin Li D->print(llvm::errs());
166*67e74705SXin Li
167*67e74705SXin Li if (Stmt *Body = D->getBody()) {
168*67e74705SXin Li llvm::errs() << '\n';
169*67e74705SXin Li Body->viewAST();
170*67e74705SXin Li llvm::errs() << '\n';
171*67e74705SXin Li }
172*67e74705SXin Li }
173*67e74705SXin Li }
174*67e74705SXin Li
CreateASTViewer()175*67e74705SXin Li std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
176*67e74705SXin Li return llvm::make_unique<ASTViewer>();
177*67e74705SXin Li }
178*67e74705SXin Li
179*67e74705SXin Li //===----------------------------------------------------------------------===//
180*67e74705SXin Li /// DeclContextPrinter - Decl and DeclContext Visualization
181*67e74705SXin Li
182*67e74705SXin Li namespace {
183*67e74705SXin Li
184*67e74705SXin Li class DeclContextPrinter : public ASTConsumer {
185*67e74705SXin Li raw_ostream& Out;
186*67e74705SXin Li public:
DeclContextPrinter()187*67e74705SXin Li DeclContextPrinter() : Out(llvm::errs()) {}
188*67e74705SXin Li
HandleTranslationUnit(ASTContext & C)189*67e74705SXin Li void HandleTranslationUnit(ASTContext &C) override {
190*67e74705SXin Li PrintDeclContext(C.getTranslationUnitDecl(), 4);
191*67e74705SXin Li }
192*67e74705SXin Li
193*67e74705SXin Li void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
194*67e74705SXin Li };
195*67e74705SXin Li } // end anonymous namespace
196*67e74705SXin Li
PrintDeclContext(const DeclContext * DC,unsigned Indentation)197*67e74705SXin Li void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
198*67e74705SXin Li unsigned Indentation) {
199*67e74705SXin Li // Print DeclContext name.
200*67e74705SXin Li switch (DC->getDeclKind()) {
201*67e74705SXin Li case Decl::TranslationUnit:
202*67e74705SXin Li Out << "[translation unit] " << DC;
203*67e74705SXin Li break;
204*67e74705SXin Li case Decl::Namespace: {
205*67e74705SXin Li Out << "[namespace] ";
206*67e74705SXin Li const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
207*67e74705SXin Li Out << *ND;
208*67e74705SXin Li break;
209*67e74705SXin Li }
210*67e74705SXin Li case Decl::Enum: {
211*67e74705SXin Li const EnumDecl* ED = cast<EnumDecl>(DC);
212*67e74705SXin Li if (ED->isCompleteDefinition())
213*67e74705SXin Li Out << "[enum] ";
214*67e74705SXin Li else
215*67e74705SXin Li Out << "<enum> ";
216*67e74705SXin Li Out << *ED;
217*67e74705SXin Li break;
218*67e74705SXin Li }
219*67e74705SXin Li case Decl::Record: {
220*67e74705SXin Li const RecordDecl* RD = cast<RecordDecl>(DC);
221*67e74705SXin Li if (RD->isCompleteDefinition())
222*67e74705SXin Li Out << "[struct] ";
223*67e74705SXin Li else
224*67e74705SXin Li Out << "<struct> ";
225*67e74705SXin Li Out << *RD;
226*67e74705SXin Li break;
227*67e74705SXin Li }
228*67e74705SXin Li case Decl::CXXRecord: {
229*67e74705SXin Li const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
230*67e74705SXin Li if (RD->isCompleteDefinition())
231*67e74705SXin Li Out << "[class] ";
232*67e74705SXin Li else
233*67e74705SXin Li Out << "<class> ";
234*67e74705SXin Li Out << *RD << ' ' << DC;
235*67e74705SXin Li break;
236*67e74705SXin Li }
237*67e74705SXin Li case Decl::ObjCMethod:
238*67e74705SXin Li Out << "[objc method]";
239*67e74705SXin Li break;
240*67e74705SXin Li case Decl::ObjCInterface:
241*67e74705SXin Li Out << "[objc interface]";
242*67e74705SXin Li break;
243*67e74705SXin Li case Decl::ObjCCategory:
244*67e74705SXin Li Out << "[objc category]";
245*67e74705SXin Li break;
246*67e74705SXin Li case Decl::ObjCProtocol:
247*67e74705SXin Li Out << "[objc protocol]";
248*67e74705SXin Li break;
249*67e74705SXin Li case Decl::ObjCImplementation:
250*67e74705SXin Li Out << "[objc implementation]";
251*67e74705SXin Li break;
252*67e74705SXin Li case Decl::ObjCCategoryImpl:
253*67e74705SXin Li Out << "[objc categoryimpl]";
254*67e74705SXin Li break;
255*67e74705SXin Li case Decl::LinkageSpec:
256*67e74705SXin Li Out << "[linkage spec]";
257*67e74705SXin Li break;
258*67e74705SXin Li case Decl::Block:
259*67e74705SXin Li Out << "[block]";
260*67e74705SXin Li break;
261*67e74705SXin Li case Decl::Function: {
262*67e74705SXin Li const FunctionDecl* FD = cast<FunctionDecl>(DC);
263*67e74705SXin Li if (FD->doesThisDeclarationHaveABody())
264*67e74705SXin Li Out << "[function] ";
265*67e74705SXin Li else
266*67e74705SXin Li Out << "<function> ";
267*67e74705SXin Li Out << *FD;
268*67e74705SXin Li // Print the parameters.
269*67e74705SXin Li Out << "(";
270*67e74705SXin Li bool PrintComma = false;
271*67e74705SXin Li for (auto I : FD->parameters()) {
272*67e74705SXin Li if (PrintComma)
273*67e74705SXin Li Out << ", ";
274*67e74705SXin Li else
275*67e74705SXin Li PrintComma = true;
276*67e74705SXin Li Out << *I;
277*67e74705SXin Li }
278*67e74705SXin Li Out << ")";
279*67e74705SXin Li break;
280*67e74705SXin Li }
281*67e74705SXin Li case Decl::CXXMethod: {
282*67e74705SXin Li const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
283*67e74705SXin Li if (D->isOutOfLine())
284*67e74705SXin Li Out << "[c++ method] ";
285*67e74705SXin Li else if (D->isImplicit())
286*67e74705SXin Li Out << "(c++ method) ";
287*67e74705SXin Li else
288*67e74705SXin Li Out << "<c++ method> ";
289*67e74705SXin Li Out << *D;
290*67e74705SXin Li // Print the parameters.
291*67e74705SXin Li Out << "(";
292*67e74705SXin Li bool PrintComma = false;
293*67e74705SXin Li for (ParmVarDecl *Parameter : D->parameters()) {
294*67e74705SXin Li if (PrintComma)
295*67e74705SXin Li Out << ", ";
296*67e74705SXin Li else
297*67e74705SXin Li PrintComma = true;
298*67e74705SXin Li Out << *Parameter;
299*67e74705SXin Li }
300*67e74705SXin Li Out << ")";
301*67e74705SXin Li
302*67e74705SXin Li // Check the semantic DeclContext.
303*67e74705SXin Li const DeclContext* SemaDC = D->getDeclContext();
304*67e74705SXin Li const DeclContext* LexicalDC = D->getLexicalDeclContext();
305*67e74705SXin Li if (SemaDC != LexicalDC)
306*67e74705SXin Li Out << " [[" << SemaDC << "]]";
307*67e74705SXin Li
308*67e74705SXin Li break;
309*67e74705SXin Li }
310*67e74705SXin Li case Decl::CXXConstructor: {
311*67e74705SXin Li const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
312*67e74705SXin Li if (D->isOutOfLine())
313*67e74705SXin Li Out << "[c++ ctor] ";
314*67e74705SXin Li else if (D->isImplicit())
315*67e74705SXin Li Out << "(c++ ctor) ";
316*67e74705SXin Li else
317*67e74705SXin Li Out << "<c++ ctor> ";
318*67e74705SXin Li Out << *D;
319*67e74705SXin Li // Print the parameters.
320*67e74705SXin Li Out << "(";
321*67e74705SXin Li bool PrintComma = false;
322*67e74705SXin Li for (ParmVarDecl *Parameter : D->parameters()) {
323*67e74705SXin Li if (PrintComma)
324*67e74705SXin Li Out << ", ";
325*67e74705SXin Li else
326*67e74705SXin Li PrintComma = true;
327*67e74705SXin Li Out << *Parameter;
328*67e74705SXin Li }
329*67e74705SXin Li Out << ")";
330*67e74705SXin Li
331*67e74705SXin Li // Check the semantic DC.
332*67e74705SXin Li const DeclContext* SemaDC = D->getDeclContext();
333*67e74705SXin Li const DeclContext* LexicalDC = D->getLexicalDeclContext();
334*67e74705SXin Li if (SemaDC != LexicalDC)
335*67e74705SXin Li Out << " [[" << SemaDC << "]]";
336*67e74705SXin Li break;
337*67e74705SXin Li }
338*67e74705SXin Li case Decl::CXXDestructor: {
339*67e74705SXin Li const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
340*67e74705SXin Li if (D->isOutOfLine())
341*67e74705SXin Li Out << "[c++ dtor] ";
342*67e74705SXin Li else if (D->isImplicit())
343*67e74705SXin Li Out << "(c++ dtor) ";
344*67e74705SXin Li else
345*67e74705SXin Li Out << "<c++ dtor> ";
346*67e74705SXin Li Out << *D;
347*67e74705SXin Li // Check the semantic DC.
348*67e74705SXin Li const DeclContext* SemaDC = D->getDeclContext();
349*67e74705SXin Li const DeclContext* LexicalDC = D->getLexicalDeclContext();
350*67e74705SXin Li if (SemaDC != LexicalDC)
351*67e74705SXin Li Out << " [[" << SemaDC << "]]";
352*67e74705SXin Li break;
353*67e74705SXin Li }
354*67e74705SXin Li case Decl::CXXConversion: {
355*67e74705SXin Li const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
356*67e74705SXin Li if (D->isOutOfLine())
357*67e74705SXin Li Out << "[c++ conversion] ";
358*67e74705SXin Li else if (D->isImplicit())
359*67e74705SXin Li Out << "(c++ conversion) ";
360*67e74705SXin Li else
361*67e74705SXin Li Out << "<c++ conversion> ";
362*67e74705SXin Li Out << *D;
363*67e74705SXin Li // Check the semantic DC.
364*67e74705SXin Li const DeclContext* SemaDC = D->getDeclContext();
365*67e74705SXin Li const DeclContext* LexicalDC = D->getLexicalDeclContext();
366*67e74705SXin Li if (SemaDC != LexicalDC)
367*67e74705SXin Li Out << " [[" << SemaDC << "]]";
368*67e74705SXin Li break;
369*67e74705SXin Li }
370*67e74705SXin Li
371*67e74705SXin Li default:
372*67e74705SXin Li llvm_unreachable("a decl that inherits DeclContext isn't handled");
373*67e74705SXin Li }
374*67e74705SXin Li
375*67e74705SXin Li Out << "\n";
376*67e74705SXin Li
377*67e74705SXin Li // Print decls in the DeclContext.
378*67e74705SXin Li for (auto *I : DC->decls()) {
379*67e74705SXin Li for (unsigned i = 0; i < Indentation; ++i)
380*67e74705SXin Li Out << " ";
381*67e74705SXin Li
382*67e74705SXin Li Decl::Kind DK = I->getKind();
383*67e74705SXin Li switch (DK) {
384*67e74705SXin Li case Decl::Namespace:
385*67e74705SXin Li case Decl::Enum:
386*67e74705SXin Li case Decl::Record:
387*67e74705SXin Li case Decl::CXXRecord:
388*67e74705SXin Li case Decl::ObjCMethod:
389*67e74705SXin Li case Decl::ObjCInterface:
390*67e74705SXin Li case Decl::ObjCCategory:
391*67e74705SXin Li case Decl::ObjCProtocol:
392*67e74705SXin Li case Decl::ObjCImplementation:
393*67e74705SXin Li case Decl::ObjCCategoryImpl:
394*67e74705SXin Li case Decl::LinkageSpec:
395*67e74705SXin Li case Decl::Block:
396*67e74705SXin Li case Decl::Function:
397*67e74705SXin Li case Decl::CXXMethod:
398*67e74705SXin Li case Decl::CXXConstructor:
399*67e74705SXin Li case Decl::CXXDestructor:
400*67e74705SXin Li case Decl::CXXConversion:
401*67e74705SXin Li {
402*67e74705SXin Li DeclContext* DC = cast<DeclContext>(I);
403*67e74705SXin Li PrintDeclContext(DC, Indentation+2);
404*67e74705SXin Li break;
405*67e74705SXin Li }
406*67e74705SXin Li case Decl::IndirectField: {
407*67e74705SXin Li IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(I);
408*67e74705SXin Li Out << "<IndirectField> " << *IFD << '\n';
409*67e74705SXin Li break;
410*67e74705SXin Li }
411*67e74705SXin Li case Decl::Label: {
412*67e74705SXin Li LabelDecl *LD = cast<LabelDecl>(I);
413*67e74705SXin Li Out << "<Label> " << *LD << '\n';
414*67e74705SXin Li break;
415*67e74705SXin Li }
416*67e74705SXin Li case Decl::Field: {
417*67e74705SXin Li FieldDecl *FD = cast<FieldDecl>(I);
418*67e74705SXin Li Out << "<field> " << *FD << '\n';
419*67e74705SXin Li break;
420*67e74705SXin Li }
421*67e74705SXin Li case Decl::Typedef:
422*67e74705SXin Li case Decl::TypeAlias: {
423*67e74705SXin Li TypedefNameDecl* TD = cast<TypedefNameDecl>(I);
424*67e74705SXin Li Out << "<typedef> " << *TD << '\n';
425*67e74705SXin Li break;
426*67e74705SXin Li }
427*67e74705SXin Li case Decl::EnumConstant: {
428*67e74705SXin Li EnumConstantDecl* ECD = cast<EnumConstantDecl>(I);
429*67e74705SXin Li Out << "<enum constant> " << *ECD << '\n';
430*67e74705SXin Li break;
431*67e74705SXin Li }
432*67e74705SXin Li case Decl::Var: {
433*67e74705SXin Li VarDecl* VD = cast<VarDecl>(I);
434*67e74705SXin Li Out << "<var> " << *VD << '\n';
435*67e74705SXin Li break;
436*67e74705SXin Li }
437*67e74705SXin Li case Decl::ImplicitParam: {
438*67e74705SXin Li ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(I);
439*67e74705SXin Li Out << "<implicit parameter> " << *IPD << '\n';
440*67e74705SXin Li break;
441*67e74705SXin Li }
442*67e74705SXin Li case Decl::ParmVar: {
443*67e74705SXin Li ParmVarDecl* PVD = cast<ParmVarDecl>(I);
444*67e74705SXin Li Out << "<parameter> " << *PVD << '\n';
445*67e74705SXin Li break;
446*67e74705SXin Li }
447*67e74705SXin Li case Decl::ObjCProperty: {
448*67e74705SXin Li ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(I);
449*67e74705SXin Li Out << "<objc property> " << *OPD << '\n';
450*67e74705SXin Li break;
451*67e74705SXin Li }
452*67e74705SXin Li case Decl::FunctionTemplate: {
453*67e74705SXin Li FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(I);
454*67e74705SXin Li Out << "<function template> " << *FTD << '\n';
455*67e74705SXin Li break;
456*67e74705SXin Li }
457*67e74705SXin Li case Decl::FileScopeAsm: {
458*67e74705SXin Li Out << "<file-scope asm>\n";
459*67e74705SXin Li break;
460*67e74705SXin Li }
461*67e74705SXin Li case Decl::UsingDirective: {
462*67e74705SXin Li Out << "<using directive>\n";
463*67e74705SXin Li break;
464*67e74705SXin Li }
465*67e74705SXin Li case Decl::NamespaceAlias: {
466*67e74705SXin Li NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(I);
467*67e74705SXin Li Out << "<namespace alias> " << *NAD << '\n';
468*67e74705SXin Li break;
469*67e74705SXin Li }
470*67e74705SXin Li case Decl::ClassTemplate: {
471*67e74705SXin Li ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(I);
472*67e74705SXin Li Out << "<class template> " << *CTD << '\n';
473*67e74705SXin Li break;
474*67e74705SXin Li }
475*67e74705SXin Li case Decl::OMPThreadPrivate: {
476*67e74705SXin Li Out << "<omp threadprivate> " << '"' << I << "\"\n";
477*67e74705SXin Li break;
478*67e74705SXin Li }
479*67e74705SXin Li default:
480*67e74705SXin Li Out << "DeclKind: " << DK << '"' << I << "\"\n";
481*67e74705SXin Li llvm_unreachable("decl unhandled");
482*67e74705SXin Li }
483*67e74705SXin Li }
484*67e74705SXin Li }
CreateDeclContextPrinter()485*67e74705SXin Li std::unique_ptr<ASTConsumer> clang::CreateDeclContextPrinter() {
486*67e74705SXin Li return llvm::make_unique<DeclContextPrinter>();
487*67e74705SXin Li }
488